SDK 与 SwiftUI 集成

本指南介绍了如何通过用户意见征求表单请求用户意见征求信息,以及如何在 SwiftUI 应用中使用 User Messaging Platform (UMP) SDK 请求广告时检查是否已征得用户同意。

前提条件

每次启动应用时,您都应使用 requestConsentInfoUpdateWithParameters:completionHandler:请求更新用户的意见征求信息。这决定了您的用户是需要提供用户意见征求(如果尚未提供)或用户意见征求是否已过期。

以下示例展示了如何在 onAppear(perform:) 方法中通过 View 检查状态。

struct ContentView: View {
  @State private var hasViewAppeared = false

  var body: some View {
    VStack {
      ...
    }
    .onAppear {
      // Gather consent only the first time the view appears.
      guard !hasViewAppeared else { return }
      hasViewAppeared = true

      // Create a UMPRequestParameters object.
      let parameters = UMPRequestParameters()
      // Set tag for under age of consent. false means users are not under age
      // of consent.
      parameters.tagForUnderAgeOfConsent = false

      // Request an update for the consent information.
      UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(with: parameters) {
         (requestConsentError) in

        if let consentError = requestConsentError {
          // Consent gathering failed.
          return print("Error: \(consentError.localizedDescription)")
        }

        // TODO: Load and present the consent form.
      }
    }
  }
}

根据需要加载并显示用户意见征求表单

收到最新的用户意见征求状态后,请对UMPConsentForm 类调用loadAndPresentIfRequiredFromViewController:completionHandler: 以加载用户意见征求表单。如果需要意见征求状态,SDK 会加载一个表单,并立即从提供的视图控制器中显示该表单。完成处理程序会在表单关闭后调用。如果不需要征得用户同意,则立即调用完成处理程序。

创建 UIViewControllerRepresentable

由于 loadAndPresentIfRequiredFromViewController:completionHandler: 需要 UIViewController 对象,因此请创建一个符合 UIViewControllerRepresentable 协议的类型。它的主要工作是公开 UIViewController 引用,以便在 SwiftUI 中访问。

struct FormViewControllerRepresentable: UIViewControllerRepresentable {
  let viewController = UIViewController()

  func makeUIViewController(context: Context) -> some UIViewController {
    return viewController
  }

  func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {}
}

您的 ViewControllerRepresentable 类型不应对屏幕上的内容有任何意义,但仍需要添加到视图层次结构中。将其添加到视图修饰符 background(alignment:content:) 中,使其不会占用屏幕空间。

struct ContentView: View {
  @State private var hasViewAppeared = false
  private let formViewControllerRepresentable = FormViewControllerRepresentable()

  var body: some View {
    VStack {
      ...
    }
    .background {
      // Add the ViewControllerRepresentable to the background so it
      // doesn't influence the placement of other views in the view hierarchy.
      formViewControllerRepresentable
        .frame(width: .zero, height: .zero)
    }
    .onAppear {
      // Gather consent only the first time the view appears.
      guard !hasViewAppeared else { return }
      hasViewAppeared = true

      // Create a UMPRequestParameters object.
      let parameters = UMPRequestParameters()
      // Set tag for under age of consent. false means users are not under age
      // of consent.
      parameters.tagForUnderAgeOfConsent = false

      // Request an update for the consent information.
      UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(with: parameters) {
         (requestConsentError) in

        if let consentError = requestConsentError {
          // Consent gathering failed.
          return print("Error: \(consentError.localizedDescription)")
        }

        UMPConsentForm.loadAndPresentIfRequired(from:
            formViewControllerRepresentable.viewController) { loadAndPresentError in

          if let consentError = loadAndPresentError {
            // Consent gathering failed.
            return print("Error: \(consentError.localizedDescription)")
          }

          // Consent gathering completed.
        }
      }
    }
  }
}

提出广告请求

在您的应用中请求广告之前,请检查您是否已使用 UMPConsentInformation.sharedInstance.canRequestAds征得用户同意。在征求用户意见时,需要检查以下两个实例:

  1. 在当前会话中征求用户意见后
  2. 拨打 requestConsentInfoUpdateWithParameters:completionHandler:后立即启动

可能已在之前的会话中征得用户同意。作为延迟时间最佳做法,我们建议您不要等待回调完成,这样您就可以在应用启动后尽快开始加载广告。

如果在征求用户意见的过程中发生错误,您仍应尝试请求广告。UMP SDK 会使用上一个会话的用户意见征求状态。

struct ContentView: View {
  @State private var isMobileAdsStartCalled = false
  @State private var hasViewAppeared = false
  private let formViewControllerRepresentable = FormViewControllerRepresentable()

  var body: some View {
    VStack {
      ...
    }
    .background {
      // Add the ViewControllerRepresentable to the background so it
      // doesn't influence the placement of other views in the view hierarchy.
      formViewControllerRepresentable
        .frame(width: .zero, height: .zero)
    }
    .onAppear {
      // Gather consent only the first time the view appears.
      guard !hasViewAppeared else { return }
      hasViewAppeared = true

      // Create a UMPRequestParameters object.
      let parameters = UMPRequestParameters()
      // Set tag for under age of consent. false means users are not under age
      // of consent.
      parameters.tagForUnderAgeOfConsent = false

      // Request an update for the consent information.
      UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(with: parameters) {
         requestConsentError in

        if let consentError = requestConsentError {
          // Consent gathering failed.
          return print("Error: \(consentError.localizedDescription)")
        }

        UMPConsentForm.loadAndPresentIfRequired(from:
            formViewControllerRepresentable.viewController) { (loadAndPresentError) in

          if let consentError = loadAndPresentError {
            // Consent gathering failed.
            return print("Error: \(consentError.localizedDescription)")
          }

          // Consent gathering completed.
          if UMPConsentInformation.sharedInstance.canRequestAds {
            startGoogleMobileAdsSDK()
          }
        }
      }

      // Check if you can initialize the Google Mobile Ads SDK in parallel
      // while checking for new consent information. Consent obtained in
      // the previous session can be used to request ads.
      if UMPConsentInformation.sharedInstance.canRequestAds {
        startGoogleMobileAdsSDK()
      }
    }
  }

  private func startGoogleMobileAdsSDK() {
    guard !isMobileAdsStartCalled else { return }

    isMobileAdsStartCalled = true

    // Initialize the Google Mobile Ads SDK.
    GADMobileAds.sharedInstance().start()

    // TODO: Request an ad.
    // GADInterstitialAd.load(...)
  }
}