zoukankan      html  css  js  c++  java
  • iOS swift 启动页加载广告(图片广告+视频广告)

    一般app在启动的时候都会有广告页,广告页用来加载自己的或者第三方的广告,广告的展示形式也多种多样,最近在看swift相关的东西,这里将提供支持加载图片广告和视频广告的解决方案

    思路:
    我们知道在加载启动页广告的时候,都需要将内容下载下来才可以正常加载出来(要不然一边启动一边加载,如果网速比较慢,可能时间都过了,图片或者视频仍然没有加载出来),所有一般加载图片需要事先把图片内容或者视频内容缓存在本地,下一次打开app的时候,查询上一次下载的内容并显示出来,同时调用服务端接口将本次的广告内容缓存起来,以供下次启动使用。由于需要显示的广告内容不确定性(图片或者视频),所以需要服务端来控制,将服务端返回的json转换成model并缓存在本地,josn中包显示类型(图片、视频还是其他),内容下载地址(图片或者视频下载地址),内容点击后是否需要跳转,跳转的链接等等信息,下次启动的时候查询model,并根据内容进行加载和跳转

    关于显示:
    图片显示这一块比较简单,直接将整张图片显示在视图中即可,给图片添加tap事件,这样当用户点击时以便可以跳转到指定的位置
    视频显示这一块使用AVFoundation中的avplayer,关于avplayer需要注意的是,其切换到后台,在进入前台的时候容易导致视频暂停,我这里的解决方案是添加applicationDidBecomeActive代理,这样当app从后台切换到前台时,捕捉到这个事件,并发送通知让avplayer继续播放

    图片广告 视频广告

    更多详细内容请参考代码
    appDelegate.swift

    import UIKit
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow?
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            // Override point for customization after application launch.
            self.window = UIWindow(frame: UIScreen.main.bounds)
            self.window?.backgroundColor = .white
            //设置rootViewController
            self.window?.rootViewController = ViewController()
            //设置launchView
            _ = LaunchView(frame: (window?.bounds)!)
            self.window?.makeKeyAndVisible()
            return true
        }
    
        //MARK:- 后台切换到前台
        func applicationDidBecomeActive(_ application: UIApplication) {
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "appBecomeActive"), object: nil)
        }
    }
    
    

    LaunchView.swift

    import UIKit
    import AVFoundation
    
    class LaunchView: UIView {
        
        var timer:Timer!
        var interval:Int = 5
        
        lazy var imgView: UIImageView = {
            let imgView = UIImageView()
            imgView.isUserInteractionEnabled = true
            let gesture = UITapGestureRecognizer.init(target: self, action: #selector(imgTouchAction))
            gesture.numberOfTouchesRequired = 1
            imgView.addGestureRecognizer(gesture)
            return imgView
        }()
        
        lazy var skipBtn:UIButton = {
            let skipBtn = UIButton()
            skipBtn.backgroundColor = UIColor(white: 0, alpha: 0.1)
            skipBtn.setTitle("跳过广告(interval)s", for: .normal)
            skipBtn.setTitleColor(.white, for: .normal)
            skipBtn.titleLabel?.font = .systemFont(ofSize: 12)
            skipBtn.layer.cornerRadius = 15
            skipBtn.layer.masksToBounds = true
            skipBtn.addTarget(self, action: #selector(dismiss), for: .touchUpInside)
            return skipBtn
        }()
        
        fileprivate var playItem:AVPlayerItem{
            get{
                //视频路径
                guard let path = Bundle.main.path(forResource: "test", ofType: "mp4") else {
                    fatalError("视频路径出错")
                }
                let url = URL(fileURLWithPath: path)
                let playItem = AVPlayerItem(url: url)
                return playItem
            }
        }
        
        fileprivate lazy var player: AVPlayer = {
            let player = AVPlayer(playerItem:playItem)
            player.actionAtItemEnd = .pause
            //设置播放完成后发送通知
            NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidPlayToEndTimeNotification(noti:)), name: .AVPlayerItemDidPlayToEndTime, object: nil)
            return player
        }()
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            //这里需要根据内容切换显示图片视图还是显示视频视图
            setupUI()
    //        setupVideoUI()
        }
        
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
    //        setupUI()
        }
        
        private func setupUI(){
            backgroundColor = .white
            
            addSubview(imgView)
            imgView.snp.makeConstraints { (make) in
                make.edges.equalToSuperview()
            }
            imgView.sd_setImage(with: URL(string: "http://img.zcool.cn/community/01e3ee5a6f2aa8a801213466f492ba.JPG@2o.jpg"))
            
            guard let window = UIApplication.shared.delegate?.window else{
                dismiss()
                return;
            }
            window?.isHidden = false
            window?.addSubview(self)
            
            addSubview(skipBtn)
            skipBtn.snp.makeConstraints { (make) in
                make.top.equalToSuperview().offset(30)
                make.right.equalToSuperview().offset(-25)
                make.size.equalTo(CGSize( 80, height: 30))
            }
            //开启定时器
            startTimer()
        }
        
        @objc private func imgTouchAction(){
            //图片广告被点击,这里可以发送通知跳转到指定页面
            dismiss()
        }
        
        private func startTimer(){
            if timer == nil {
                timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerInterval), userInfo: nil, repeats: true)
            }
        }
        
        @objc private func timerInterval(){
            interval -= 1
            if interval <= 0 {
                interval = 0
                dismiss()
                return
            }
            skipBtn.setTitle("跳过广告(interval)s", for: .normal)
        }
        
        @objc private func dismiss(){
            if timer != nil {
                if timer.isValid {  //如果定时器开启状态,关闭定时器
                    timer.invalidate()
                }
            }
            UIView.animate(withDuration: 0.5, animations: {
                //缩放
                self.imgView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
                //渐隐
                self.alpha = 0
            }, completion: { Bool in
                self.removeFromSuperview()
            })
        }
        
        deinit {
            print("启动页移除")
            NotificationCenter.default.removeObserver(self)
        }
    }
    
    //MARK:- 视频相关
    extension LaunchView{
        
        fileprivate func setupVideoUI(){
            backgroundColor = .white
            NotificationCenter.default.addObserver(self, selector: #selector(playVideos), name: NSNotification.Name(rawValue: "appBecomeActive"), object: nil)
            setupForAVplayerView()
            player.play()
            
            guard let window = UIApplication.shared.delegate?.window else{
                dismiss()
                return;
            }
            window?.isHidden = false
            window?.addSubview(self)
            
            //跳过广告
            skipBtn.setTitle("跳过广告", for: .normal)
            addSubview(skipBtn)
            skipBtn.snp.makeConstraints { (make) in
                make.top.equalToSuperview().offset(30)
                make.right.equalToSuperview().offset(-25)
                make.size.equalTo(CGSize( 80, height: 30))
            }
        }
        
        private func setupForAVplayerView(){
            let playerLayer = AVPlayerLayer(player: player)
            playerLayer.frame = bounds
            layer.addSublayer(playerLayer)
            let gesture = UITapGestureRecognizer(target: self, action: #selector(videoAdTouch))
            gesture.numberOfTapsRequired = 1
            addGestureRecognizer(gesture)
        }
        
        @objc private func playerItemDidPlayToEndTimeNotification(noti:Notification){
            player.pause()
            dismiss()
        }
        
        @objc private func videoAdTouch(){
            player.pause()
            //视频被点击 可以发送通知让进行跳转
            dismiss()
        }
        
        @objc private func playVideos(){
            player.play()
        }
    }
    
    

    这里需要注意代码中提供了2中视图样式,需要根据显示类型在这里切换样式

        override init(frame: CGRect) {
            super.init(frame: frame)
            //这里需要根据内容切换显示图片视图还是显示视频视图
            setupUI()
    //        setupVideoUI()
        }
    

    整个视图展示在window上,如果需要图片或者视频点击后需要跳转,可以通过发送通知,将点击的model通过通知的形势在rootViewController中注册通知,并接受通知和跳转
    由于需要涉及到到接口调用,我这里没有写那么详细,代码中的图片和视频使用的是本地数据,具体json的存储过程可以根据实际情况自行拓展

    转发请标记转发来源:https://www.cnblogs.com/qqcc1388/p/9894684.html

  • 相关阅读:
    Git切换分支
    JS中字符串那些事~
    将博客搬至CSDN
    MFC默认窗口类名称
    Windows下使用vim编写代码,使用nmake编译代码,使用vs来调试代码
    从CWnd::GetSafeHwnd实现得到的知识
    ctags使用
    MCI支持的格式在注册表中的位置
    注意!!一定要谨慎使用c/c++原生指针
    MFC模态对话框程序不响应OnIdle
  • 原文地址:https://www.cnblogs.com/qqcc1388/p/9894684.html
Copyright © 2011-2022 走看看