Swift 开屏广告的实现 (支持本地与网络的图片,动态图,视频)

原理

用户在使用app的时候,用户肯定会多次打开app的,但是如果网速慢图片大,总不能让用户看3秒默认启动图吧?那样体验太不好了,因此还是加入缓存机制比较好。我的实现思路是,第一次不让用户去看这个3秒广告了,直接略过,开一个线程去缓存这张图片。第二次用户再启动app的时候,判断广告有效时间显示图片 ,gif、视频同理。

效果图


Example.gif

![
gif.gif
]
vidio.gif

部分代码

AppDelegate  需要显示广告图的时候添加以下代码

import MDSplashScreen

    if type == .localImage{
        let adView = MDSplashScreenView.init(type: .localImage)
        adView.img = "localImage.JPG"
        adView.linkUrl = "https://www.baidu.com/"
        adView.imageValidTime = "03/02/2018 14:25"
        adView.showSplashScreenWithTime(showTime: 3)
    }else if type == .localGif{
        let adView = MDSplashScreenView.init(type: .localGif)
        adView.img = "localGIf"
        adView.linkUrl = "https://www.baidu.com/"
        adView.imageValidTime = "03/02/2018 14:25"
        adView.showSplashScreenWithTime(showTime: 3)
    }else if type == .localVidio{
        let adView = MDSplashScreenView.init(type: .localVidio)
        adView.img = "localVidio"
        adView.linkUrl = ""
        adView.imageValidTime = "03/02/2018 14:25"
        adView.videoCycleOnce = false //是否循环
        adView.showSplashScreenWithTime(showTime: 0)
    }else if type == .netImage{
        let splashScreenManager = MDSplashScreenManager.sharedManager
        if UserDefaults.standard.object(forKey: AdImageName) != nil{
            let imageName = UserDefaults.standard.object(forKey: AdImageName) as! String
            let filepath = splashScreenManager.getFilePathWithName(name: imageName)
            let isExist = splashScreenManager.isFileExistWithFilePath(filePath: filepath)
            if isExist{
                let adView = MDSplashScreenView.init(type: .netImage)
                adView.img = filepath
                adView.linkUrl = UserDefaults.standard.object(forKey: AdLinkUrl) as? String
                adView.imageValidTime = UserDefaults.standard.object(forKey: AdValidTime) as? String
                adView.showSplashScreenWithTime(showTime: 3)
            }
        }

        splashScreenManager.getAdvertisingData(url: "http://img1.126.net/channel6/2016/022471/0805/2.jpg?dpi=6401136", validTime: "03/02/2018 14:25", linkUrl: "https://www.jianshu.com/u/90028000c41d", type: .netImage)
    }else if type == .netGif{
        let splashScreenManager = MDSplashScreenManager.sharedManager
        if UserDefaults.standard.object(forKey: AdGifName) != nil{
            let gifName = UserDefaults.standard.object(forKey: AdGifName) as! String
            let filepath = splashScreenManager.getFilePathWithName(name: gifName)
            let isExist = splashScreenManager.isFileExistWithFilePath(filePath: filepath)
            if isExist{
                let adView = MDSplashScreenView.init(type: .netGif)
                adView.img = filepath
                adView.linkUrl = UserDefaults.standard.object(forKey: AdLinkUrl) as? String
                adView.imageValidTime = UserDefaults.standard.object(forKey: AdValidTime) as? String
                adView.showSplashScreenWithTime(showTime: 3)
            }
        }
        
        splashScreenManager.getAdvertisingData(url: "http://yun.it7090.com/image/XHLaunchAd/pic05.gif", validTime: "03/02/2018 14:25", linkUrl: "https://www.jianshu.com/u/90028000c41d", type: .netGif)
    }else if type == .netVidio{
        let splashScreenManager = MDSplashScreenManager.sharedManager
        if UserDefaults.standard.object(forKey: AdViedioName) != nil{
            let vidioName = UserDefaults.standard.object(forKey: AdViedioName) as! String
            let filepath = splashScreenManager.getFilePathWithName(name:vidioName)
            let isExist = splashScreenManager.isFileExistWithFilePath(filePath: filepath)
            if isExist{
                let adView = MDSplashScreenView.init(type: .netVidio)
                adView.img = filepath
                adView.linkUrl = UserDefaults.standard.object(forKey: AdLinkUrl) as? String
                adView.imageValidTime = UserDefaults.standard.object(forKey: AdValidTime) as? String
                adView.showSplashScreenWithTime(showTime: 0)
            }
        }
        
        splashScreenManager.getAdvertisingData(url: "http://yun.it7090.com/video/XHLaunchAd/video03.mp4", validTime: "03/02/2018 14:25", linkUrl: "https://www.jianshu.com/u/90028000c41d", type: .netVidio)
    }


MDSplashScreenView

显示广告图
    open func showSplashScreenWithTime(showTime:Int){
        if type == .localImage{
            self.adImageView.image = UIImage.init(named: img!)
        }else if type == .localGif{
            self.adImageView.loadGif(name: img!)
        }else if type == .netImage{
            self.adImageView.image = UIImage.init(contentsOfFile: self.img!)
        }else if type == .netGif{
            let data = try? Data.init(contentsOf: URL.init(fileURLWithPath: self.img!))
            if data == nil{
                self.dismiss()
            }else{
                self.adImageView.image = UIImage.gif(data: data!)
            }
        }else if type == .localVidio{
            let filePath = Bundle.main.path(forResource: img!, ofType: "mp4")
            let videoURL = URL(fileURLWithPath: filePath!)
            let playerItem = AVPlayerItem.init(url: videoURL)
            self.videoPlayer?.player = AVPlayer.init(playerItem: playerItem)
            self.videoPlayer?.player?.play()
        }else if type == .netVidio{
            let videoURL = URL(fileURLWithPath:  img!)
            let playerItem = AVPlayerItem.init(url: videoURL)
            self.videoPlayer?.player = AVPlayer.init(playerItem: playerItem)
            self.videoPlayer?.player?.play()
        }
    
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MM/dd/yyyy HH:mm"
        dateFormatter.string(from: Date())

        let  timeStampString = self.imageValidTime
        if timeStampString == nil{
            print("结束时间存储失败")
            self.dismiss()
        }
        let validTimeDate = dateFormatter.date(from: timeStampString!)

        var result:ComparisonResult?
        result = validTimeDate?.compare(Date())
        //将存下来的日期和当前日期相比,如果当前日期小于存下来的时间,则可以显示广告页,反之则不显示
        if result == .orderedAscending{
            dismiss()
        }else{
            if showTime != 0{
                self.showTime = showTime
                countButton.setTitle("跳过\(showTime)", for: .normal)
                startTimer()
            }else{
                countButton.setTitle("跳过", for: .normal)
            }
            let window = UIApplication.shared.delegate?.window
            window??.isHidden = false
            window??.addSubview(self)
        }
        
    }

获取图片
open func getAdvertisingData(url:String,validTime:String,linkUrl:String,type:MDSplashScreenType){
        // 获取名称
        let stringArr = url.components(separatedBy: "/")
        let name: String? = stringArr.last
        // 拼接沙盒路径
        let filePath: String = getFilePathWithName(name: name!)
        let isExist: Bool = isFileExistWithFilePath(filePath: filePath)
        if !isExist {
            // 如果该资源不存在,则删除老的,下载新的
            if type == .netImage{
                downloadAdDataWithUrl(url: url, name: name!, linkUrl: linkUrl, validTime: validTime,key: AdImageName)
            }else if type == .netGif{
                downloadAdDataWithUrl(url: url, name: name!, linkUrl: linkUrl, validTime: validTime,key: AdGifName)
            }else if type == .netVidio{
                downloadAdDataWithUrl(url: url, name: name!, linkUrl: linkUrl, validTime: validTime,key: AdViedioName)
            }
        }
    }
异步下载图片
    //下载资源到本地
    fileprivate func downloadAdDataWithUrl(url:String,name:String,linkUrl:String,validTime:String,key:String){
        DispatchQueue.global().async {
            let data = try? Data.init(contentsOf: URL(string: url)!)
            if data != nil{
                let filePath  = self.getFilePathWithName(name: name)
                let gifData = NSData.init(data: data!)
                let isWrite = gifData.write(toFile: filePath, atomically: true)
                print(filePath)
                if isWrite{
                    let adImageName:String? = UserDefaults.standard.object(forKey: key) as? String
                    if name == adImageName{
                        self.deleteOldCache()
                    }
                    UserDefaults.standard.setValue(name, forKey: key)
                    UserDefaults.standard.setValue(linkUrl, forKey: AdLinkUrl)
                    UserDefaults.standard.setValue(validTime, forKey: AdValidTime)
                    UserDefaults.standard.synchronize()
                }else{
                    print("保存失败")
                }
            }else{
                print("Data为空,请检查您的网络或链接")
            }
        }
    }
    

//点击事件
@objc func toAdVC(){
        //点击广告图时,广告图消失,同时像首页发送通知,并把广告页对应的地址传给首页
        self.dismiss()
        NotificationCenter.default.post(name: NSNotification.Name.init(ToAdVC), object: linkUrl, userInfo: nil)
    }

支持 pod

pod 'MDSplashScreen'

附Demo地址

有什么问题欢迎提出。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352