5.4 KiB
5.4 KiB
🔴 关键崩溃修复
问题定位
症状: 应用在打印 "XS- 开始创建 BbbAdManager.shared 单例" 后立即崩溃
根本原因: BbbAdManager 类中使用了 Swift Concurrency 的类型
// ❌ 这一行导致 iOS 12 崩溃!
private var initializationContinuations: [CheckedContinuation<Void, Never>] = []
为什么崩溃:
CheckedContinuation是 Swift Concurrency 的类型,需要 iOS 13+- 在 iOS 12 上,这个类型根本不存在
- 当 Swift 创建
BbbAdManager实例时,会先初始化所有存储属性 - 尝试初始化包含
CheckedContinuation的数组时,因为类型不存在而崩溃 - 崩溃发生在进入
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 中:
- Product → Clean Build Folder (Cmd+Shift+K)
- Product → Build (Cmd+B)
- 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"
📚 相关文档
- iOS12_COMPATIBILITY_GUIDE.md - 详细配置指南
- DEBUG_CRASH_GUIDE.md - 调试崩溃指南
- CHANGES_SUMMARY.md - 完整修改记录
关键修复完成时间: 2025-01-01
修复的根本问题: Swift Concurrency 类型在 iOS 12 上不可用
测试状态: 代码已完成,待 Xcode 配置和测试