You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SpriteKit的SKScene中展示插屏广告?类型转换错误求解

Hey there! Let's fix that interstitial ad issue in SpriteKit right away.

The Root Cause of Your Error

The error Cannot convert value of type 'Start' to expected argument type 'UIViewController' happens because Google Mobile Ads' GADInterstitial.present(fromRootViewController:) method requires a UIViewController instance to display the ad—but your Start class is an SKScene, not a view controller. SpriteKit scenes run inside a view controller (usually a GameViewController), so we just need to get a reference to that parent view controller.

Step-by-Step Solution & Code Example

Here's how to properly implement interstitial ads in your SKScene:

  1. Add a reference to the parent view controller in your scene class
  2. Initialize and load the ad when the scene loads
  3. Present the ad using the view controller reference when needed
import SpriteKit
import GoogleMobileAds

class Start: SKScene, GADInterstitialDelegate {
    var interstitial: GADInterstitial!
    // Weak reference to avoid retain cycles
    weak var parentViewController: UIViewController?

    override func didMove(to view: SKView) {
        // Option 1: Get the root view controller from the scene's SKView
        parentViewController = view.window?.rootViewController
        
        // Option 2 (more reliable): If you have a custom GameViewController, pass it directly
        // (Add this to your GameViewController's viewDidLoad when presenting the scene)
        // scene.parentViewController = self
        
        // Initialize and load the interstitial ad
        interstitial = GADInterstitial(adUnitID: "YOUR_AD_UNIT_ID")
        interstitial.delegate = self
        interstitial.load(GADRequest())
    }

    // Call this method when you want to show the ad (e.g., on a button tap)
    func showInterstitialAd() {
        guard let vc = parentViewController, interstitial.isReady else {
            print("Ad not ready or view controller reference missing")
            return
        }
        interstitial.present(fromRootViewController: vc)
    }

    // Delegate method to reload the ad after it's dismissed
    func interstitialDidDismissScreen(_ ad: GADInterstitial) {
        // Reinitialize and load a new ad for next time
        interstitial = GADInterstitial(adUnitID: "YOUR_AD_UNIT_ID")
        interstitial.delegate = self
        interstitial.load(GADRequest())
    }
}

Key Notes

  • Use a weak reference for the view controller to prevent memory leaks.
  • Always check if the ad is ready (interstitial.isReady) before trying to present it—this avoids crashes if the ad hasn't finished loading.
  • Reload the ad after dismissal so you have a fresh ad ready for the next trigger event.

If you're using a custom GameViewController, passing the reference directly (Option 2) is more reliable than relying on rootViewController (especially if your app uses navigation controllers or tab bars).

内容的提问来源于stack exchange,提问作者Jack23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:53:26