We have a situation where our app compiles and links in Xcode 15.1, but crashes without a stack trace when run in a simulator or real device running iOS 15.x. The minimum deployment target is set to iOS 15 and the app compiles and links fine and was uploaded to TestFlight.

The error message unfortunately does not seem very helpful in figuring out what the problem is.

Here is how the error looks in the console:

dyld[8011]: Symbol not found: _swift_getExtendedExistentialTypeMetadata
  Referenced from: /Users/jonas/Library/Developer/CoreSimulator/Devices/04C9C2EC-A371-4523-9E71-3A5A0A3BBD02/data/Containers/Bundle/Application/799DE0D8-FDC1-4378-BC4C-AE4157CED3B0/SwiftPackageIssue.app/SwiftPackageIssue
  Expected in: /Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 15.5.simruntime/Contents/Resources/RuntimeRoot/usr/lib/swift/libswiftCore.dylib

or in a crashdump like this:

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Termination Reason: DYLD 4 Symbol missing
Symbol not found: _$s7SwiftUI28BorderedProminentButtonStyleVAA09PrimitiveeF0AAMc
Referenced from: /private/var/containers/Bundle/Application/53FB853D-69A1-4EDF-A118-A5C56839968D/myApp.app/myApp
Expected in: /System/Library/Frameworks/SwiftUI.framework/SwiftUI

Triggered by Thread:  0


Thread 0 Crashed:
0   dyld                            0x0000000101d04be8 __abort_with_payload + 8
1   dyld                            0x0000000101cde498 abort_with_payload_wrapper_internal + 104 (terminate_with_reason.c:102)
2   dyld                            0x0000000101d0958c abort_with_payload + 16 (terminate_with_reason.c:124)
3   dyld                            0x0000000101cedba4 dyld4::halt(char const*) + 328 (DyldProcessConfig.cpp:2004)
4   dyld                            0x0000000101cc7a00 dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*) + 3520 (dyldMain.cpp:0)
5   dyld                            0x0000000101cdb6fc start + 488 (dyldMain.cpp:879)
2

There are 2 answers

0
Michael J On BEST ANSWER

The issues are caused by a bug in the compiler of XCode 15.0.1

You do not need to refactor your code to avoid casts like the above (like I did).

Upgrade to Xcode 15.1 asap where these issues are fixed and the builds run on iOS15 again.

1
Michael J On

We have found the problem is that XCode 15.0.1 does not check correctly for compatibility issue regarding to runtime casts of existential types.

Make sure you run enough smoke tests and be aware that casts like the above are not supported on iOS15! As soon as existentials are involved in runtime casts you risk breaking your build!

This has caused some serious headache for us, as we did not do smoke tests on iOS15 for a while. We ended up digging through heaps of git commits to isolate the issues.

Hope this helps someone to avoid this headache. (we lost almost a week).

I have opened a bug and filed a DTS ticket with Apple.

Here is some example code that causes the issue. Insert it into a std. iOS app as generated by Xcode and set minimum deployment target to iOS15. You will find that the compiler does not produce an error and yet the code does not run on iOS15.

ContentView.swift:

import Combine

struct ContentView: View {
    var body: some View {
        
        let foo = Foo<Int,Never>(subject:PassthroughSubject<Int,Never>())
        
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
            Text("Hello, world!")
        }
        .padding()
    }
    
    
}

struct Foo<Output,Failure:Error> {
    let subject:any Subject<Output,Failure>
    
    // Compiles but should not.
    func shouldNotCompile() {
        if let subject = subject as? PassthroughSubject<Output,Failure> {
            print("Oops.")
        }
    }
    
    // Generates compiler error in project, but not in swift package.
//    func shouldAlsoNotCompile(subject:PassthroughSubject<Output,Failure>) -> (any Subject<Output,Failure>)? {
//        return subject as? any Subject<Output,Failure>
//    }
    
}