Momento_iOS 1.0.11

Momento_iOS 1.0.11

MinhyunCho 维护。



Momento iOS 指南

指南文档更新日期 → 2023.07.10 SDK 版本 → 0.0.2

最低 iOS 开发目标 → Ver.11.0

公共设置项目指南

AppDelegate

  • 在 AppDelegate 的下面方法中添加调试模式 ON/OFF 信息。
  • True 的情况下连接测试服务器,False 的情况下连接到生产服务器。
  • 在生产部署中使用的情况下,请在参数中添加 False
  • 没有设置时自动连接到生产(默认值 = false)。
  • 本指南仅供参考,您可以参考 Banner、Native、Video 以及 VC 的示例代码。但并非必须,这只是为了帮助您更方便地应用。您不需要一定要遵循示例进行实现。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        MomentSDK.shared.isDebugMode(true) // <- 테스트서버 ?? 상용서버
        
        return true
}

MomentAdsDelegate

  • onAdLoaded(dspName: String)
    • 广告加载成功时会调用,可以在此function中定义需要执行的操作。
  • onAdShowed(isShown: Bool)
    • 广告显示成功时会调用,可以在此function中定义需要执行的操作。
  • onAdClicked()
    • 点击广告时会调用,可以在此function中定义需要执行的操作。
  • onAdFailed(error: Error)
    • 广告加载失败时会调用,可以在此function中定义需要执行的操作。
  • onAdTimedout()
    • 广告加载中发生超时时调用,可以在此function中定义需要执行的操作。
  • onAdRemoved()
    • 广告被删除时会调用,可以在此function中定义需要执行的操作。

MomentVideoDelegate

  • onVideoLoaded(dspName: String)
    • 广告视频加载成功时会调用,可以在此function中定义需要执行的操作。
  • onVideoStoped()
    • 广告视频在中间停止时会调用,可以在此function中定义需要执行的操作。
  • onVideoComplete()
    • 完全播放广告视频时会调用,可以在此function中定义需要执行的操作。
  • onVideoRewarded(state: Bool)
    • 在中间关闭奖励式广告视频时被调用,对于插屏式广告视频,不会调用此delegate function。可以在此function中定义需要执行的操作。
  • onVideoError(description: String)Duplicated(0.1.36)
    • 广告因任何原因失败时会调用,可以在此function中定义需要执行的操作。
  • onVideoTimedout()
    • 广告请求超时时调用,可以在此function中定义需要执行的操作。
  • onVideoShown()
    • 广告正常显示时会调用,可以在此function中定义需要执行的操作。
  • onVideoClosed()
    • 广告关闭时会调用,可以在此function中定义需要执行的操作。
  • onVideoRemoved()
    • 广告被删除时会调用,可以在此function中定义需要执行的操作。
  • onVideoClicked(type: MomentSDK.videoClickType)
    • 点击广告时会调用,可以在此function中定义需要执行的操作。
  • onVideoLoadFailed(description: String)
    • 广告加载失败时会调用,可以在此function中定义需要执行的操作。
  • onVideoShowFailed.description: String)
    • 广告显示失败时会调用,可以在此function中定义需要执行的操作。

Banner/Native/Video分别详细设置指南

Banner

  • Banner设置元素

    • 分为50 / 100 / 250三种尺寸。定义枚举后使用更方便。
    enum bannerSizeEnum: Int {
        case small = 50
        case medium = 100
        case large = 250
    }
    • 可以使用MomentBannerView(size: Int, unitID: String)参数进行初始化。
    • 将用于控制MomentBannerView的VC声明为View的Delegate。
    • 通过 MomentBannerView 的**loadAd()**可以通过服务器加载广告。
  • MomentAdsDelegate

    • 上文中描述的Delegate的函数会根据情况被调用。因此,可以继承MomentAdsDelegate并在其中实现相应的方法来使用。
  • MomentBannerView

    • MomentBannerView使用示例

      var sizeEnum: bannerSizeEnum = .small // 50
      var moBanner: MomentBannerView?
      var getUnitID = ""
      ...
      if moBanner == nil {
          moBanner = MomentBannerView(size: sizeEnum.rawValue, unitId: getUnitID)
          guard let moBanner = moBanner else { return }
          moBanner.delegate = self
          getBannerView.addSubview(moBanner) //배너위치에다가 addsubview
          moBanner.loadAd()
      } else {
          moBanner?.loadAd()
      }

Native

  • Native设置元素

    • 可使用Xib构建UI和Code构建UI。
    • 使用Xib、Code构建UI后,分别在每个View中插入unitID以进行初始化。
    • 使用MomentNativeManager的loadWithRendering()连接UI配置元素。
  • 通过Xib构建UI的示例

    class NativeXibView: UIView {
        @IBOutlet weak var imageView: UIImageView!
        @IBOutlet weak var button: UIButton!
        @IBOutlet weak var titleLabel: UILabel!
        @IBOutlet weak var descriptionLabel: UILabel!
        @IBOutlet weak var logoImageView: UIImageView!
    		@IBOutlet weak var optionalButton: UIButton!
        
        private var getUnitId = ""
        
        var manager: MomentNativeManager!
        @objc public weak var delegate: MomentAdsDelegate? {
            didSet {
                manager.delegate = delegate
            }
        }
        
        @objc public init(unitId: String) {
            let makeframe = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 300) // 모든 버튼, 사진, 텍스트 등을 담을 프레임의 사이즈
            super.init(frame: makeframe)
            getUnitId = unitId
            manager = MomentNativeManager(unitId: getUnitId)
            manager.delegate = delegate
            
            let adView = Bundle.main.loadNibNamed("NativeXibView", owner: self, options: nil)?.first as? UIView
            self.addSubview(adView!)
            self.backgroundColor = .clear
        }
        
        @objc public func loadAd() {
            manager.loadWithRendering(mainImageView: imageView, logoImageView: logoImageView, titleLabel: titleLabel, descriptionLabel: descriptionLabel, button: button, optionalButton: optionalButton, timeOut: 10)
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        @objc public func destory() {
            delegate?.onAdRemoved()
        }
    }
  • 通过Code构建UI的示例

    class NativeTestView: UIView {
        /* View를 구성하는 라이브러리를 사용하지 않는 경우 */
        var mainImageView = UIImageView()
        var stackH = UIStackView()
        var stackV = UIStackView()
        var logoImageView = UIImageView()
        var titleLabel = UILabel()
        var descriptionLabel = UILabel()
        var button = UIButton()
        var optionalButton = UIButton()
        
        /* SnapKit과 Then을 사용하여 View를 구성하는 경우, 아래의 With SnapKit + Then 주석을 참고하여 적용할 수 있습니다. */
        var mainImageView: UIImageView!
        var stackH: UIStackView!
        var stackV: UIStackView!
        var logoImageView: UIImageView!
        var titleLabel: UILabel!
        var descriptionLabel: UILabel!
        var button: UIButton!
        var optionalButton: UIButton!
        
        private var getUnitId = ""
        
        var manager: MomentNativeManager!
        @objc public weak var delegate: MomentAdsDelegate? {
            didSet {
                manager.delegate = delegate
            }
        }
        
        @objc public init(unitId: String) {
            let makeframe = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 300) // 모든 버튼, 사진, 텍스트 등을 담을 프레임의 사이즈
            super.init(frame: makeframe)
            getUnitId = unitId
            manager = MomentNativeManager(unitId: getUnitId)
            manager.delegate = delegate
        }
        
        @objc public func loadAd() {
    				if mainImageView == nil { setupWithLayout() } // With SnapKit + Then
            manager.loadWithRendering(mainImageView: mainImageView, logoImageView: logoImageView, titleLabel: titleLabel, descriptionLabel: descriptionLabel, button: button, optionalButton: optionalButton, timeOut: 10)
            setupView() // Without SnapKit + Then
            layout() // Without SnapKit + Then
        }
        
        @objc public func destory() {
            delegate?.onAdRemoved()
        }
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
        }
    
    		deinit {
            print("Deinit")
        }
    
    		//MARK: - Using SnapKit + Then
        private func setupWithLayout() {
            if titleLabel != nil {
                titleLabel.text = ""
            }
            mainImageView = UIImageView().then {
                $0.translatesAutoresizingMaskIntoConstraints = false
                $0.clipsToBounds = true
                $0.contentMode = .scaleAspectFit
                self.addSubview($0)
                $0.snp.makeConstraints {
                    $0.width.equalTo(300)
                    $0.height.equalTo(115)
                    $0.top.equalToSuperview()
                }
            }
    
            stackH = UIStackView().then {
                $0.translatesAutoresizingMaskIntoConstraints = false
                $0.clipsToBounds = true
                $0.axis = .horizontal
                $0.spacing = 8
                $0.distribution = .fill
                self.addSubview($0)
                $0.snp.makeConstraints {
                    $0.height.equalTo(40)
                    $0.top.equalTo(mainImageView.snp.bottom).offset(25)
                    $0.leading.trailing.equalTo(mainImageView).offset(12)
                }
            }
    
            logoImageView = UIImageView().then {
                $0.translatesAutoresizingMaskIntoConstraints = false
                $0.clipsToBounds = true
                $0.contentMode = .scaleAspectFit
                stackH.addArrangedSubview($0)
                $0.snp.makeConstraints {
                    $0.width.height.equalTo(40)
                }
            }
    
            stackV = UIStackView().then {
                $0.translatesAutoresizingMaskIntoConstraints = false
                $0.clipsToBounds = true
                $0.axis = .vertical
                $0.spacing = 2
                $0.distribution = .equalSpacing
                stackH.addArrangedSubview($0)
            }
    
            titleLabel = UILabel().then {
                $0.translatesAutoresizingMaskIntoConstraints = false
                $0.font = UIFont.boldSystemFont(ofSize: 13.0)
                $0.numberOfLines = 1
                stackV.addArrangedSubview($0)
            }
    
            descriptionLabel = UILabel().then {
                $0.translatesAutoresizingMaskIntoConstraints = false
                $0.font = UIFont.boldSystemFont(ofSize: 13.0)
                $0.numberOfLines = 1
                stackV.addArrangedSubview($0)
            }
    
            button = UIButton().then {
                $0.translatesAutoresizingMaskIntoConstraints = false
                $0.setTitle("보러가기", for: .normal)
                $0.clipsToBounds = true
                $0.backgroundColor = .blue
                self.addSubview($0)
                $0.snp.makeConstraints {
                    $0.width.equalTo(mainImageView.snp.width)
                    $0.height.equalTo(42)
                    $0.top.equalTo(stackH.snp.bottom).offset(25)
                }
            }
    
            optionalButton = UIButton().then {
                $0.translatesAutoresizingMaskIntoConstraints = false
                $0.backgroundColor = .clear
                $0.clipsToBounds = true
                self.addSubview($0)
                $0.snp.makeConstraints {
                    $0.top.bottom.equalTo(self.safeAreaLayoutGuide)
                    $0.leading.trailing.equalTo(mainImageView)
                }
            }
        }
        
    //MARK: - Using Swift Constraints
        func setupView() {
            backgroundColor = .clear
            
            mainImageView.translatesAutoresizingMaskIntoConstraints = false
            mainImageView.clipsToBounds = true
            mainImageView.contentMode = .scaleAspectFit
            self.addSubview(mainImageView)
            
            stackH.translatesAutoresizingMaskIntoConstraints = false
            stackH.clipsToBounds = true
            stackH.axis = .horizontal
            stackH.spacing = 8
            stackH.distribution = .fill
            self.addSubview(stackH)
            
            logoImageView.translatesAutoresizingMaskIntoConstraints = false
            logoImageView.clipsToBounds = true
            logoImageView.contentMode = .scaleAspectFit
            stackH.addArrangedSubview(logoImageView)
            
            stackV.translatesAutoresizingMaskIntoConstraints = false
            stackV.clipsToBounds = true
            stackV.axis = .vertical
            stackV.spacing = 2
            stackV.distribution = .equalSpacing
            stackH.addArrangedSubview(stackV)
            
            titleLabel.translatesAutoresizingMaskIntoConstraints = false
            titleLabel.font = UIFont.boldSystemFont(ofSize: 13.0)
            titleLabel.numberOfLines = 1
            stackV.addArrangedSubview(titleLabel)
            
            descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
            descriptionLabel.font = UIFont.boldSystemFont(ofSize: 13.0)
            descriptionLabel.numberOfLines = 1
            stackV.addArrangedSubview(descriptionLabel)
            
            button.translatesAutoresizingMaskIntoConstraints = false
            button.setTitle("보러가기", for: .normal)
            button.clipsToBounds = true
            button.backgroundColor = .blue
            self.addSubview(button)
    
    				optionalButton.translatesAutoresizingMaskIntoConstraints = false
            optionalButton.backgroundColor = .clear
            optionalButton.clipsToBounds = true
            self.addSubview(optionalButton)
        }
        
        func layout() {
    				guard let superview = self.superview else { return }
            mainImageView.widthAnchor.constraint(equalToConstant: 300).isActive = true
            mainImageView.heightAnchor.constraint(equalToConstant: 115).isActive = true
            mainImageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
            
            stackH.heightAnchor.constraint(equalToConstant: 40).isActive = true
            stackH.topAnchor.constraint(equalTo: mainImageView.bottomAnchor, constant: 25).isActive = true
            stackH.leadingAnchor.constraint(equalTo: mainImageView.leadingAnchor, constant: 12).isActive = true
            stackH.trailingAnchor.constraint(equalTo: mainImageView.trailingAnchor, constant: -12).isActive = true
            
            logoImageView.widthAnchor.constraint(equalToConstant: 40).isActive = true
            logoImageView.heightAnchor.constraint(equalToConstant: 40).isActive = true
            
            button.widthAnchor.constraint(equalTo: mainImageView.widthAnchor).isActive = true
            button.heightAnchor.constraint(equalToConstant: 42).isActive = true
            button.topAnchor.constraint(equalTo: stackH.bottomAnchor, constant: 25).isActive = true
    
    				optionalButton.topAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.topAnchor).isActive = true
            optionalButton.leadingAnchor.constraint(equalTo: mainImageView.leadingAnchor).isActive = true
            optionalButton.trailingAnchor.constraint(equalTo: mainImageView.trailingAnchor).isActive = true
            optionalButton.bottomAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.bottomAnchor).isActive = true
        }
    }
    • 使用Code构建UI的情况下,也存在使用SnapKit + Then的示例代码。
  • MomentAdsDelegate

    • 上文中描述的Delegate的函数会根据情况被调用。因此,可以继承MomentAdsDelegate并在其中实现相应的方法来使用。
  • MomentNativeManager

    • 无论是Xib方式还是Code方式,都需要声明MomentNativeManager类型的manager,然后调用loadWithRendering()方法。
    • loadWithRendering()的参数中,除了按钮和时间超时(timeOut)外,其它元素都是可选的,开发者可以选择是否使用。例如,如果不使用用于加载logo图像的UIImageView,则可以将其设置为nil。

    时间超时(timeOut)的默认值为15秒。如果不添加任何值,则默认为15秒;如果有特定的时间,可以添加以在相应的时间内没有响应时调用Delegate的onAdTimedout()。

    • 更详细的内容可以通过loadWithRendering()的快速帮助方法(opt + click)来查看。
    class NativeTestVC: UIViewController {
        
        var size = 300
        var xibNative: NativeXibView?
        var moNative: NativeTestView?
        var getUnitID = ""
        ...
        switch sender.tag {
        case 21:
                if moNative != nil {
                    moNative?.removeFromSuperview()
                    moNative = nil
                }
                if xibNative == nil {
                    xibNative = NativeXibView(unitId: getUnitID)
                    guard let xibNative else { return }
                    xibNative.delegate = self
                    
                    getNativeView.addSubview(xibNative) // 메인뷰와 연결
                    xibNative.loadAd()
                } else {
                    xibNative?.loadAd()
                }
        case 22:
                if xibNative != nil {
                    xibNative?.removeFromSuperview()
                    xibNative = nil
                }
                if moNative == nil {
                    moNative = NativeTestView(unitId: getUnitID)
                    guard let moNative else { return }
                    moNative.delegate = self
                    
                    getNativeView.addSubview(moNative) // 메인뷰와 연결
                    moNative.loadAd()
                } else {
                    moNative?.loadAd()
                }
        default:
            break
        }
    }

Video

  • 视频设置元素及MomentVideoManager

    • 对于视频,可以独立使用loadVideo()和showVideo()。
      • loadVideo()可以预先加载视频广告,而showVideo()可以显示已加载的广告。
      • 在showVideo()中,视频播放完毕后,用户点击close按钮触发事件,**将自动加载一个广告**。
    • 通过VideoManager的hasVideoAd()方法可以检查是否有广告。
    • 在ViewController中声明继承自MomentVideoManager的变量。在声明变量的时间插入unitID。
    • 将该变量的videoDelegate设置为self,之后在需要的时间调用loadVideo()和showVideo()。
    • 示例
    class VideoTestVC: UIViewController {
    		...
        var getUnitID: String = ""
        var moVideo: MomentVideoManager?
    		...
        @IBAction func bannerAct(_ sender: UIButton) {
            switch sender.tag {
            case 20:
                for subview in getStackView.arrangedSubviews {
                    subview.removeFromSuperview()
                }
            case 21:
                if moVideo == nil {
                    moVideo = MomentVideoManager(unitID: getUnitID) <-
                    guard let moVideo = moVideo else { return }
                    moVideo.videoDelegate = self <-
                    moVideo.loadVideo() <-
                } else {
                    moVideo?.loadVideo()
                }
                
            case 22:
                guard let moVideo = moVideo else { return }
                moVideo.videoDelegate = self
                moVideo.showVideo() <-
    				...
            default:
                break
            }
        }
    		...
    }
  • MomentVideoDelegate

    • 上文中描述的Delegate的函数会根据情况被调用。因此,可以继承MomentVideoDelegate并在其中实现相应的方法来使用。

GDPR 집해제 가이드

MomentoiOS SDK GDPR 집해제 미니멘트 버전 → 0.1.32

本指南是为遵守GDPR的媒体制作的。

通过MomentSDK的内部方法setTCString(:String)传递TCString。

MomentSDK.shared.setTCString(TCSTring: "E1X2A3M4P5L6E7")

根据用户GDPR的同意与否,将接收到的result value传递给用户。

如果用户不同意,请将setTCString参数传递空白字符串“”。