App啟動加載廣告頁面思路

很多app在啟動圖加載完畢后,還會顯示幾秒的廣告,有個跳過按鈕可以跳過這個廣告,有的app在點擊廣告頁之后還會進入一個廣告頁面,點擊返回進入首頁。今天我們就來開發一個廣告頁面,效果如下。

Untitled 2.gif

思路

1.廣告頁加載:廣告頁的內容要實時顯示,在沒網絡或者網絡很差的情況下依然可以顯示。所以我的做法是通過接口獲取圖片鏈接等一些信息,然后將圖片異步下載到本地,并保存圖片名,每次打開app時先根據本地存儲的圖片名查找沙盒中是否存在該圖片,如果存在,則顯示廣告頁。

2.檢測廣告頁面是否更新。無論本地是否存在廣告圖片,每次打開APP都重新調用獲取廣告圖片鏈接等信息的接口,根據圖片名稱或者其他唯一標識等方法判斷廣告是否更新,如果圖片的唯一標識與本地保存的信息不一致,則重新下載新圖片,并覆蓋舊圖片。

3.廣告頁點擊。如果點擊廣告需要跳轉廣告詳情頁面,我的做法是將獲取廣告信息的接口返回的數據全部保存在本地,點擊的時候從本地取出要廣告的鏈接即可,廣告詳情頁面是從首頁跳轉的。

4.廣告頁的顯示代碼可以放在AppDeleate中或者放在UITabbarController
的控制器中。如果代碼是在AppDelegate中,可以通過發送通知的方式,讓首頁push到廣告詳情頁,如果代碼實在UITabbarController里的直接在UITabbarController里處理即可,我做法是直接將代碼放在UITabbarController里。

5.主要邏輯。用戶第一次打開APP的時候不顯示廣告,在這個時候去調用廣告圖片接口,將數據保存在本下載圖片保存在沙盒中,用戶第二打開APP的時候照樣調用廣告接口,并將調用接口返回的數據的唯一標識與之前本地保存的廣告數據的唯一標識進行比較,如果不一樣則進行現在圖片并保存,用于下一次啟動APP時顯示。

注意:
一般廣告頁面的底部和啟動圖的底部一般都是相同的,這樣給用戶的感覺就是一直是同一個頁面,而不是跳轉到另一頁面顯示的。

代碼:
1、自定義廣告頁面:

import UIKit

@objc protocol AdvertViewDelegate {
    @objc optional
    func onclickAdvertView(view: AdvertView)
}

class AdvertView: UIImageView {

    private var btn = UIButton(type: .custom)
    private var times: Int = 0
    private weak var delegate: AdvertViewDelegate?
    // 在global線程里創建一個時間源
    private let codeTimer = DispatchSource.makeTimerSource(queue:DispatchQueue.global())
    
    class func addAdvertView(supView: UIView, image: UIImage, times: Int, frame: CGRect, delegate: Any) {
        let advertView = AdvertView(frame: frame)
        supView.addSubview(advertView)
        advertView.times = times;
        advertView.image = image;
        advertView.startCoundown()
        advertView.delegate = delegate as? AdvertViewDelegate
    }

    
    override init(frame: CGRect) {
        super.init(frame: frame)
        isUserInteractionEnabled = true
        addSubview(btn)
        btn.backgroundColor = UIColor.black
        btn.alpha = 0.8
        btn.layer.cornerRadius = 5
        btn.titleLabel?.font = UIFont.systemFont(ofSize: 12)
        btn.addTarget(self, action: #selector(btnClick), for: .touchUpInside)
        
        let tap = UITapGestureRecognizer(target: self, action: #selector(clickView))
        addGestureRecognizer(tap)
    }
    
    @objc private func clickView() {
        delegate?.onclickAdvertView?(view: self)
    }
    
    @objc private func btnClick() {
        codeTimer.cancel()
        UIView.animate(withDuration: 1.0, animations: {
            self.alpha = 0.0
        }, completion: { (true) in
            self.removeFromSuperview()
        })
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func startCoundown() {
        btn.setTitle("跳過\(times)", for: .normal)
        var timeCount = times + 1
        
        // 設定這個時間源是每秒循環一次,立即開始
        codeTimer.scheduleRepeating(deadline: .now(), interval: .seconds(1))
        // 設定時間源的觸發事件
        codeTimer.setEventHandler(handler: {
            // 每秒計時一次
            timeCount = timeCount - 1
            
            // 時間到了取消時間源
            if timeCount <= 0 {
                self.codeTimer.cancel()
                DispatchQueue.main.async {
                    UIView.animate(withDuration: 1.0, animations: { 
                        self.alpha = 0.0
                    }, completion: { (true) in
                        self.removeFromSuperview()
                    })
                }
            }
            // 返回主線程處理一些事件,更新UI等等
            DispatchQueue.main.async {
                self.btn.setTitle("跳過 \(timeCount)", for: .normal)
            }
        })
        // 啟動時間源
        codeTimer.resume()
        
    }
    
    
    override func layoutSubviews() {
        super.layoutSubviews()
        let y: CGFloat = 20.0
        let width: CGFloat = 70.0
        let height: CGFloat = 30.0
        let x: CGFloat = screenWidth - width - 10.0
        btn.frame = CGRect.init(x: x, y: y, width: width, height: height)
    }
    
    deinit {
        
    }

}

2、UITabbarController主要代碼

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        //從沙盒中取出廣告圖片
        let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
        let imagePath = "\(path!)/\(AdvertImage).png"
        guard let image = UIImage.init(contentsOfFile: imagePath) else{
            return
        }
        AdvertView.addAdvertView(supView: self.view, image: image, times: 10, frame: CGRect.init(x: 0, y: 0, width: screenWidth, height: screenHeight), delegate: self)
        
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        getImage()
    }
// MARK: - 網絡請求
extension KKMainTabBarController {
    ///  下載圖片
    func downImage(url: URL) {
        SDWebImageManager.shared().downloadImage(with: url, options: SDWebImageOptions(rawValue: 0), progress: nil, completed: { (image, error, type, animated, url) in
            guard let image = image else{
                return
            }
            let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
            let imageData = UIImageJPEGRepresentation(image, 0.5)
            guard let imgData = imageData else{
                return
            }
            let imagepath = "\(path!)/\(AdvertImage).png"
            NSData(data: imgData).write(toFile: imagepath, atomically: true)
        })
    }
    /// 調用廣告接口
    func getImage() {
        KKAFNetWorking.sharedManager.reqeust(url: "http://192.168.2.32/ceshi/public/index.php?s=admin/File/getAdvertImage", method: "GET") { (obj) in
            guard let obj = obj else{
                return
            }
            guard let status = obj["status"] as? String else{
                return
            }
            if status == "200" {
                guard let array = obj["data"] as? [[String: Any]] else{
                    return
                }
                guard let data = array.first else{
                    return
                }
                guard let currentid = (data["imageUrl"] as? String) else{
                    return
                }
                
                let userdefault = UserDefaults.standard
                let dict = userdefault.value(forKey: AdvertImage) as? [String: Any]
                userdefault.set(data, forKey: AdvertImage)
                userdefault.synchronize()
                if dict != nil {
                    let orgid = dict!["imageUrl"]! as! String
                    if currentid != orgid {
                        let url = URL(string: "http://192.168.2.32/ceshi/public/uploads/\(currentid)")
                        self.downImage(url: url!)
                    }else {//判斷圖片是否存在,
                        let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
                        let imagePath = "\(path!)/\(AdvertImage).png"
                        if ( FileManager.default.fileExists(atPath: imagePath) == false) {
                            let url = URL(string: "http://192.168.2.32/ceshi/public/uploads/\(currentid)")
                            self.downImage(url: url!)
                        }
                    }
                    
                }else{
                    let url = URL(string: "http://192.168.2.32/ceshi/public/uploads/\(currentid)")
                    self.downImage(url: url!)
                }
               
                
            }else{
                return
            }
            
        }
    }
}

獲取圖片接口是我自己寫的,外網訪問不了??????
以下是接口返回的數據

{
    data =     (
                {
            "add_time" = "2017-05-13 14:32:54";
            id = 2;
            imageUrl = "20170422/3.png";
        }
    );
    message = "\U6570\U636e\U83b7\U53d6\U6210\U529f";
    status = 200;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,238評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,430評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,134評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,893評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,653評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,136評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,212評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,372評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,888評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,738評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,482評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,179評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,588評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,829評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,610評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,916評論 2 372

推薦閱讀更多精彩內容