CoreData CloudKit sync resulting in main thread initialisation issue

I'm using Xcode 14 beta 4, on macOS Monterey 12.5, developing a Mac app that's using CoreData CloudKit sync — with my context being configured with two configurations (one for a local cache and one data synced via CloudKit).

An issue recently appeared where the app crashes soon after start-up with this message:

[threadmgrsupport] _TSGetMainThread_block_invoke:Main thread potentially initialized incorrectly, cf <rdar://problem/67741850>

And this stack trace:

Thread 1 Queue : com.apple.main-thread (serial)
#0	0x000000018b86b5e8 in ___NSAssertMainEventQueueIsCurrentEventQueue_block_invoke ()
#1	0x0000000105b563a8 in _dispatch_client_callout ()
#2	0x0000000105b58300 in _dispatch_once_callout ()
#3	0x000000018b86a2dc in _DPSNextEvent ()
#4	0x000000018b868e14 in -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] ()
#5	0x000000018b85afe0 in -[NSApplication run] ()
#6	0x000000018b82c6fc in NSApplicationMain ()
#7	0x00000001ae281e98 in specialized runApp(_:) ()
#8	0x00000001aee10588 in runApp<τ_0_0>(_:) ()
#9	0x00000001ae88626c in static App.main() ()

Things work again, if I disable the CloudKit sync by not setting cloudKitContainerOptions on my "Cloud" configuration. Similarly, it works on first install, but reappears on subsequent runs. The code is in a package that's shared with an iOS version of the app, which has no such issues.

I also tried going back to previous commits that worked before, and it works again until at some point it stops working again for the same commits. So it doesn't seem to be caused directly by my code, but rather by something that the CloudKit sync is doing.

Any help would be much appreciated.

Accepted Reply

It appears that the reason is that I'm using the SwiftUI App model for my Mac app, and the init() method of my App subclass is not running via NSApplicationMain. So if other code, such as CloudKit then runs it'll assign the main thread to the wrong queue or thread. I can fix this manually by calling let _ = NSApplication.shared manually in my init() method or by deferring my access to CloudKit / CoreData using DispatchQueue.main.async { ... } calls.

Submitted as FB10902789, as a SwiftUI bug.

  • If you want it to run on the main thread, why don't you mark it as @MainActor (Swift Concurrency)?

  • @newwbee, I can't do that, as none of my code is causing this. It's the framework causing the problem and making a call in the background.

    I can work around this by manually injecting a call to let _ = NSApplication.shared.

  • let _ = NSApplication.shared solved it for me! God this made my brain hurt... Thank you.

Replies

It appears that the reason is that I'm using the SwiftUI App model for my Mac app, and the init() method of my App subclass is not running via NSApplicationMain. So if other code, such as CloudKit then runs it'll assign the main thread to the wrong queue or thread. I can fix this manually by calling let _ = NSApplication.shared manually in my init() method or by deferring my access to CloudKit / CoreData using DispatchQueue.main.async { ... } calls.

Submitted as FB10902789, as a SwiftUI bug.

  • If you want it to run on the main thread, why don't you mark it as @MainActor (Swift Concurrency)?

  • @newwbee, I can't do that, as none of my code is causing this. It's the framework causing the problem and making a call in the background.

    I can work around this by manually injecting a call to let _ = NSApplication.shared.

  • let _ = NSApplication.shared solved it for me! God this made my brain hurt... Thank you.

I'm getting the same thing, except I'm using Catalyst. Which doesn't enable me to use NSApplication. I have no idea how to fix this

  • were you able to resolve this eventually?

  • Did you find a solution?

Add a Comment

I'm having exactly the same issue, except that my Mac app has a traditional app delegate. Does anyone have any insights for how to resolve for this scenario?