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 會載入表單,並立即從提供的檢視畫面控制器顯示表單。系統會在使用者關閉表單後呼叫完成處理常式。如果不需要同意聲明,系統會立即呼叫完成處理常式。

建立 UIViewControllerRe 代表

由於 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(...)
  }
}