Xcode 16 iOS 18 compatibility - SwiftUI Previews Crash
I am receiving a crash using Xcode 16, iOS 18 and SwiftUI Previews (earlier versions of iOS < 18 work).
Something related to Texture being in the framework search paths while SwiftUI Previews is trying to load the binary / some main thread assertion.
Application Specific Information:
libsystem_sim_platform.dylib:
CoreSimulator 987.2 - Device: iPhone 16 Pro (233D7258-C8AC-41D3-B7CF-8136F91007AB) - Runtime: iOS 18.1 (22B81) - DeviceType: iPhone 16 Pro
dyld:
dyld config: DYLD_SHARED_CACHE_DIR=/Users/jisaacs/Library/Developer/CoreSimulator/Caches/dyld/24C101/com.apple.CoreSimulator.SimRuntime.iOS-18-1.22B81 DYLD_ROOT_PATH=/Library/Developer/CoreSimulator/Volumes/iOS_22B81/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.1.simruntime/Contents/Resources/RuntimeRoot DYLD_LIBRARY_PATH=/Users/jisaacs/Library/Developer/Xcode/DerivedData/r4e-fmmdabgcnpgaskfskovbmmlmxcgj/Build/Products/Debug-iphonesimulator DYLD_INSERT_LIBRARIES=@executable_path/__preview.dylib:/Library/Developer/CoreSimulator/Volumes/iOS_22B81/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.1.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libLogRedirect.dylib:/System/Library/PrivateFrameworks/LiveExecutionResultsProbe.framework/LiveExecutionResultsProbe:/System/Library/PrivateFrameworks/PreviewsInjection.framework/PreviewsInjection DYLD_FRAMEWORK_PATH=/Users/jisaacs/Library/Developer/Xcode/DerivedData/r4e-fmmdabgcnpgaskfskovbmmlmxcgj/Build/Products/Debug-iphonesimulator DYLD_FALLBACK_FRAMEWORK_PATH=/Library/Developer/CoreSimulator/Volumes/iOS_22B81/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.1.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks DYLD_FALLBACK_LIBRARY_PATH=/Library/Developer/CoreSimulator/Volumes/iOS_22B81/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.1.simruntime/Contents/Resources/RuntimeRoot/usr/lib
libsystem_c.dylib:
abort() called
libc++abi.dylib:
terminating due to uncaught exception of type NSException
CoreFoundation:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This function must be called on the main thread'
dyld_sim:
dyld config: DYLD_SHARED_CACHE_DIR=/Users/jisaacs/Library/Developer/CoreSimulator/Caches/dyld/24C101/com.apple.CoreSimulator.SimRuntime.iOS-18-1.22B81 DYLD_ROOT_PATH=/Library/Developer/CoreSimulator/Volumes/iOS_22B81/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.1.simruntime/Contents/Resources/RuntimeRoot DYLD_LIBRARY_PATH=/Users/jisaacs/Library/Developer/Xcode/DerivedData/r4e-fmmdabgcnpgaskfskovbmmlmxcgj/Build/Products/Debug-iphonesimulator DYLD_INSERT_LIBRARIES=@executable_path/__preview.dylib:/Library/Developer/CoreSimulator/Volumes/iOS_22B81/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.1.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libLogRedirect.dylib:/System/Library/PrivateFrameworks/LiveExecutionResultsProbe.framework/LiveExecutionResultsProbe:/System/Library/PrivateFrameworks/PreviewsInjection.framework/PreviewsInjection DYLD_FRAMEWORK_PATH=/Users/jisaacs/Library/Developer/Xcode/DerivedData/r4e-fmmdabgcnpgaskfskovbmmlmxcgj/Build/Products/Debug-iphonesimulator DYLD_FALLBACK_FRAMEWORK_PATH=/Library/Developer/CoreSimulator/Volumes/iOS_22B81/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.1.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks DYLD_FALLBACK_LIBRARY_PATH=/Library/Developer/CoreSimulator/Volumes/iOS_22B81/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.1.simruntime/Contents/Resources/RuntimeRoot/usr/lib
Crashing Thread:
0 CoreFoundation 0x00012c570 __exceptionPreprocess + 160
1 libobjc.A.dylib 0x00002ada8 objc_exception_throw + 72
2 Foundation 0x0006a2398 -[NSMutableDictionary(NSMutableDictionary) classForCoder] + 0
3 AsyncDisplayKit 0x000102fbc __ASInitializeFrameworkMainThreadOnConstructor_block_invoke + 196 (ASInternalHelpers.mm:68)
4 libdispatch.dylib 0x000003de0 _dispatch_client_callout + 16
5 libdispatch.dylib 0x0000055d4 _dispatch_once_callout + 28
6 AsyncDisplayKit 0x000102ed8 _dispatch_once(long*, void () block_pointer) + 36 (once.h:86)
7 AsyncDisplayKit 0x000102ed8 ASInitializeFrameworkMainThreadOnConstructor + 80 (ASInternalHelpers.mm:67)
8 AsyncDisplayKit 0x00009efa0 ASLoadFrameworkInitializerOnConstructor() + 12 (ASDisplayNode.mm:261)
9 dyld_sim 0x0000104e8 invocation function for block in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const + 216
10 dyld_sim 0x000031ae4 invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const + 164
11 dyld_sim 0x0000297b4 invocation function for block in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const + 488
12 dyld_sim 0x000028488 dyld3::MachOFile::forEachLoadCommand(Diagnostics&, void (load_command const*, bool&) block_pointer) const + 284
13 dyld_sim 0x000028794 dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const + 164
14 dyld_sim 0x00002afb0 dyld3::MachOFile::forEachInitializerPointerSection(Diagnostics&, void (unsigned int, unsigned int, bool&) block_pointer) const + 132
15 dyld_sim 0x000031804 dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const + 324
16 dyld_sim 0x0000103a4 dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const + 148
17 dyld_sim 0x000015f64 dyld4::JustInTimeLoader::runInitializers(dyld4::RuntimeState&) const + 32
18 dyld_sim 0x000010708 dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&, dyld3::Array<dyld4::Loader const*>&) const + 308
19 dyld_sim 0x0000106a8 dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&, dyld3::Array<dyld4::Loader const*>&) const + 212
20 dyld_sim 0x00001381c dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const::$_0::operator()() const + 136
21 dyld_sim 0x0000107ac dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const + 84
22 dyld_sim 0x00001e360 dyld4::APIs::dlopen_from(char const*, int, void*) + 1384
23 PreviewsInjection 0x00002c828 ???
24 PreviewsInjection 0x00002c2a0 __previews_injection_perform_first_jit_link + 12
25 XOJITExecutor 0x000007124 __xojit_executor_run_program_wrapper + 1828
26 XOJITExecutor 0x000004a44 ???
27 XOJITExecutor 0x00000475c ???
28 libdispatch.dylib 0x0000024ec _dispatch_call_block_and_release + 24
29 libdispatch.dylib 0x000003de0 _dispatch_client_callout + 16
30 libdispatch.dylib 0x0000077dc _dispatch_continuation_pop + 896
31 libdispatch.dylib 0x000006958 _dispatch_async_redirect_invoke + 864
32 libdispatch.dylib 0x000016518 _dispatch_root_queue_drain + 364
33 libdispatch.dylib 0x000016f60 _dispatch_worker_thread2 + 232
34 libsystem_pthread.dylib 0x000003b38 _pthread_wqthread + 224
35 libsystem_pthread.dylib 0x000002934 start_wqthread + 8
```
@jeromeDefReputation just question, how did you get this stack trace from SwiftUI Preview? I have the same issue, but I'm just curious.
I'm running into this issue too. Anybody figure out how to work around this other than using an iOS 17 preview device instead?
I have fixed it, below is the code to help you out -
- Go to file
ASInternalHelpers.mmand replace the functions -ASInitializeFrameworkMainThreadOnConstructorandASInitializeFrameworkMainThreadOnDestructor
with below code -
void ASInitializeFrameworkMainThreadOnConstructor(void)
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// Added check to run the code on main thread only for non preview (swiftUI previews) environments.
if (![[NSProcessInfo processInfo].environment[@"XCODE_RUNNING_FOR_PREVIEWS"] isEqualToString:@"1"]) {
ASDisplayNodeCAssertMainThread();
}
ASNotifyInitialized();
#if AS_SIGNPOST_ENABLE
_ASInitializeSignpostObservers();
#endif
});
}
void ASInitializeFrameworkMainThreadOnDestructor(void)
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// Skip in SwiftUI preview mode
if ([[NSProcessInfo processInfo].environment[@"XCODE_RUNNING_FOR_PREVIEWS"] isEqualToString:@"1"]) {
return;
}
ASDisplayNodeCAssertMainThread();
// Ensure these values are cached on the main thread before needed in the background.
if (ASActivateExperimentalFeature(ASExperimentalLayerDefaults)) {
// Nop. We will gather default values on-demand in ASDefaultAllowsGroupOpacity and ASDefaultAllowsEdgeAntialiasing
} else {
CALayer *layer = [[[UIView alloc] init] layer];
allowsGroupOpacityFromUIKitOrNil = @(layer.allowsGroupOpacity);
allowsEdgeAntialiasingFromUIKitOrNil = @(layer.allowsEdgeAntialiasing);
}
});
}
- Go to file
ASConfigurationInternal.mmand replace the function -frameworkDidInitialize
with below code -
- (void)frameworkDidInitialize
{
// Added check to run the code on main thread only for non preview (swiftUI previews) environments.
if (![[NSProcessInfo processInfo].environment[@"XCODE_RUNNING_FOR_PREVIEWS"] isEqualToString:@"1"]) {
ASDisplayNodeAssertMainThread();
}
if (_frameworkInitialized) {
ASDisplayNodeFailAssert(@"Framework initialized twice.");
return;
}
_frameworkInitialized = YES;
const auto delegate = _config.delegate;
if ([delegate respondsToSelector:@selector(textureDidInitialize)]) {
[delegate textureDidInitialize];
}
}