SwiftUI预览在iOS14下使用Task崩溃(iOS15+正常)
SwiftUI预览在iOS14 Swift Package中点击按钮崩溃的解决方案
问题原因
这是Xcode/SwiftUI针对iOS14 Swift Package预览的兼容性Bug:iOS14的SwiftUI预览运行环境未完整支持Swift Concurrency的Task类型,当Package指定iOS14为最低版本时,预览的运行时无法正确调度异步任务,触发崩溃;iOS15及以上原生支持Swift Concurrency,因此无此问题。
解决方案
1. 兼容iOS14的异步任务写法
将Task替换为iOS14支持的异步调度方式,或通过版本判断做兼容:
struct Test_Previews: PreviewProvider { static var previews: some View { Button("Hello world") { if #available(iOS 15.0, *) { Task { print("Hi!") } } else { // iOS14用DispatchQueue替代异步任务 DispatchQueue.global(qos: .userInitiated).async { print("Hi!") // 若需更新UI,切换回主线程 DispatchQueue.main.async { // UI更新操作 } } } } .previewDisplayName("iOS14 Compatible Preview") } }
2. 给预览指定iOS15+运行环境
即使Package最低支持iOS14,也可以在预览中指定iOS15及以上的模拟器运行:
struct Test_Previews: PreviewProvider { static var previews: some View { Button("Hello world") { Task { print("Hi!") } } .previewDisplayName("iOS15+ Preview") .previewDevice(PreviewDevice(rawValue: "iPhone 14")) // 选择iOS15+的设备 } }
或直接在Xcode预览面板的设备选择器中,切换到iOS15及以上版本的模拟器。
3. 升级Xcode到最新版本
苹果在后续Xcode版本中可能修复了该预览兼容性问题,尝试升级到Xcode 14.3及以上版本验证问题是否解决。
4. 单独调整预览目标的平台版本
修改Package.swift,给预览关联的测试目标单独设置更高的iOS版本:
import PackageDescription let package = Package( name: "PreviewCrashDemo", platforms: [.iOS(.v14)], products: [ .library( name: "PreviewCrashDemo", targets: ["PreviewCrashDemo"]), ], dependencies: [], targets: [ .target( name: "PreviewCrashDemo", dependencies: []), .testTarget( name: "PreviewCrashDemoTests", dependencies: ["PreviewCrashDemo"], platforms: [.iOS(.v15)] // 测试目标设为iOS15,预览会复用该环境 ), ] )
内容的提问来源于stack exchange,提问作者Steven Martreux
相关产品推荐
相关产品推荐

