# 🔴 关键崩溃修复 ## 问题定位 **症状:** 应用在打印 `"XS- 开始创建 BbbAdManager.shared 单例"` 后立即崩溃 **根本原因:** `BbbAdManager` 类中使用了 Swift Concurrency 的类型 ```swift // ❌ 这一行导致 iOS 12 崩溃! private var initializationContinuations: [CheckedContinuation] = [] ``` **为什么崩溃:** 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` ```swift // ❌ 旧代码(iOS 13+ 才能用) private var initializationContinuations: [CheckedContinuation] = [] // ✅ 新代码(iOS 12+ 都能用) private var initializationCallbacks: [() -> Void] = [] ``` ### 修改 2: 更新 initAd 方法 ```swift // 调用所有等待的回调(而不是 resume continuations) for callback in self.initializationCallbacks { callback() } self.initializationCallbacks.removeAll() ``` ### 修改 3: 简化 waitForSDKInitialization ```swift // 基于回调队列的简单实现,无需轮询 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 ```bash 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 不够用? ```swift // ❌ 这样还是会崩溃! @available(iOS 15.0, *) private var continuation: CheckedContinuation? // 原因:属性声明在类加载时就会处理, // @available 只能保护方法调用,无法保护类型本身的存在 ``` ### 正确的做法 ```swift // ✅ 方法 1: 使用与旧版本兼容的类型 private var callbacks: [() -> Void] = [] // ✅ 方法 2: 使用条件编译(但会增加代码复杂度) #if swift(>=5.5) private var continuation: CheckedContinuation? #endif ``` ## 🚀 完成标志 当你完成所有修改后: - [ ] Deployment Target 已改为 12.0 - [ ] AppTrackingTransparency 已设为 Optional - [ ] 运行 `pod install` 完成 - [ ] 清理并重新编译成功 - [ ] 在 iOS 12/13 模拟器或真机上运行成功 - [ ] 看到完整的日志输出,包括 "XS- init config" ## 📚 相关文档 - [iOS12_COMPATIBILITY_GUIDE.md](./iOS12_COMPATIBILITY_GUIDE.md) - 详细配置指南 - [DEBUG_CRASH_GUIDE.md](./DEBUG_CRASH_GUIDE.md) - 调试崩溃指南 - [CHANGES_SUMMARY.md](./CHANGES_SUMMARY.md) - 完整修改记录 --- **关键修复完成时间:** 2025-01-01 **修复的根本问题:** Swift Concurrency 类型在 iOS 12 上不可用 **测试状态:** 代码已完成,待 Xcode 配置和测试