Post

Replies

Boosts

Views

Activity

Reply to Xcode 13.2 Archived App Crashes on iOS 14
I have same issue with Xcode 13.2 (13C90), SwiftUI and #available in if statement. Project works fine with old Xcode and in Debug configuration, but crashes with old versions of iOS (iOS 13 & 14) in Release configuration (or using TestFlight). Steps to reproduce: Create a new SwiftUI iPhone Application project. Set the iOS target to 14 Create a simple view with an if #available statement and any new iOS 15 modifier. For example: struct ContentView: View {     var body: some View { if #available(iOS 15.0, *) { List { Text("iOS 15 new feature") .listRowSeparator(.hidden) } } else { List { Text("Old style") } }     } } Change the build configuration in the launch scheme to Release and run the app on a device or simulator with iOS 14. Application will crash with error: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0) * frame #0: 0x00007fff2f38f127 libswiftCore.dylib`swift::ResolveAsSymbolicReference::operator()(swift::Demangle::__runtime::SymbolicReferenceKind, swift::Demangle::__runtime::Directness, int, void const*) + 55 frame #1: 0x00007fff2f3b15dd libswiftCore.dylib`swift::Demangle::__runtime::Demangler::demangleSymbolicReference(unsigned char) + 141 frame #2: 0x00007fff2f3ae5a8 libswiftCore.dylib`swift::Demangle::__runtime::Demangler::demangleType(__swift::__runtime::llvm::StringRef, std::__1::function<swift::Demangle::__runtime::Node* (swift::Demangle::__runtime::SymbolicReferenceKind, swift::Demangle::__runtime::Directness, int, void const*)>) + 168 frame #3: 0x00007fff2f394974 libswiftCore.dylib`swift_getTypeByMangledNameImpl(swift::MetadataRequest, __swift::__runtime::llvm::StringRef, void const* const*, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 516 frame #4: 0x00007fff2f39212d libswiftCore.dylib`swift::swift_getTypeByMangledName(swift::MetadataRequest, __swift::__runtime::llvm::StringRef, void const* const*, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 477 frame #5: 0x00007fff2f39235b libswiftCore.dylib`swift_getTypeByMangledNameInContext + 171 frame #6: 0x000000010305add7 AvailableBug`__swift_instantiateConcreteTypeFromMangledName at <compiler-generated>:0 ... It looks like SwiftUI is trying to initialize the content of the if statement and crashes on an unknown modifier or element. If creates a simple wrapper structure that defers initialization to the "body", everything works fine. Workaround: struct LazyContent<Content: View>: View { let content: ()->Content init (@ViewBuilder content: @escaping ()->Content) { self.content = content } var body: some View { content() } } struct ContentView: View {     var body: some View { if #available(iOS 15.0, *) { LazyContent { List { Text("iOS 15 new feature") .listRowSeparator(.hidden) } } } else { List { Text("Old style") } }     } }
Dec ’21
Reply to WidgetBundleBuilder crash on #available(iOS 18.0) check: WidgetBundleBuilder includes an unknown OS version
The situation gets even worse if you need to triple-check to support, for example, older widgets without interaction, iOS 17 widgets with interaction, and the new iOS 18 control widgets. If you use the above workaround with three versions, it will result in an error: Function declares an opaque return type 'some Widget', but the return statements in its body do not have matching underlying types Code with error: var body: some Widget { if #available(iOS 18.0, *) { return body_iOS18 } else if #available(iOS 17.0, *) { return body_iOS17 } else { return body_old } } So you have to create ugly things like: var body: some Widget { if #available(iOS 17.0, *) { return body_new } else { return body_old } } @available(iOSApplicationExtension 17.0, *) var body_new: some Widget { if #available(iOS 18.0, *) { return body_iOS18 } else { return body_iOS17 } }
Sep ’24