如何将AdMob的GADFullScreenContentDelegate适配Swift 6并发模型
Swift 6下适配GADFullScreenContentDelegate并发隔离的解决方案
针对Swift 6语言模式下,标记@MainActor的类实现AdMob的GADFullScreenContentDelegate时遇到的并发隔离错误,以下是可行的针对性解决方案:
方案一:显式标记代理方法为@MainActor并处理Sendable参数
给每个代理方法添加@MainActor标记,同时将非Sendable的参数强制转为@unchecked Sendable(需确认业务场景下跨Actor访问安全):
@MainActor final class InterstitialWrapper: NSObject { // 类原有实现 } extension InterstitialWrapper: GADFullScreenContentDelegate { @MainActor func ad(_ ad: any GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) { // 显式告知编译器参数可安全跨Actor访问 let safeAd = ad as! @unchecked Sendable // 使用safeAd执行后续逻辑 } // 其他代理方法需同步添加@MainActor标记 @MainActor func adDidPresentFullScreenContent(_ ad: any GADFullScreenPresentingAd) { let safeAd = ad as! @unchecked Sendable // 业务逻辑实现 } }
方案二:移除类级@MainActor,仅给代理方法添加隔离标记
如果不需要整个类都绑定到Main Actor,可移除类的@MainActor标记,只给代理方法单独添加@MainActor:
final class InterstitialWrapper: NSObject { // 类原有实现,去掉@MainActor } extension InterstitialWrapper: GADFullScreenContentDelegate { @MainActor func ad(_ ad: any GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) { // 直接实现业务逻辑 } @MainActor func adDidDismissFullScreenContent(_ ad: any GADFullScreenPresentingAd) { // 直接实现业务逻辑 } }
方案三:用Task包装代理回调到Main Actor
保留类的@MainActor标记,在代理方法内部通过Task将逻辑调度到Main Actor执行:
@MainActor final class InterstitialWrapper: NSObject, GADFullScreenContentDelegate { // 类原有实现 func ad(_ ad: any GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) { Task { @MainActor in // 在这里执行所有需要Main Actor隔离的逻辑 handleAdPresentationError(ad: ad, error: error) } } @MainActor private func handleAdPresentationError(ad: any GADFullScreenPresentingAd, error: Error) { // 实际业务逻辑处理 } }
问题根源
GoogleMobileAds框架目前尚未完全适配Swift 6的Sendable协议和并发隔离规则,导致编译器无法自动确认代理参数的跨Actor安全性,需要通过上述手动方式完成兼容性适配。
内容的提问来源于stack exchange,提问作者OMGPOP
相关产品推荐
相关产品推荐

