App runs successfully in Xcode in simulator and on device, but crashes on iOS 14 when archived and installed either ad hoc or using TestFlight. Archived app works on iOS 15.
This is a 100% SwiftUI app that ran successfully on iOS 14 & 15 prior to Xcode 13.2.
Relevant log:
Date/Time: 2021-12-16 17:37:54.4907 -0800
Launch Time: 2021-12-16 17:37:43.7261 -0800
OS Version: iPhone OS 14.8.1 (18H107)
Release Type: User
Baseband Version: n/a
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
VM Region Info: 0 is not in any region. Bytes before following region: 4295491584
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
UNUSED SPACE AT START
--->
__TEXT 100080000-1005f0000 [ 5568K] r-x/r-x SM=COW .../App-Name-Redacted
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [25305]
Triggered by Thread: 0
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") }
}
}
}