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

SwiftUI中调用UnityAds show方法编译报错,寻求技术解决方案

SwiftUI环境下UnityAds广告展示问题解决

错误原因分析

你遇到的Cannot convert value of type 'UIViewController.Type' to expected argument type 'UIViewController'编译错误,核心原因是UnityAds.show(_:placementId:showDelegate:)方法的第一个参数需要UIViewController的实例,但你传入的是UIViewController类本身(UIViewController.Type),完全不符合参数要求。

SwiftUI环境适配方案

纯SwiftUI项目无默认UIViewController实例,需通过以下方式获取有效顶层视图控制器,同时修正UnityAds的初始化与调用逻辑:

1. 封装顶层VC获取工具

先实现一个全局工具方法,用来获取当前活跃的顶层UIViewController:

import UIKit

extension UIApplication {
    static func getTopViewController() -> UIViewController? {
        guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
              let window = windowScene.windows.first else {
            return nil
        }
        var topViewController = window.rootViewController
        while let presentedViewController = topViewController?.presentedViewController {
            topViewController = presentedViewController
        }
        return topViewController
    }
}

2. 修正UnityAds初始化与广告逻辑

不要在全局直接调用UnityAds.initialize,应放在App入口初始化时执行,同时修正广告展示方法:

import SwiftUI
import UnityAds

@main
struct YourAppName: App {
    init() {
        // 初始化UnityAds,放在App初始化阶段执行更合理
        UnityAds.initialize("307659", testMode: true)
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    var body: some View {
        VStack(spacing: 20) {
            Button("加载插屏广告") {
                loadInterstitial_UnityAds()
            }
            Button("展示广告") {
                showAds_Unity()
            }
        }
    }
    
    func loadInterstitial_UnityAds(){
        guard UnityAds.isInitialized() else {
            print("UnityAds未初始化")
            return
        }
        // 新增加载回调,便于排查加载状态
        UnityAds.load("video") { state, error in
            if let error = error {
                print("广告加载失败: \(error.localizedDescription)")
            } else if state == .ready {
                print("广告加载完成")
            }
        }
    }
    
    func showAds_Unity(){
        guard let topVC = UIApplication.getTopViewController() else {
            print("无法获取顶层视图控制器")
            return
        }
        // 注意:placementId需与Unity后台配置的广告位ID一致,你之前传的307659是AppID,不是广告位ID
        UnityAds.show(topVC, placementId: "video", showDelegate: self)
    }
}

// 可选:实现UnityAdsShowDelegate处理广告回调,便于业务逻辑扩展
extension ContentView: UnityAdsShowDelegate {
    func unityAdsShowComplete(_ placementId: String, with finishState: UnityAdsShowCompletionState) {
        print("广告展示完成: \(finishState.rawValue)")
    }
    
    func unityAdsShowFailed(_ placementId: String, with error: UnityAdsShowError, with message: String) {
        print("广告展示失败: \(message)")
    }
    
    func unityAdsShowStart(_ placementId: String) {
        print("广告开始展示")
    }
    
    func unityAdsShowClick(_ placementId: String) {
        print("广告被点击")
    }
}

关键注意事项

  • 区分AppID与PlacementId:你之前在展示方法中传入的307659是UnityAds的AppID,而非广告位ID(placementId),需替换为Unity后台创建的对应广告位ID(比如你加载时用的video)。
  • 初始化时机:避免在全局作用域直接初始化UnityAds,放在App结构体的init方法中更符合SwiftUI的生命周期规范。
  • 顶层VC可靠性:通过UIApplication扩展获取顶层VC是SwiftUI环境下获取UIViewController实例的通用方案,确保广告能正确展示在当前界面之上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:31:02