Request authorization for the notification center crash iOS app on Swift 6

Hey all!

During the migration of a production app to swift 6, I've encountered a problem: when hitting the UNUserNotificationCenter.current().requestAuthorization the app crashes.

If I switch back to Language Version 5 the app works as expected.

The offending code is defined here

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        FirebaseConfiguration.shared.setLoggerLevel(.min)

        UNUserNotificationCenter.current().delegate = self

        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { _, _ in }

        application.registerForRemoteNotifications()

        Messaging.messaging().delegate = self

        return true
    }
}

The error is depicted here: I have no idea how to fix this.

Any help will be really appreciated

thanks in advance

Answered by DTS Engineer in 807248022
Written by DTS Engineer in 806202022
I’m gonna do some more research about this (FB15294185)

I spent some time talking this over with various colleagues, just to make sure I fully understand what’s going on. The high-level summary is:

  • Swift 6 has inserted a run-time check to catch a concurrency issue that Swift 5 did not.

  • This isn’t caught at compile time because of a Swift / Objective-C impedance mismatch.

If you want to know more, follow me down the rabbit hole!


Consider this simplified version of Artecoop’s test code:

@main
final class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    
    func applicationDidFinishLaunching(_ application: UIApplication) {
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound, .badge]) { success, error in
            print(success)
            assert(Thread.isMainThread)
        }
    }
}

The entire did-finish-launching method should run on the main actor. That’s because:

  • The method itself is part of the implementation of the UIApplicationDelegate protocol, and that’s declared @MainActor.

  • The requestAuthorization(…) method doesn’t do anything to tell the Swift compiler that it will call the completion handler on a secondary thread (more on that below).

If you build this program in Swift 6 mode, on running it you trap before the print(…) call, in a main actor check inserted by the Swift compiler. That’s the central complaint of the original post.

However, consider what happens if you build this in Swift 5 mode. This time it traps in the assert(…). So this trap is clearly an improvement: Swift 6 mode is consistently detecting a problem that could otherwise cause a data race.


However, that explanation leaves a number of unanswered questions. Let’s start with fixes.

The fix I described above, calling the async version of the method, works because the Swift compiler implements the async method with code that kinda looks something like this:

extension UNUserNotificationCenter {

    func requestNotificationQQQ1(
        options: UNAuthorizationOptions
    ) async throws -> Bool {
        try await withCheckedThrowingContinuation { cont in
            self.requestAuthorization(options: options) { success, error in
                if success {
                    cont.resume(returning: true)
                } else {
                    cont.resume(throwing: error!)
                }
            }
        }
    }
}

In this case the completion handler isn’t bound to the main actor and thus the compiler doesn’t add an assert. And the CheckedContinuation type is thread safe, so calling its methods from any thread is fine.

The other fix is to make the closure as @Sendable:

center.requestAuthorization(options: [.alert, .sound, .badge]) { @Sendable success, error in
    print(success)
    // print(self.window)
}

This disconnects the closure from the main actor and thus there’s no main actor check. However, it also means that you can’t access main actor state in the closure. If you uncomment the access to self.window, the compiler complains that Main actor-isolated property 'window' can not be referenced from a Sendable closure.


Finally, let’s come back to why the compiler doesn’t know that the completion handler can be called on any thread. That’s tied to the Objective-C declaration, which is imported into Swift as:

func requestAuthorization(
    options: UNAuthorizationOptions = [],
    completionHandler: @escaping (Bool, (any Error)?) -> Void
)

Imagine you wrote your own (very bad :-) [1] version of this in Swift:

extension UNUserNotificationCenter {

    func requestAuthorizationQQQ2(
        options: UNAuthorizationOptions = [],
        completionHandler: @escaping (Bool, (any Error)?) -> Void
    ) {
        DispatchQueue.global().asyncAfter(deadline: .now() + 0.1) {
            completionHandler(true, nil)
         // ^ Capture of 'completionHandler' with non-sendable type '(Bool, (any Error)?) -> Void' in a `@Sendable` closure
        }
    }
}

The compiler complains that the closure is being sent across isolation domains even though it’s not sendable. That’s obviously bad.

The thing to note here is that this is exactly what Objective-C is doing, and it’s why you’re running into the problem.

The most straightforward way to fix the requestAuthorizationQQQ2(…) method is to replace @escaping with @Sendable. And the equivalent of doing that in Objective-C is to add NS_SWIFT_SENDABLE to the completion handler parameter of the -requestAuthorizationWithOptions:completionHandler: method [2].

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] To start, I’m not following my own advice here: Avoid Dispatch Global Concurrent Queues

[2] It wouldn’t surprise me if that were the final resolution of FB15294185, but that’s still in The Future™.

This crashes all the time, right?

If so, please generate a crash report and post it here. See Posting a Crash Report for advice on how to do that.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Here the .ips crash report, with .txt extension as suggested in your post.

{"app_name":"IBreviary","timestamp":"2024-09-27 09:22:22.00 +0200","app_version":"9.1.0","slice_uuid":"d49a25e1-0486-3466-bcb3-50d478688bfa","build_version":"1.0.0","platform":7,"bundleID":"it.netguru.ibreviaryproterrasancta","share_with_app_devs":0,"is_first_party":0,"bug_type":"309","os_version":"macOS 15.0 (24A335)","roots_installed":0,"name":"IBreviary","incident_id":"910D2D0B-73F8-4DF4-AC50-22F7DEEBE14D"}
{
  "uptime" : 3100,
  "procRole" : "Foreground",
  "version" : 2,
  "userID" : 501,
  "deployVersion" : 210,
  "modelCode" : "Macmini9,1",
  "coalitionID" : 1293,
  "osVersion" : {
    "train" : "macOS 15.0",
    "build" : "24A335",
    "releaseType" : "User"
  },
  "captureTime" : "2024-09-27 09:22:21.6960 +0200",
  "codeSigningMonitor" : 1,
  "incident" : "910D2D0B-73F8-4DF4-AC50-22F7DEEBE14D",
  "pid" : 2503,
  "translated" : false,
  "cpuType" : "ARM-64",
  "roots_installed" : 0,
  "bug_type" : "309",
  "procLaunch" : "2024-09-27 09:22:21.2781 +0200",
  "procStartAbsTime" : 75903969853,
  "procExitAbsTime" : 75913966469,
  "procName" : "IBreviary",
  "procPath" : "\/Users\/USER\/Library\/Developer\/CoreSimulator\/Devices\/16AD31A6-E5E4-496D-90C8-317ECA5C848E\/data\/Containers\/Bundle\/Application\/B7A991A7-E46A-4C39-9474-8D35F517017D\/IBreviary.app\/IBreviary",
  "bundleInfo" : {"CFBundleShortVersionString":"9.1.0","CFBundleVersion":"1.0.0","CFBundleIdentifier":"it.netguru.ibreviaryproterrasancta"},
  "storeInfo" : {"deviceIdentifierForVendor":"7F7C5D56-B1E1-561A-A5EA-E6D28BE4A3EE","thirdParty":true},
  "parentProc" : "launchd_sim",
  "parentPid" : 1605,
  "coalitionName" : "com.apple.CoreSimulator.SimDevice.16AD31A6-E5E4-496D-90C8-317ECA5C848E",
  "crashReporterKey" : "F29867F4-60F9-22B9-BAEF-6C0D7AFC57DE",
  "responsiblePid" : 727,
  "responsibleProc" : "SimulatorTrampoline",
  "codeSigningID" : "it.netguru.ibreviaryproterrasancta",
  "codeSigningTeamID" : "",
  "codeSigningFlags" : 570425857,
  "codeSigningValidationCategory" : 10,
  "codeSigningTrustLevel" : 4294967295,
  "instructionByteStream" : {"beforePC":"IQgykaBjANEx2QCUs4Ne+PMDAPnAAQCwALQzkRzKAJSI+TWwEzkA+Q==","atPC":"IAAg1PRPvqn9ewGp\/UMAkfMDAKoIAED5AKFAOQhMANEfDQCxyQQAVA=="},
  "bootSessionUUID" : "F7CF55E5-0EA7-497C-BE7B-3AEA0CAFB794",
  "sip" : "enabled",
  "exception" : {"codes":"0x0000000000000001, 0x000000018017b0e8","rawCodes":[1,6444003560],"type":"EXC_BREAKPOINT","signal":"SIGTRAP"},
  "termination" : {"flags":0,"code":5,"namespace":"SIGNAL","indicator":"Trace\/BPT trap: 5","byProc":"exc handler","byPid":2503},
  "os_fault" : {"process":"IBreviary"},
  "extMods" : {"caller":{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"system":{"thread_create":0,"thread_set_state":174,"task_for_pid":5},"targeted":{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"warnings":0},
  "faultingThread" : 2,
  "threads" : [{"id":52511,"threadState":{"x":[{"value":8257098808,"symbolLocation":16,"symbol":"OBJC_METACLASS_$__UITraitInterfaceProtectionState"},{"value":8352273633},{"value":6442874944,"symbolLocation":0,"symbol":"_objc_msgForward_impcache"},{"value":0},{"value":6443042873,"symbolLocation":393,"symbol":"_OBJC_$_INSTANCE_METHODS_NSObject"},{"value":4294967295},{"value":956},{"value":1},{"value":1},{"value":2684878849},{"value":69},{"value":8349169376},{"value":3104257},{"value":3},{"value":24},{"value":12},{"value":6442450944},{"value":10230562816},{"value":0},{"value":8352273633},{"value":6442874944,"symbolLocation":0,"symbol":"_objc_msgForward_impcache"},{"value":8257098808,"symbolLocation":16,"symbol":"OBJC_METACLASS_$__UITraitInterfaceProtectionState"},{"value":0},{"value":4},{"value":1},{"value":6442874944,"symbolLocation":0,"symbol":"_objc_msgForward_impcache"},{"value":8257098792,"symbolLocation":0,"symbol":"OBJC_METACLASS_$__UITraitInterfaceProtectionState"},{"value":4316040528},{"value":105553140684096}],"flavor":"ARM_THREAD_STATE64","lr":{"value":6442882852},"cpsr":{"value":1610616832},"fp":{"value":6157697904},"sp":{"value":6157697840},"esr":{"value":2181038087,"description":"(Instruction Abort) Translation fault"},"pc":{"value":6442882584},"far":{"value":0}},"queue":"com.apple.main-thread","frames":[{"imageOffset":22040,"symbol":"cache_t::isConstantEmptyCache() const","symbolLocation":8,"imageIndex":8},{"imageOffset":22308,"symbol":"cache_t::insert(objc_selector*, void (*)(), objc_object*)","symbolLocation":136,"imageIndex":8},{"imageOffset":111896,"symbol":"lookUpImpOrForward","symbolLocation":400,"imageIndex":8},{"imageOffset":112356,"symbol":"resolveMethod_locked(objc_object*, objc_selector*, objc_class*, int)","symbolLocation":216,"imageIndex":8},{"imageOffset":27332,"symbol":"class_respondsToSelector_inst","symbolLocation":164,"imageIndex":8},{"imageOffset":14599832,"symbol":"_UITraitTokenForTraitLocked","symbolLocation":320,"imageIndex":9},{"imageOffset":10536152,"symbol":"+[UITraitCollection traitCollectionWithNSIntegerValue:forTrait:]","symbolLocation":56,"imageIndex":9},{"imageOffset":14041332,"symbol":"-[_UIInterfaceProtectionSceneComponent _traitOverrides]","symbolLocation":48,"imageIndex":9},{"imageOffset":17584856,"symbol":"-[UIWindowScene _registerSceneComponent:forKey:]","symbolLocation":104,"imageIndex":9},{"imageOffset":2661520,"symbol":"__66+[UIScene _sceneForFBSScene:create:withSession:connectionOptions:]_block_invoke_3","symbolLocation":104,"imageIndex":9},{"imageOffset":494024,"symbol":"__NSDICTIONARY_IS_CALLING_OUT_TO_A_BLOCK__","symbolLocation":16,"imageIndex":10},{"imageOffset":1699276,"symbol":"-[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:]","symbolLocation":260,"imageIndex":10},{"imageOffset":2660076,"symbol":"+[UIScene _sceneForFBSScene:create:withSession:connectionOptions:]","symbolLocation":648,"imageIndex":9},{"imageOffset":14824540,"symbol":"-[UIApplication _connectUISceneFromFBSScene:transitionContext:]","symbolLocation":808,"imageIndex":9},{"imageOffset":14825228,"symbol":"-[UIApplication workspace:didCreateScene:withTransitionContext:completion:]","symbolLocation":304,"imageIndex":9},{"imageOffset":9382920,"symbol":"-[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:]","symbolLocation":260,"imageIndex":9},{"imageOffset":68836,"symbol":"__95-[FBSScene _callOutQueue_didCreateWithTransitionContext:alternativeCreationCallout:completion:]_block_invoke","symbolLocation":260,"imageIndex":11},{"imageOffset":69796,"symbol":"-[FBSScene _callOutQueue_coalesceClientSettingsUpdates:]","symbolLocation":60,"imageIndex":11},{"imageOffset":68452,"symbol":"-[FBSScene _callOutQueue_didCreateWithTransitionContext:alternativeCreationCallout:completion:]","symbolLocation":408,"imageIndex":11},{"imageOffset":253264,"symbol":"__93-[FBSWorkspaceScenesClient _callOutQueue_sendDidCreateForScene:transitionContext:completion:]_block_invoke.156","symbolLocation":216,"imageIndex":11},{"imageOffset":120344,"symbol":"-[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:]","symbolLocation":160,"imageIndex":11},{"imageOffset":246304,"symbol":"-[FBSWorkspaceScenesClient _callOutQueue_sendDidCreateForScene:transitionContext:completion:]","symbolLocation":388,"imageIndex":11},{"imageOffset":15840,"symbol":"_dispatch_client_callout","symbolLocation":16,"imageIndex":12},{"imageOffset":32000,"symbol":"_dispatch_block_invoke_direct","symbolLocation":376,"imageIndex":12},{"imageOffset":396120,"symbol":"__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__","symbolLocation":44,"imageIndex":11},{"imageOffset":395828,"symbol":"-[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible]","symbolLocation":196,"imageIndex":11},{"imageOffset":396172,"symbol":"-[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource]","symbolLocation":24,"imageIndex":11},{"imageOffset":590628,"symbol":"__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__","symbolLocation":24,"imageIndex":10},{"imageOffset":590444,"symbol":"__CFRunLoopDoSource0","symbolLocation":172,"imageIndex":10},{"imageOffset":588332,"symbol":"__CFRunLoopDoSources0","symbolLocation":324,"imageIndex":10},{"imageOffset":565424,"symbol":"__CFRunLoopRun","symbolLocation":788,"imageIndex":10},{"imageOffset":563552,"symbol":"CFRunLoopRunSpecific","symbolLocation":536,"imageIndex":10},{"imageOffset":15120,"symbol":"GSEventRunModal","symbolLocation":160,"imageIndex":13},{"imageOffset":14818112,"symbol":"-[UIApplication _run]","symbolLocation":796,"imageIndex":9},{"imageOffset":14835000,"symbol":"UIApplicationMain","symbolLocation":124,"imageIndex":9},{"imageOffset":8964788,"symbol":"closure #1 in KitRendererCommon(_:)","symbolLocation":164,"imageIndex":14},{"imageOffset":8964060,"symbol":"runApp<a>(_:)","symbolLocation":84,"imageIndex":14},{"imageOffset":6089868,"symbol":"static App.main()","symbolLocation":148,"imageIndex":14},{"imageOffset":3354924,"sourceFile":"\/","symbol":"static IBreviaryApp.$main()","symbolLocation":152,"imageIndex":3},{"imageOffset":3365792,"sourceLine":15,"sourceFile":"IBreviaryApp.swift","symbol":"__debug_main_executable_dylib_entry_point","imageIndex":3,"symbolLocation":12},{"imageOffset":5136,"symbol":"start_sim","symbolLocation":20,"imageIndex":2},{"imageOffset":25204,"symbol":"start","symbolLocation":2840,"imageIndex":0}]},{"id":52518,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6158266368},{"value":3587},{"value":6157729792},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6158266368},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"triggered":true,"id":52519,"threadState":{"x":[{"value":105553162585616},{"value":0},{"value":0},{"value":105553162585664},{"value":105553162585728},{"value":0},{"value":29382749080023913},{"value":105553162585600},{"value":8255094784,"symbolLocation":32,"symbol":"_OBJC_PROTOCOL_$_OS_dispatch_data"},{"value":2187565051},{"value":127},{"value":1536},{"value":2043},{"value":2045},{"value":2189662221},{"value":2187565051},{"value":2189426688},{"value":13},{"value":0},{"value":105553162585472},{"value":0},{"value":276},{"value":4},{"value":0},{"value":105553162602088},{"value":0},{"value":4351},{"value":105553140652160},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":6444003552},"cpsr":{"value":1610616832},"fp":{"value":6158837568},"sp":{"value":6158837504},"esr":{"value":4060086273,"description":"(Breakpoint) brk 1"},"pc":{"value":6444003560,"matchesCrashFrame":1},"far":{"value":0}},"queue":"com.apple.usernotifications.UNUserNotificationServiceConnection.call-out","frames":[{"imageOffset":24808,"symbol":"_dispatch_assert_queue_fail","symbolLocation":116,"imageIndex":12},{"imageOffset":24692,"symbol":"dispatch_assert_queue","symbolLocation":188,"imageIndex":12},{"imageOffset":279520,"symbol":"swift_task_isCurrentExecutorImpl(swift::SerialExecutorRef)","symbolLocation":284,"imageIndex":16},{"imageOffset":3357384,"sourceFile":"IBreviaryApp.swift","symbol":"closure #1 in AppDelegate.application(_:didFinishLaunchingWithOptions:)","symbolLocation":96,"imageIndex":3},{"imageOffset":3357604,"sourceFile":"\/","symbol":"thunk for @escaping @callee_guaranteed (@unowned Bool, @guaranteed Error?) -> ()","symbolLocation":136,"imageIndex":3},{"imageOffset":9452,"symbol":"_dispatch_call_block_and_release","symbolLocation":24,"imageIndex":12},{"imageOffset":15840,"symbol":"_dispatch_client_callout","symbolLocation":16,"imageIndex":12},{"imageOffset":48992,"symbol":"_dispatch_lane_serial_drain","symbolLocation":956,"imageIndex":12},{"imageOffset":51864,"symbol":"_dispatch_lane_invoke","symbolLocation":388,"imageIndex":12},{"imageOffset":98116,"symbol":"_dispatch_root_queue_drain_deferred_wlh","symbolLocation":276,"imageIndex":12},{"imageOffset":95648,"symbol":"_dispatch_workloop_worker_thread","symbolLocation":440,"imageIndex":12},{"imageOffset":15220,"symbol":"_pthread_wqthread","symbolLocation":284,"imageIndex":6},{"imageOffset":10548,"symbol":"start_wqthread","symbolLocation":8,"imageIndex":6}]},{"id":52520,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6159413248},{"value":11523},{"value":6158876672},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6159413248},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52521,"threadState":{"x":[{"value":182},{"value":0},{"value":182},{"value":6444359184,"symbolLocation":0,"symbol":"nanov2_malloc_type"},{"value":5},{"value":0},{"value":105553173949504},{"value":672},{"value":105553173949504},{"value":0},{"value":244838346588160},{"value":192},{"value":105553116266716},{"value":2095104},{"value":2043},{"value":3170934844},{"value":3},{"value":3173029950},{"value":0},{"value":4294967295},{"value":6159983048},{"value":6159983064},{"value":13},{"value":8053585496,"symbolLocation":0,"symbol":"__kCFAllocatorSystemDefault"},{"value":182},{"value":6159982752},{"value":8053585496,"symbolLocation":0,"symbol":"__kCFAllocatorSystemDefault"},{"value":0},{"value":105553156122560}],"flavor":"ARM_THREAD_STATE64","lr":{"value":6446493092},"cpsr":{"value":1073745920},"fp":{"value":6159982976},"sp":{"value":6159981712},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4313062824},"far":{"value":0}},"queue":"com.google.firebase.crashlytics.ios.binary-images","frames":[{"imageOffset":7592,"symbol":"read","symbolLocation":8,"imageIndex":5},{"imageOffset":327076,"symbol":"_CFReadBytesFromFile","symbolLocation":356,"imageIndex":10},{"imageOffset":997764,"symbol":"CFURLCreateDataAndPropertiesFromResource","symbolLocation":320,"imageIndex":10},{"imageOffset":1025528,"symbol":"_CFDataCreateFromURL","symbolLocation":84,"imageIndex":10},{"imageOffset":1465072,"symbol":"_CFBundleLoadNonLocTableData","symbolLocation":164,"imageIndex":10},{"imageOffset":1464160,"symbol":"_CFBundleGetStringsSources","symbolLocation":1896,"imageIndex":10},{"imageOffset":1727976,"symbol":"CFBundleGetLocalInfoDictionary","symbolLocation":196,"imageIndex":10},{"imageOffset":6693328,"symbol":"-[NSBundle localizedInfoDictionary]","symbolLocation":20,"imageIndex":17},{"imageOffset":6693372,"symbol":"-[NSBundle objectForInfoDictionaryKey:]","symbolLocation":24,"imageIndex":17},{"imageOffset":4273688,"sourceLine":544,"sourceFile":"FIRCLSBinaryImage.m","symbol":"FIRCLSBinaryImageRecordLibraryFrameworkInfo","imageIndex":3,"symbolLocation":404},{"imageOffset":4273152,"sourceLine":568,"sourceFile":"FIRCLSBinaryImage.m","symbol":"FIRCLSBinaryImageRecordSlice","imageIndex":3,"symbolLocation":240},{"imageOffset":4272176,"sourceLine":396,"sourceFile":"FIRCLSBinaryImage.m","symbol":"FIRCLSProcessBinaryImageChange","imageIndex":3,"symbolLocation":144},{"imageOffset":15840,"symbol":"_dispatch_client_callout","symbolLocation":16,"imageIndex":12},{"imageOffset":48992,"symbol":"_dispatch_lane_serial_drain","symbolLocation":956,"imageIndex":12},{"imageOffset":51864,"symbol":"_dispatch_lane_invoke","symbolLocation":388,"imageIndex":12},{"imageOffset":98116,"symbol":"_dispatch_root_queue_drain_deferred_wlh","symbolLocation":276,"imageIndex":12},{"imageOffset":95648,"symbol":"_dispatch_workloop_worker_thread","symbolLocation":440,"imageIndex":12},{"imageOffset":15220,"symbol":"_pthread_wqthread","symbolLocation":284,"imageIndex":6},{"imageOffset":10548,"symbol":"start_wqthread","symbolLocation":8,"imageIndex":6}]},{"id":52523,"threadState":{"x":[{"value":105553116309152},{"value":1},{"value":0},{"value":0},{"value":6160552760},{"value":115},{"value":105553118431776},{"value":0},{"value":0},{"value":0},{"value":6160550248},{"value":2083},{"value":1},{"value":1},{"value":2043},{"value":3332474962},{"value":4310091920,"symbolLocation":0,"symbol":"_platform_strcmp"},{"value":3334570069},{"value":0},{"value":4454384568},{"value":1},{"value":0},{"value":105553156211168},{"value":105553169825792},{"value":6491365014,"symbolLocation":8304,"symbol":"aDigits"},{"value":4320151488},{"value":0},{"value":4320151480},{"value":4454384128}],"flavor":"ARM_THREAD_STATE64","lr":{"value":6490078268},"cpsr":{"value":2147487744},"fp":{"value":6160553104},"sp":{"value":6160552992},"esr":{"value":2449473547,"description":"(Data Abort) byte read Access flag fault"},"pc":{"value":6490087072},"far":{"value":0}},"queue":"APMExperimentWorkerQueue","frames":[{"imageOffset":220832,"symbol":"unixLock","symbolLocation":68,"imageIndex":19},{"imageOffset":212028,"symbol":"sqlite3PagerSharedLock","symbolLocation":376,"imageIndex":19},{"imageOffset":312964,"symbol":"btreeBeginTrans","symbolLocation":812,"imageIndex":19},{"imageOffset":421868,"symbol":"sqlite3InitOne","symbolLocation":576,"imageIndex":19},{"imageOffset":150520,"symbol":"sqlite3Init","symbolLocation":72,"imageIndex":19},{"imageOffset":486896,"symbol":"sqlite3ReadSchema","symbolLocation":48,"imageIndex":19},{"imageOffset":582836,"symbol":"sqlite3Pragma","symbolLocation":1276,"imageIndex":19},{"imageOffset":504228,"symbol":"yy_reduce","symbolLocation":6672,"imageIndex":19},{"imageOffset":119076,"symbol":"sqlite3RunParser","symbolLocation":992,"imageIndex":19},{"imageOffset":470604,"symbol":"sqlite3Prepare","symbolLocation":416,"imageIndex":19},{"imageOffset":113140,"symbol":"sqlite3LockAndPrepare","symbolLocation":220,"imageIndex":19},{"imageOffset":6526368,"symbol":"-[APMSqliteStore prepareSQL:error:]","symbolLocation":176,"imageIndex":3},{"imageOffset":6527584,"symbol":"-[APMSqliteStore validateDatabaseWithError:]","symbolLocation":76,"imageIndex":3},{"imageOffset":6527392,"symbol":"-[APMSqliteStore openAndValidateDatabase:]","symbolLocation":520,"imageIndex":3},{"imageOffset":6512232,"symbol":"-[APMSqliteStore initWithDatabasePath:error:]","symbolLocation":184,"imageIndex":3},{"imageOffset":6001148,"symbol":"-[APMEDatabase initializeDatabaseResourcesWithContext:databasePath:]","symbolLocation":92,"imageIndex":3},{"imageOffset":6000932,"symbol":"-[APMEDatabase initWithPath:]","symbolLocation":124,"imageIndex":3},{"imageOffset":6031788,"symbol":"-[APMETaskManager startTaskManagerOnWorkerQueue]","symbolLocation":56,"imageIndex":3},{"imageOffset":6031716,"symbol":"__35-[APMETaskManager startTaskManager]_block_invoke","symbolLocation":28,"imageIndex":3},{"imageOffset":6036624,"symbol":"__46-[APMETaskManager dispatchAsyncOnWorkerQueue:]_block_invoke","symbolLocation":36,"imageIndex":3},{"imageOffset":9452,"symbol":"_dispatch_call_block_and_release","symbolLocation":24,"imageIndex":12},{"imageOffset":15840,"symbol":"_dispatch_client_callout","symbolLocation":16,"imageIndex":12},{"imageOffset":48992,"symbol":"_dispatch_lane_serial_drain","symbolLocation":956,"imageIndex":12},{"imageOffset":51864,"symbol":"_dispatch_lane_invoke","symbolLocation":388,"imageIndex":12},{"imageOffset":98116,"symbol":"_dispatch_root_queue_drain_deferred_wlh","symbolLocation":276,"imageIndex":12},{"imageOffset":95648,"symbol":"_dispatch_workloop_worker_thread","symbolLocation":440,"imageIndex":12},{"imageOffset":15220,"symbol":"_pthread_wqthread","symbolLocation":284,"imageIndex":6},{"imageOffset":10548,"symbol":"start_wqthread","symbolLocation":8,"imageIndex":6}]},{"id":52524,"threadState":{"x":[{"value":1},{"value":8},{"value":0},{"value":6161126191},{"value":6161126496},{"value":6161126495},{"value":6161126880},{"value":6161126879},{"value":4339444304},{"value":4337458464},{"value":4339714480},{"value":6161126504},{"value":46},{"value":1},{"value":7697720},{"value":3356280},{"value":6445329204,"symbolLocation":0,"symbol":"dladdr"},{"value":6446586532,"symbolLocation":0,"symbol":"-[__NSCFNumber unsignedLongValue]"},{"value":0},{"value":6161127240},{"value":6161126840},{"value":4328456192},{"value":4336812032},{"value":11399040},{"value":8241152},{"value":3357384},{"value":5143728},{"value":4337318352},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":4309438384},"cpsr":{"value":536875008},"fp":{"value":6161126736},"sp":{"value":6161126448},"esr":{"value":2449473547,"description":"(Data Abort) byte read Access flag fault"},"pc":{"value":4309438596},"far":{"value":0}},"queue":"com.google.firebase.crashlytics.startup","frames":[{"imageOffset":184452,"symbol":"dyld3::MachOLoaded::findClosestSymbol(unsigned long long, char const**, unsigned long long*) const","symbolLocation":460,"imageIndex":2},{"imageOffset":121084,"symbol":"dyld4::APIs::dladdr(void const*, dl_info*)","symbolLocation":228,"imageIndex":2},{"imageOffset":4451012,"sourceLine":143,"sourceFile":"FIRCLSSymbolResolver.m","symbol":"-[FIRCLSSymbolResolver updateStackFrame:]","imageIndex":3,"symbolLocation":416},{"imageOffset":4468872,"sourceLine":23,"sourceFile":"FIRCLSSymbolicationOperation.m","symbol":"__36-[FIRCLSSymbolicationOperation main]_block_invoke","imageIndex":3,"symbolLocation":92},{"imageOffset":4469528,"sourceLine":22,"sourceFile":"FIRCLSThreadArrayOperation.m","symbol":"-[FIRCLSThreadArrayOperation enumerateFramesWithBlock:]","imageIndex":3,"symbolLocation":472},{"imageOffset":4468756,"sourceLine":22,"sourceFile":"FIRCLSSymbolicationOperation.m","symbol":"-[FIRCLSSymbolicationOperation main]","imageIndex":3,"symbolLocation":124},{"imageOffset":7468380,"symbol":"__NSOPERATION_IS_INVOKING_MAIN__","symbolLocation":12,"imageIndex":17},{"imageOffset":7453376,"symbol":"-[NSOperation start]","symbolLocation":620,"imageIndex":17},{"imageOffset":4464752,"sourceLine":96,"sourceFile":"FIRCLSProcessReportOperation.m","symbol":"-[FIRCLSProcessReportOperation symbolicateFile:withResolver:]","imageIndex":3,"symbolLocation":372},{"imageOffset":4465296,"sourceLine":109,"sourceFile":"FIRCLSProcessReportOperation.m","symbol":"__36-[FIRCLSProcessReportOperation main]_block_invoke","imageIndex":3,"symbolLocation":116},{"imageOffset":4431384,"sourceLine":169,"sourceFile":"FIRCLSInternalReport.m","symbol":"-[FIRCLSInternalReport enumerateSymbolicatableFilesInContent:]","imageIndex":3,"symbolLocation":312},{"imageOffset":4465144,"sourceLine":108,"sourceFile":"FIRCLSProcessReportOperation.m","symbol":"-[FIRCLSProcessReportOperation main]","imageIndex":3,"symbolLocation":244},{"imageOffset":7468380,"symbol":"__NSOPERATION_IS_INVOKING_MAIN__","symbolLocation":12,"imageIndex":17},{"imageOffset":7453376,"symbol":"-[NSOperation start]","symbolLocation":620,"imageIndex":17},{"imageOffset":4344664,"sourceLine":126,"sourceFile":"FIRCLSReportUploader.m","symbol":"__91-[FIRCLSReportUploader prepareAndSubmitReport:dataCollectionToken:asUrgent:withProcessing:]_block_invoke","imageIndex":3,"symbolLocation":672},{"imageOffset":4268896,"sourceLine":231,"sourceFile":"FIRCLSApplication.m","symbol":"FIRCLSApplicationActivity","imageIndex":3,"symbolLocation":108},{"imageOffset":4343900,"sourceLine":87,"sourceFile":"FIRCLSReportUploader.m","symbol":"-[FIRCLSReportUploader prepareAndSubmitReport:dataCollectionToken:asUrgent:withProcessing:]","imageIndex":3,"symbolLocation":320},{"imageOffset":4313588,"sourceLine":236,"sourceFile":"FIRCLSExistingReportManager.m","symbol":"-[FIRCLSExistingReportManager processExistingActiveReportPath:dataCollectionToken:asUrgent:]","imageIndex":3,"symbolLocation":420},{"imageOffset":4311144,"sourceLine":182,"sourceFile":"FIRCLSExistingReportManager.m","symbol":"-[FIRCLSExistingReportManager sendUnsentReportsWithToken:asUrgent:]","imageIndex":3,"symbolLocation":304},{"imageOffset":4339912,"sourceLine":407,"sourceFile":"FIRCLSReportManager.m","symbol":"-[FIRCLSReportManager beginReportUploadsWithToken:blockingSend:]","imageIndex":3,"symbolLocation":164},{"imageOffset":4337720,"sourceLine":323,"sourceFile":"FIRCLSReportManager.m","symbol":"__41-[FIRCLSReportManager startWithProfiling]_block_invoke","imageIndex":3,"symbolLocation":80},{"imageOffset":3954088,"sourceLine":273,"sourceFile":"FBLPromise.m","symbol":"__56-[FBLPromise chainOnQueue:chainedFulfill:chainedReject:]_block_invoke.33","imageIndex":3,"symbolLocation":100},{"imageOffset":3952520,"sourceLine":238,"sourceFile":"FBLPromise.m","symbol":"__44-[FBLPromise observeOnQueue:fulfill:reject:]_block_invoke.28","imageIndex":3,"symbolLocation":52},{"imageOffset":9452,"symbol":"_dispatch_call_block_and_release","symbolLocation":24,"imageIndex":12},{"imageOffset":15840,"symbol":"_dispatch_client_callout","symbolLocation":16,"imageIndex":12},{"imageOffset":49208,"symbol":"_dispatch_lane_serial_drain","symbolLocation":1172,"imageIndex":12},{"imageOffset":51864,"symbol":"_dispatch_lane_invoke","symbolLocation":388,"imageIndex":12},{"imageOffset":98116,"symbol":"_dispatch_root_queue_drain_deferred_wlh","symbolLocation":276,"imageIndex":12},{"imageOffset":95648,"symbol":"_dispatch_workloop_worker_thread","symbolLocation":440,"imageIndex":12},{"imageOffset":15220,"symbol":"_pthread_wqthread","symbolLocation":284,"imageIndex":6},{"imageOffset":10548,"symbol":"start_wqthread","symbolLocation":8,"imageIndex":6}]},{"id":52530,"name":"com.apple.uikit.eventfetch-thread","threadState":{"x":[{"value":268451845},{"value":21592279046},{"value":8589934592},{"value":90172838379520},{"value":4294967295},{"value":90172838379520},{"value":2},{"value":4294967295},{"value":18446744073709550527},{"value":2},{"value":4294967295},{"value":0},{"value":0},{"value":20995},{"value":3072},{"value":3120793615},{"value":18446744073709551569},{"value":3122890747},{"value":0},{"value":4294967295},{"value":2},{"value":90172838379520},{"value":4294967295},{"value":90172838379520},{"value":6161702264},{"value":8589934592},{"value":21592279046},{"value":21592279046},{"value":4412409862}],"flavor":"ARM_THREAD_STATE64","lr":{"value":4313130692},"cpsr":{"value":4096},"fp":{"value":6161702112},"sp":{"value":6161702032},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4313059984},"far":{"value":0}},"frames":[{"imageOffset":4752,"symbol":"mach_msg2_trap","symbolLocation":8,"imageIndex":5},{"imageOffset":75460,"symbol":"mach_msg2_internal","symbolLocation":76,"imageIndex":5},{"imageOffset":37876,"symbol":"mach_msg_overwrite","symbolLocation":536,"imageIndex":5},{"imageOffset":5580,"symbol":"mach_msg","symbolLocation":20,"imageIndex":5},{"imageOffset":588640,"symbol":"__CFRunLoopServiceMachPort","symbolLocation":156,"imageIndex":10},{"imageOffset":565796,"symbol":"__CFRunLoopRun","symbolLocation":1160,"imageIndex":10},{"imageOffset":563552,"symbol":"CFRunLoopRunSpecific","symbolLocation":536,"imageIndex":10},{"imageOffset":7671588,"symbol":"-[NSRunLoop(NSRunLoop) runMode:beforeDate:]","symbolLocation":208,"imageIndex":17},{"imageOffset":7672132,"symbol":"-[NSRunLoop(NSRunLoop) runUntilDate:]","symbolLocation":60,"imageIndex":17},{"imageOffset":15522952,"symbol":"-[UIEventFetcher threadMain]","symbolLocation":404,"imageIndex":9},{"imageOffset":7830892,"symbol":"__NSThread__start__","symbolLocation":720,"imageIndex":17},{"imageOffset":30456,"symbol":"_pthread_start","symbolLocation":104,"imageIndex":6},{"imageOffset":10560,"symbol":"thread_start","symbolLocation":8,"imageIndex":6}]},{"id":52533,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6162280448},{"value":18691},{"value":6161743872},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6162280448},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52534,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6162853888},{"value":12815},{"value":6162317312},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6162853888},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52535,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6163427328},{"value":22279},{"value":6162890752},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6163427328},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52536,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6164000768},{"value":32003},{"value":6163464192},{"value":0},{"value":409602},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6164000768},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52538,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6164574208},{"value":22531},{"value":6164037632},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6164574208},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52539,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6165147648},{"value":31747},{"value":6164611072},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6165147648},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52540,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6165721088},{"value":31491},{"value":6165184512},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6165721088},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52541,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6166294528},{"value":22787},{"value":6165757952},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6166294528},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52542,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6166867968},{"value":31235},{"value":6166331392},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6166867968},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52543,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6167441408},{"value":23043},{"value":6166904832},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6167441408},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52544,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6168014848},{"value":30979},{"value":6167478272},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6168014848},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52545,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6168588288},{"value":23299},{"value":6168051712},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6168588288},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52546,"threadState":{"x":[{"value":1},{"value":0},{"value":2},{"value":6169158704},{"value":2},{"value":0},{"value":0},{"value":1027},{"value":1024},{"value":8255030336,"symbolLocation":0,"symbol":"_dispatch_mgr_q"},{"value":1024},{"value":137438953472},{"value":27021597764222978},{"value":137438953472},{"value":9005137670438912},{"value":18446744073709551615},{"value":375},{"value":4334524672,"symbolLocation":0,"symbol":"-[APMIdentity appIDFromGMP]"},{"value":0},{"value":1027},{"value":0},{"value":0},{"value":2},{"value":6169158704},{"value":2},{"value":6169158704},{"value":105553162466688},{"value":8255030336,"symbolLocation":0,"symbol":"_dispatch_mgr_q"},{"value":132096}],"flavor":"ARM_THREAD_STATE64","lr":{"value":6444140612},"cpsr":{"value":4096},"fp":{"value":6169158672},"sp":{"value":6169158576},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4313066980},"far":{"value":0}},"queue":"com.google.fira.worker","frames":[{"imageOffset":11748,"symbol":"kevent_id","symbolLocation":8,"imageIndex":5},{"imageOffset":161860,"symbol":"_dispatch_kq_poll","symbolLocation":216,"imageIndex":12},{"imageOffset":164724,"symbol":"_dispatch_event_loop_wait_for_ownership","symbolLocation":540,"imageIndex":12},{"imageOffset":81344,"symbol":"__DISPATCH_WAIT_FOR_QUEUE__","symbolLocation":364,"imageIndex":12},{"imageOffset":80092,"symbol":"_dispatch_sync_f_slow","symbolLocation":160,"imageIndex":12},{"imageOffset":6068604,"symbol":"-[APMIdentity appIDFromGMP]","symbolLocation":124,"imageIndex":3},{"imageOffset":6115228,"symbol":"-[APMMeasurement updatePersistedAppIDFromGMPAndAdMob]","symbolLocation":28,"imageIndex":3},{"imageOffset":6116424,"symbol":"__47-[APMMeasurement startMeasurementOnWorkerQueue]_block_invoke","symbolLocation":488,"imageIndex":3},{"imageOffset":6115736,"symbol":"-[APMMeasurement startMeasurementOnWorkerQueue]","symbolLocation":140,"imageIndex":3},{"imageOffset":6113788,"symbol":"-[APMMeasurement setEnabledOnWorkerQueue:]","symbolLocation":216,"imageIndex":3},{"imageOffset":6113556,"symbol":"__29-[APMMeasurement setEnabled:]_block_invoke","symbolLocation":36,"imageIndex":3},{"imageOffset":6488292,"symbol":"__51-[APMScheduler scheduleOnWorkerQueueBlockID:block:]_block_invoke","symbolLocation":44,"imageIndex":3},{"imageOffset":9452,"symbol":"_dispatch_call_block_and_release","symbolLocation":24,"imageIndex":12},{"imageOffset":15840,"symbol":"_dispatch_client_callout","symbolLocation":16,"imageIndex":12},{"imageOffset":48992,"symbol":"_dispatch_lane_serial_drain","symbolLocation":956,"imageIndex":12},{"imageOffset":51864,"symbol":"_dispatch_lane_invoke","symbolLocation":388,"imageIndex":12},{"imageOffset":98116,"symbol":"_dispatch_root_queue_drain_deferred_wlh","symbolLocation":276,"imageIndex":12},{"imageOffset":95648,"symbol":"_dispatch_workloop_worker_thread","symbolLocation":440,"imageIndex":12},{"imageOffset":15220,"symbol":"_pthread_wqthread","symbolLocation":284,"imageIndex":6},{"imageOffset":10548,"symbol":"start_wqthread","symbolLocation":8,"imageIndex":6}]},{"id":52547,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6169735168},{"value":23555},{"value":6169198592},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6169735168},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52548,"frames":[{"imageOffset":10540,"symbol":"start_wqthread","symbolLocation":0,"imageIndex":6}],"threadState":{"x":[{"value":6170308608},{"value":23811},{"value":6169772032},{"value":0},{"value":409604},{"value":18446744073709551615},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":0},"cpsr":{"value":4096},"fp":{"value":0},"sp":{"value":6170308608},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4312279340},"far":{"value":0}}},{"id":52555,"name":"com.google.firebase.crashlytics.MachExceptionServer","threadState":{"x":[{"value":1},{"value":0},{"value":1},{"value":4310092520},{"value":10758893076481},{"value":0},{"value":0},{"value":0},{"value":4335300216},{"value":0},{"value":1},{"value":2505},{"value":0},{"value":0},{"value":0},{"value":8255036968,"symbolLocation":0,"symbol":"_NSConcreteStackBlock"},{"value":4},{"value":6443462048,"symbolLocation":0,"symbol":"-[__NSStackBlock__ release]"},{"value":0},{"value":6170329088},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":4332869004},"cpsr":{"value":4096},"fp":{"value":4327554720},"sp":{"value":4327554528},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":4313074168},"far":{"value":0}},"frames":[{"imageOffset":18936,"symbol":"write","symbolLocation":8,"imageIndex":5},{"imageOffset":4412812,"sourceLine":62,"sourceFile":"FIRCLSInternalLogging.c","symbol":"FIRCLSSDKFileLog","imageIndex":3,"symbolLocation":436},{"imageOffset":4390412,"sourceLine":269,"sourceFile":"FIRCLSMachException.c","symbol":"FIRCLSMachExceptionReply","imageIndex":3,"symbolLocation":332},{"imageOffset":4389040,"sourceLine":180,"sourceFile":"FIRCLSMachException.c","symbol":"FIRCLSMachExceptionServer","imageIndex":3,"symbolLocation":100},{"imageOffset":30456,"symbol":"_pthread_start","symbolLocation":104,"imageIndex":6},{"imageOffset":10560,"symbol":"thread_start","symbolLocation":8,"imageIndex":6}]}],
  "usedImages" : [
  {
    "source" : "P",
    "arch" : "arm64e",
    "base" : 4310286336,
    "size" : 540672,
    "uuid" : "02e3ca05-e849-31c8-a4f2-c7292420dfad",
    "path" : "\/usr\/lib\/dyld",
    "name" : "dyld"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 4309172224,
    "CFBundleShortVersionString" : "9.1.0",
    "CFBundleIdentifier" : "it.netguru.ibreviaryproterrasancta",
    "size" : 16384,
    "uuid" : "d49a25e1-0486-3466-bcb3-50d478688bfa",
    "path" : "\/Users\/USER\/Library\/Developer\/CoreSimulator\/Devices\/16AD31A6-E5E4-496D-90C8-317ECA5C848E\/data\/Containers\/Bundle\/Application\/B7A991A7-E46A-4C39-9474-8D35F517017D\/IBreviary.app\/IBreviary",
    "name" : "IBreviary",
    "CFBundleVersion" : "1.0.0"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 4309254144,
    "size" : 278528,
    "uuid" : "6499b476-4b66-3148-b85b-496aa7ea0690",
    "path" : "\/Volumes\/VOLUME\/*\/dyld_sim",
    "name" : "dyld_sim"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 4328456192,
    "size" : 7618560,
    "uuid" : "237f8b3c-2e19-3675-a628-2038d81f3a6f",
    "path" : "\/Users\/USER\/Library\/Developer\/CoreSimulator\/Devices\/16AD31A6-E5E4-496D-90C8-317ECA5C848E\/data\/Containers\/Bundle\/Application\/B7A991A7-E46A-4C39-9474-8D35F517017D\/IBreviary.app\/IBreviary.debug.dylib",
    "name" : "IBreviary.debug.dylib"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 4310089728,
    "size" : 32768,
    "uuid" : "cac022b0-a3f8-30b6-8328-16b8f49134fc",
    "path" : "\/usr\/lib\/system\/libsystem_platform.dylib",
    "name" : "libsystem_platform.dylib"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 4313055232,
    "size" : 245760,
    "uuid" : "7608fd64-96fa-3081-bf0a-75b678fbb4e6",
    "path" : "\/usr\/lib\/system\/libsystem_kernel.dylib",
    "name" : "libsystem_kernel.dylib"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 4312268800,
    "size" : 65536,
    "uuid" : "a7b14a67-6701-3dd4-b1ca-738197b71fb0",
    "path" : "\/usr\/lib\/system\/libsystem_pthread.dylib",
    "name" : "libsystem_pthread.dylib"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 4313743360,
    "size" : 49152,
    "uuid" : "5456a55f-46e1-386f-a22e-35e385923f2d",
    "path" : "\/Volumes\/VOLUME\/*\/libobjc-trampolines.dylib",
    "name" : "libobjc-trampolines.dylib"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 6442860544,
    "size" : 245156,
    "uuid" : "eea0093e-1937-3650-ac0f-430162fd94d5",
    "path" : "\/Volumes\/VOLUME\/*\/libobjc.A.dylib",
    "name" : "libobjc.A.dylib"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 6522671104,
    "CFBundleShortVersionString" : "1.0",
    "CFBundleIdentifier" : "com.apple.UIKitCore",
    "size" : 30367744,
    "uuid" : "d41f23e0-fb5e-33e4-9687-bb277a61190f",
    "path" : "\/Volumes\/VOLUME\/*\/UIKitCore.framework\/UIKitCore",
    "name" : "UIKitCore",
    "CFBundleVersion" : "8081.1.108"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 6446166016,
    "CFBundleShortVersionString" : "6.9",
    "CFBundleIdentifier" : "com.apple.CoreFoundation",
    "size" : 3997696,
    "uuid" : "5f40c0e3-6b50-30c6-a686-3ab03c9a5404",
    "path" : "\/Volumes\/VOLUME\/*\/CoreFoundation.framework\/CoreFoundation",
    "name" : "CoreFoundation",
    "CFBundleVersion" : "3038.1.101"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 6569869312,
    "CFBundleShortVersionString" : "943.1.1.1",
    "CFBundleIdentifier" : "com.apple.FrontBoardServices",
    "size" : 782336,
    "uuid" : "21704388-b15b-3081-a6e9-3ad7fc4828a3",
    "path" : "\/Volumes\/VOLUME\/*\/FrontBoardServices.framework\/FrontBoardServices",
    "name" : "FrontBoardServices",
    "CFBundleVersion" : "943.1.1.1"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 6443978752,
    "size" : 282624,
    "uuid" : "71b0ee55-14d3-363f-88de-27caee135593",
    "path" : "\/Volumes\/VOLUME\/*\/libdispatch.dylib",
    "name" : "libdispatch.dylib"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 6712459264,
    "CFBundleShortVersionString" : "1.0",
    "CFBundleIdentifier" : "com.apple.GraphicsServices",
    "size" : 36864,
    "uuid" : "587e9fae-3ada-346c-a206-e2949d400fff",
    "path" : "\/Volumes\/VOLUME\/*\/GraphicsServices.framework\/GraphicsServices",
    "name" : "GraphicsServices",
    "CFBundleVersion" : "1.0"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 7807311872,
    "CFBundleShortVersionString" : "6.0.87.1.105",
    "CFBundleIdentifier" : "com.apple.SwiftUI",
    "size" : 18591744,
    "uuid" : "cfae81a0-dbe9-328f-8ffb-a04fa9e9fb05",
    "path" : "\/Volumes\/VOLUME\/*\/SwiftUI.framework\/SwiftUI",
    "name" : "SwiftUI",
    "CFBundleVersion" : "6.0.87.1.105"
  },
  {
    "size" : 0,
    "source" : "A",
    "base" : 0,
    "uuid" : "00000000-0000-0000-0000-000000000000"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 9735512064,
    "size" : 397304,
    "uuid" : "6426c1c4-b325-3601-97fa-5ff51dc1d400",
    "path" : "\/Volumes\/VOLUME\/*\/libswift_Concurrency.dylib",
    "name" : "libswift_Concurrency.dylib"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 6450683904,
    "CFBundleShortVersionString" : "6.9",
    "CFBundleIdentifier" : "com.apple.Foundation",
    "size" : 12873728,
    "uuid" : "1a4bc02e-f4dc-3ab5-9bb7-61d28064ffe8",
    "path" : "\/Volumes\/VOLUME\/*\/Foundation.framework\/Foundation",
    "name" : "Foundation",
    "CFBundleVersion" : "3038.1.101"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 6444261376,
    "size" : 249856,
    "uuid" : "ea9fb439-ff22-35af-aa45-d8e4687a357b",
    "path" : "\/Volumes\/VOLUME\/*\/libsystem_malloc.dylib",
    "name" : "libsystem_malloc.dylib"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 6489866240,
    "size" : 1544192,
    "uuid" : "5030d655-3c88-3ba3-a056-f91a552e20a3",
    "path" : "\/Volumes\/VOLUME\/*\/libsqlite3.dylib",
    "name" : "libsqlite3.dylib"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 6445281280,
    "size" : 159740,
    "uuid" : "c1530a09-477b-3916-97bf-39d147a69c38",
    "path" : "\/Volumes\/VOLUME\/*\/libdyld.dylib",
    "name" : "libdyld.dylib"
  },
  {
    "source" : "P",
    "arch" : "arm64",
    "base" : 6443458560,
    "size" : 12281,
    "uuid" : "a8d7048d-ff4f-33c2-bef5-18ec6aaf90dc",
    "path" : "\/Volumes\/VOLUME\/*\/libsystem_blocks.dylib",
    "name" : "libsystem_blocks.dylib"
  }
],
  "sharedCache" : {
  "base" : 6442450944,
  "size" : 3788111872,
  "uuid" : "10c4b65c-4eda-37e9-b0e7-c6360b3230f2"
},
  "vmSummary" : "ReadOnly portion of Libraries: Total=1.4G resident=0K(0%) swapped_out_or_unallocated=1.4G(100%)\nWritable regions: Total=626.3M written=1703K(0%) resident=1703K(0%) swapped_out=0K(0%) unallocated=624.7M(100%)\n\n                                VIRTUAL   REGION \nREGION TYPE                        SIZE    COUNT (non-coalesced) \n===========                     =======  ======= \nActivity Tracing                   256K        1 \nAttributeGraph Data               1024K        1 \nColorSync                           48K        3 \nCoreData Object IDs               4112K        2 \nFoundation                          16K        1 \nKernel Alloc Once                   32K        1 \nMALLOC                           597.5M       47 \nMALLOC guard page                  192K       12 \nMach message                        16K        1 \nSQLite page cache                  640K        5 \nSTACK GUARD                       56.4M       23 \nStack                             19.7M       24 \nVM_ALLOCATE                        672K        6 \n__DATA                            24.6M      631 \n__DATA_CONST                      69.1M      650 \n__DATA_DIRTY                       107K       12 \n__FONT_DATA                        2352        1 \n__LINKEDIT                       681.7M        9 \n__OBJC_RW                         2686K        1 \n__TEXT                           724.4M      664 \n__TPRO_CONST                       580K        3 \ndyld private memory                2.6G        8 \nmapped file                       39.6M        7 \nowned unmapped memory               64K        1 \npage table in kernel              1703K        1 \nshared memory                       16K        1 \n===========                     =======  ======= \nTOTAL                              4.8G     2116 \n",
  "legacyInfo" : {
  "threadTriggered" : {
    "queue" : "com.apple.usernotifications.UNUserNotificationServiceConnection.call-out"
  }
},
  "logWritingSignature" : "db986f6c0d8045f8942922f24b56661e3b113be6",
  "trialInfo" : {
  "rollouts" : [
    {
      "rolloutId" : "64628732bf2f5257dedc8988",
      "factorPackIds" : {

      },
      "deploymentId" : 240000001
    },
    {
      "rolloutId" : "60f8ddccefea4203d95cbeef",
      "factorPackIds" : {

      },
      "deploymentId" : 240000025
    }
  ],
  "experiments" : [
    {
      "treatmentId" : "45f4e2a5-551b-4bc2-a2dc-19c244dda8f8",
      "experimentId" : "6643969b3099cf28e049862f",
      "deploymentId" : 400000007
    }
  ]
}
}
</a>

Thanks for the crash report.

Consider this snippet:

@MainActor var counter = 0

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions …) -> Bool {
        counter += 1
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { _, _ in
            counter += 1
       }
        return true
    }
    …
}

I’m compiling this with Xcode 16.0 in the Swift 6 language mode.

The increments of counter show that Swift thinks that both application(_:didFinishLaunchingWithOptions:) and the closure are supposed to be running on the main actor. However, the closure called by requestAuthorization(options:completionHandler:) is documented to not run there. I’d expect that the compiler would insert code to ‘bounce’ to the main actor, but instead it inserted code to trap if it’s not on the main actor.

I’m not sure why it thinks that in this context. Oh, and I checked with the latest Xcode 16.1 beta, and it has the same issue.

I’m gonna do some more research about this (FB15294185) but, for the moment, you can avoid the crash by calling the Swift async function variant of the API:

let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
Task {
    do {
        _ = try await UNUserNotificationCenter.current().requestAuthorization(options: authOptions)
        print("here")
    } catch {
        print("there")
    }
}

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I can confirm that your workaround is working and the app is not crashing anymore. I'll check for future resolution of the problem.

Thanks Quinn!

FWIW, I was experiencing the same phenomenon (crashes related to multi threading issues) in a few other places:

  • LAContext.evaluatePolicy(_:localizedReason:reply:)
  • UNUserNotificationCenter.getNotificationSettings(completionHandler:)
  • UNUserNotificationCenter.add(_:withCompletionHandler:)

In all of these cases, the workaround suggested by Quinn did the trick of avoiding the crash.

Best Regards, Viktor

Written by DTS Engineer in 806202022
I’m gonna do some more research about this (FB15294185)

I spent some time talking this over with various colleagues, just to make sure I fully understand what’s going on. The high-level summary is:

  • Swift 6 has inserted a run-time check to catch a concurrency issue that Swift 5 did not.

  • This isn’t caught at compile time because of a Swift / Objective-C impedance mismatch.

If you want to know more, follow me down the rabbit hole!


Consider this simplified version of Artecoop’s test code:

@main
final class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    
    func applicationDidFinishLaunching(_ application: UIApplication) {
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound, .badge]) { success, error in
            print(success)
            assert(Thread.isMainThread)
        }
    }
}

The entire did-finish-launching method should run on the main actor. That’s because:

  • The method itself is part of the implementation of the UIApplicationDelegate protocol, and that’s declared @MainActor.

  • The requestAuthorization(…) method doesn’t do anything to tell the Swift compiler that it will call the completion handler on a secondary thread (more on that below).

If you build this program in Swift 6 mode, on running it you trap before the print(…) call, in a main actor check inserted by the Swift compiler. That’s the central complaint of the original post.

However, consider what happens if you build this in Swift 5 mode. This time it traps in the assert(…). So this trap is clearly an improvement: Swift 6 mode is consistently detecting a problem that could otherwise cause a data race.


However, that explanation leaves a number of unanswered questions. Let’s start with fixes.

The fix I described above, calling the async version of the method, works because the Swift compiler implements the async method with code that kinda looks something like this:

extension UNUserNotificationCenter {

    func requestNotificationQQQ1(
        options: UNAuthorizationOptions
    ) async throws -> Bool {
        try await withCheckedThrowingContinuation { cont in
            self.requestAuthorization(options: options) { success, error in
                if success {
                    cont.resume(returning: true)
                } else {
                    cont.resume(throwing: error!)
                }
            }
        }
    }
}

In this case the completion handler isn’t bound to the main actor and thus the compiler doesn’t add an assert. And the CheckedContinuation type is thread safe, so calling its methods from any thread is fine.

The other fix is to make the closure as @Sendable:

center.requestAuthorization(options: [.alert, .sound, .badge]) { @Sendable success, error in
    print(success)
    // print(self.window)
}

This disconnects the closure from the main actor and thus there’s no main actor check. However, it also means that you can’t access main actor state in the closure. If you uncomment the access to self.window, the compiler complains that Main actor-isolated property 'window' can not be referenced from a Sendable closure.


Finally, let’s come back to why the compiler doesn’t know that the completion handler can be called on any thread. That’s tied to the Objective-C declaration, which is imported into Swift as:

func requestAuthorization(
    options: UNAuthorizationOptions = [],
    completionHandler: @escaping (Bool, (any Error)?) -> Void
)

Imagine you wrote your own (very bad :-) [1] version of this in Swift:

extension UNUserNotificationCenter {

    func requestAuthorizationQQQ2(
        options: UNAuthorizationOptions = [],
        completionHandler: @escaping (Bool, (any Error)?) -> Void
    ) {
        DispatchQueue.global().asyncAfter(deadline: .now() + 0.1) {
            completionHandler(true, nil)
         // ^ Capture of 'completionHandler' with non-sendable type '(Bool, (any Error)?) -> Void' in a `@Sendable` closure
        }
    }
}

The compiler complains that the closure is being sent across isolation domains even though it’s not sendable. That’s obviously bad.

The thing to note here is that this is exactly what Objective-C is doing, and it’s why you’re running into the problem.

The most straightforward way to fix the requestAuthorizationQQQ2(…) method is to replace @escaping with @Sendable. And the equivalent of doing that in Objective-C is to add NS_SWIFT_SENDABLE to the completion handler parameter of the -requestAuthorizationWithOptions:completionHandler: method [2].

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] To start, I’m not following my own advice here: Avoid Dispatch Global Concurrent Queues

[2] It wouldn’t surprise me if that were the final resolution of FB15294185, but that’s still in The Future™.

Man, that's an explanation!

Thanks for sharing the insight of the problem, so me and everyone that will hit this post can understand and fix its own code.

Thanks again Quinn

Written by Artecoop in 807348022
Man, an explanation!

Yep. Mostly I write this stuff down as an excuse to get it straight in my own head (-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi,

I tried to apply the solution of Quinn to UNUserNotificationCenter.getNotificationSettings(completionHandler:) and get the error "Non-sendable type 'UNNotificationSettings' returned by implicitly asynchronous call to nonisolated function cannot cross actor boundary"

It would be great if someone could help me to fix it.

func getNotificationSettings() {
        let center = UNUserNotificationCenter.current()
        Task {
            let settings = await center.notificationSettings() // here I get the error "Non-sendable type 'UNNotificationSettings' returned by implicitly asynchronous call to nonisolated function cannot cross actor boundary"
            let authorizationStatus = settings.authorizationStatus
        }
    }

Thank you!

Hi

in the meantime I solved it like this. Maybe this is helpful for someone.

    func getUserNotificationPermission(completion: @Sendable @escaping (String) -> Void) {
        DispatchQueue.global(qos: .userInteractive).async {
            UNUserNotificationCenter.current().getNotificationSettings { settings in
                if settings.authorizationStatus == .authorized {
                    completion("authorized")
                }
                
                if settings.authorizationStatus == .provisional {
                    completion("authorized")
                }
                
                if settings.authorizationStatus == .ephemeral {
                    completion("authorized")
                }
                
                if settings.authorizationStatus == .denied {
                    completion("denied")
                }
                
                if settings.authorizationStatus == .notDetermined {
                    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { success, error in
                        if success {
                            completion("authorized")
                        } else {
                            completion("denied")
                        }
                    }
                }
            }
        }
    }

I can call this function via a Button from a SwiftUI View:

struct ContentView: View {
    var body: some View {
        VStack {
            Button("getUserNotificationPermission") {
                getUserNotificationPermission { permission in
                    if permission == "authorized" {
                        print("permission: \(permission)")
                    }
                }
            }
        }
    }
}


I presume that getNotificationSettings() is a method on an main-actor-isolated type, like your app delegate. If it isn’t, you don’t get this error.

If so, the easiest fix is to mark getNotificationSettings() as nonisolated.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I can attest that AVCaptureDevice.requestAccess suffered from this same problem, i.e. crashing with a thread/queue violation when built under Swift 6.

Original code:

AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: { granted in
  if (granted)
  {
      DispatchQueue.main.async { [weak self] in
        // do something
   }
  }
})

Modified code:

Task {
    let granted = await AVCaptureDevice.requestAccess(for: .video)
    if (granted) {
        Task { @MainActor in
            // do something
        }
    }
}

This code pops a permission dialog for using the camera, and as soon as the Allow button is clicked the app would crash.

Thank you Eskimo for the detail explanation, that helps a lot. And and @Sendable closure solution solved my issue.

And I want to mention something related. I'm using the async version before, just like the one you mention before:

Written by DTS Engineer in 806202022
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] Task { do { _ = try await UNUserNotificationCenter.current().requestAuthorization(options: authOptions) print("here") } catch { print("there") } }

But recently I detect a memory leak in the Instruments, that's why I need to find a way to go back to the completion callback version. Could you find out why the async version has that memory leak? BTW I'm using Xcode 16.1.0. And here is the screenshot in Instruments:

Your can easily reproduce it in Instruments with the code you provide.

Requesting speech recognition authorization is still a problem. The following code crashes right away when in Swift6 mode:

Task {
  SFSpeechRecognizer.requestAuthorization { status in
    switch status {
    case .authorized:
      Task { @MainActor in
        // do something
      }
      break
    case .denied, .restricted, .notDetermined:
      Task { @MainActor in
        // do something          }
      break
    @unknown default:
      Task { @MainActor in
        // do something
      }
    }
  }
}

The crashlog is very similar to what @Artecoop has posted.

@DTS Engineer : How can we fix that ? Is there any workaround ?

Written by chnbr in 822844022
How can we fix that ?

Have you tried generalising the techniques I outlined above to your specific case?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Request authorization for the notification center crash iOS app on Swift 6
 
 
Q