build-ipa/ironSource/PlayBTopOn/CRITICAL_FIX.md
2026-01-05 10:40:05 +08:00

5.4 KiB
Raw Blame History

🔴 关键崩溃修复

问题定位

症状: 应用在打印 "XS- 开始创建 BbbAdManager.shared 单例" 后立即崩溃

根本原因: BbbAdManager 类中使用了 Swift Concurrency 的类型

// ❌ 这一行导致 iOS 12 崩溃!
private var initializationContinuations: [CheckedContinuation<Void, Never>] = []

为什么崩溃:

  1. CheckedContinuation 是 Swift Concurrency 的类型,需要 iOS 13+
  2. 在 iOS 12 上,这个类型根本不存在
  3. 当 Swift 创建 BbbAdManager 实例时,会先初始化所有存储属性
  4. 尝试初始化包含 CheckedContinuation 的数组时,因为类型不存在而崩溃
  5. 崩溃发生在进入 init() 方法之前,所以 "XS- BbbAdManager init 开始" 日志永远不会打印

已修复

修改 1: 替换 Swift Concurrency 类型

文件: PlayBTopOn/playB/bbbAdManager.swift

// ❌ 旧代码iOS 13+ 才能用)
private var initializationContinuations: [CheckedContinuation<Void, Never>] = []

// ✅ 新代码iOS 12+ 都能用)
private var initializationCallbacks: [() -> Void] = []

修改 2: 更新 initAd 方法

// 调用所有等待的回调(而不是 resume continuations
for callback in self.initializationCallbacks {
    callback()
}
self.initializationCallbacks.removeAll()

修改 3: 简化 waitForSDKInitialization

// 基于回调队列的简单实现,无需轮询
func waitForSDKInitialization(completion: @escaping () -> Void) {
    if isSDKInitialized {
        completion()
        return
    }
    
    // 添加到队列initAd 完成时会调用
    initializationCallbacks.append(completion)
}

🎯 所有修复总结

问题 解决方案 状态
Task { await ... } 改用 DispatchQueue + 回调 已修复
AppTrackingTransparency 导入 使用 #if canImport() 已修复
async/await 函数 标记 @available(iOS 15.0, *) 已修复
CheckedContinuation 类型 改用普通闭包数组 已修复
Deployment Target = 17.4 需改为 12.0 ⚠️ 需手动操作
ATT 框架链接 需设为 Optional ⚠️ 需手动操作

📝 接下来必须做的事

1. 在 Xcode 中修改 Deployment Target最重要

打开 PlayBTopOn.xcworkspace
↓
选择项目 PlayBTopOn
↓
选择 TARGETS → PlayBTopOn
↓
General → Deployment Info
↓
iOS Deployment Target: 17.4 → 12.0

同时修改 PROJECT 的设置:

选择 PROJECT → PlayBTopOn
↓
Build Settings → Deployment
↓
iOS Deployment Target: 17.4 → 12.0

2. 设置 AppTrackingTransparency 为弱链接

TARGETS → PlayBTopOn
↓
Build Phases → Link Binary With Libraries
↓
找到 AppTrackingTransparency.framework
↓
Status: Required → Optional

3. 重新安装 Pods

cd /Users/mac/workspaces/projects/ios/build-ipa/ironSource/PlayBTopOn
pod install

4. 清理并重新编译

在 Xcode 中:

  1. Product → Clean Build Folder (Cmd+Shift+K)
  2. Product → Build (Cmd+B)
  3. Product → Run (Cmd+R)

🔍 验证日志

成功运行后,你应该看到完整的日志序列:

XS- app start: xxx
XS- app start 2: xxx
XS- YL_PlayVC viewDidLoad 开始
XS- app start 21: xxx
XS- 准备访问 BbbAdManager.shared
XS- 开始创建 BbbAdManager.config
XS- bConfig init 开始
XS- bConfig init: allAdIds count = 3
XS- bConfig init 完成
XS- BbbAdManager.config 创建完成
XS- 开始创建 BbbAdManager.shared 单例
XS- BbbAdManager init 开始         ← 之前卡在这里之前
XS- BbbAdManager init 完成         ← 现在应该能看到这个
XS- BbbAdManager.shared 单例创建完成
XS- 准备调用 initConfig()
XS- init config                     ← 现在应该能看到这个了!
XS- init config 1
XS- init config 2
XS- init config 3
...

💡 技术要点

Swift Concurrency 与 iOS 版本

特性 最低版本
Task iOS 15.0
async/await iOS 15.0
CheckedContinuation iOS 13.0
AsyncStream iOS 15.0
@MainActor iOS 15.0

为什么 @available 不够用?

// ❌ 这样还是会崩溃!
@available(iOS 15.0, *)
private var continuation: CheckedContinuation<Void, Never>?

// 原因:属性声明在类加载时就会处理,
// @available 只能保护方法调用,无法保护类型本身的存在

正确的做法

// ✅ 方法 1: 使用与旧版本兼容的类型
private var callbacks: [() -> Void] = []

// ✅ 方法 2: 使用条件编译(但会增加代码复杂度)
#if swift(>=5.5)
private var continuation: CheckedContinuation<Void, Never>?
#endif

🚀 完成标志

当你完成所有修改后:

  • Deployment Target 已改为 12.0
  • AppTrackingTransparency 已设为 Optional
  • 运行 pod install 完成
  • 清理并重新编译成功
  • 在 iOS 12/13 模拟器或真机上运行成功
  • 看到完整的日志输出,包括 "XS- init config"

📚 相关文档


关键修复完成时间: 2025-01-01
修复的根本问题: Swift Concurrency 类型在 iOS 12 上不可用
测试状态: 代码已完成,待 Xcode 配置和测试