Texture icon indicating copy to clipboard operation
Texture copied to clipboard

Xcode 16 iOS 18 compatibility - SwiftUI Previews Crash

Open jeromeDefReputation opened this issue 1 year ago • 3 comments

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 avatar Dec 19 '24 14:12 jeromeDefReputation

@jeromeDefReputation just question, how did you get this stack trace from SwiftUI Preview? I have the same issue, but I'm just curious.

muukii avatar Apr 08 '25 04:04 muukii

I'm running into this issue too. Anybody figure out how to work around this other than using an iOS 17 preview device instead?

bdolman avatar May 23 '25 17:05 bdolman

I have fixed it, below is the code to help you out -

  1. Go to file ASInternalHelpers.mm and replace the functions - ASInitializeFrameworkMainThreadOnConstructor and ASInitializeFrameworkMainThreadOnDestructor

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);
    }
  });
}
  1. Go to file ASConfigurationInternal.mm and 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];
  }
}

rahulVermaSimpplr avatar May 26 '25 06:05 rahulVermaSimpplr