I'm experiencing the same issue too, it seemed to be introduced in one of the recent beta releases as I'm pretty sure I tested the same scenario when the first iOS 17/watchOS 10 Beta was released and it worked as expected.
My app has a companion watchOS app which requests location permission.
Replication Steps
Install iOS and companion watchOS apps.
After prompt, grant location permission on watchOS app (Location permissions work as expected at this point).
Reinstall iOS and companion watchOS apps.
Expected
The watchOS app requests location permission and the user is promoted to grant the permission.
Actual
The watchOS app requests location permission but the user is not prompted to grant the permission and therefore locations data cannot be retrieved.
Workaround
If you reset Location & Privacy settings the user is prompted for permission the next time the watchOS app requests location permission.
Go to Settings > General > Transfer or Reset iPhone, tap Reset, then tap Reset Location & Privacy.
Technical Notes
After reinstalling the apps and starting the watchOS app the CLLocationManagerDelegate doesn't receive the initial call to locationManagerDidChangeAuthorization(_ manager: CLLocationManager) with the current authorization status. In addition, getting authorizationStatus from the CLLocationManager instance returns .notDetermined and calling requestWhenInUseAuthorization() does not prompt the user for permission.
Post
Replies
Boosts
Views
Activity
This issue, as I was experiencing it (https://developer.apple.com/forums/thread/736574?answerId=763408022#763408022) has been resolved in the Beta releases of iOS 17.1 and watchOS 10.1.
I've tested the replication steps with my app and a sample app and confirmed that after reinstalling the companion watch app the location authorization was successfully requested and locations were returned.
Will confirm once the releases are public and close related feedback (FB13098566).
I'm seeing the same thing. CPU spike for about a minute when launching the app from Xcode to debug on iPhone and the app hangs on the launch screen for the duration.
Wasn't experiencing the issue with Xcode 15.2, installed Xcode 15.3, code unchanged and the issue started.
Edit: As suggested above, going to Edit Scheme > Run > Diagnostics and disabling Thread Performance Checker resolved the issue for me.
Thanks for the help.
A) Did you see and follow this warning:
"Always declare properties that have a fetch request wrapper as private. This lets the compiler help you avoid accidentally setting the property from the memberwise initializer of the enclosing view."
The documentation doesn't say this explicitly, but I think what they're warning about there is that it's posible to end up in a situation where the process of updating your interface based on a fetch request can end up accidentally modifying that data it's trying to display, which basically ends up rentering CoreData. I think this still trigger a crash in the same way calling "performBlockAndWait" inside a "performBlockAndWait" call would.
On A), this is actually something I did relatively recently but unfortunately the crash is still being reported in the current version with this change in place. It did change the call stack in the crash reports slightly but nothing which added any additional context to help diagnose the issue.
B) On the reproduction side, this is worth thinking about more:
"It also appears as if this happens on launch as the crash times and launch times are always very similar."
The work you're doing isn't what I'd associate with a "basic" app launch, so I suspect that this might be tied to some form of state restoration. Testing wise, I'd focus on putting your app into interesting/unusual state, not just "brute force" testing. Also, under "Settings.app-> Developer", there is a switch labeled "State Restoration Testing-> Fast App Termination" which could be very helpful here. Turning that on means that system will terminate your app whenever it suspends, forcing your app to restore state every time it comes to the foreground. That will let you test this code path while avoiding the disruption force quitting could cause.
For B), thanks for pointing me towards the 'Fast App Termination' setting, it's not something I was aware of and I've been using it today to try and trigger the crash. Unfortunately without success.
Looking further into the reports, it looks like although the majority of them occur on launch there are instances where it happens when the app has been suspended and opened again and even when the app is opened in the background (in response to a Watch Connectivity message). So it seems like it's something which isn't just limited to the app launching.
Unfortunately I'm still a bit stuck as I can't think of any other way to try and replicate the issue. At the moment the next thing I can think to try is to change @FetchRequest to use an NSFetchRequest and see if that shows anything different in future reports.
Are you sure this isn't about launching into the background? The log you sent showed WatchConnectivity activity, but it had also been running for a very short period of time AND the app was not in the foreground.
...
Is that true of all logs? If not, what's different about the "exceptions"? What about logs that don't show WatchConnectivity?
The logs seem to cover four scenarios, which are pretty much all the ways that the app supports opening.
I've attached sample crash logs for each scenario. The call stack of the crash is pretty much the same for all of them.
Foreground/Suspended
App is suspended and opened by the user. Launch time and crash time are different and other threads can show CoreData or WatchConnectivity usage as the app initialises both when it opens.
Foreground/Launch
App is launched by the user. Launch time and crash time are similar and other threads can show CoreData or WatchConnectivity usage as the app initialises both when it opens. Other threads almost always show CoreData usage from NSCloudKitMirroringDelegate _performSetupRequest.
Background/Suspended
App is suspended and opened in the background as a result of WatchConnectivity. Launch time and crash time are different and other threads only seem to show WatchConnectivity usage.
Background/Launch
App launched in the background as a result of WatchConnectivity. Launch time and crash time are similar and other threads only seem to show WatchConnectivity usage.
Background:Suspended.txt
Background:Launch.txt
Foreground:Launch.txt
Foreground:Suspended.txt
[quote='797720022, DTS Engineer, /thread/760343?answerId=797720022#797720022']
I would set a symbolic breakpoint on "FetchRequest.update", do some experimenting with your app to try and the overall "stack" you're seeing.
[/quote]
I've made some progress and think I've identified the crash.
I wasn't able to set a symbolic breakpoint on FetchRequest.update() (I tried a few variations but it never seemed to catch anything) but instead I set one on -[NSFetchedResultsController performFetch:] as that is just a little further down in the call stack.
The app has some custom Core Data migration functionality that enables adhoc data transformation before continuing with a lightweight migration. When the breakpoint was triggered I noticed that one of the other threads was calling the migration functionality so it got me to take a look, that's where I noticed the following line of code.
// Initalizing a coordinator with the same model more than once results in errors when fetching entities.
let persistentStoreCoordinator = migrationStep.destinationVersionIsCurrent ? appPersistentStoreCoordinator : NSPersistentStoreCoordinator(managedObjectModel: migrationStep.destinationModel)
This happens before triggering the migration and determines the coordinator used during the migration, with appPersistentStoreCoordinator passed in as an already created NSPersistentStoreCoordinator.
Originally it was creating a new NSPersistentStoreCoordinator each time but I changed it to the above, sometimes using the already created NSPersistentStoreCoordinator, as a result of the error described in the comment. I tested the code path where the new NSPersistentStoreCoordinator was created and the app crashed with the following errors.
executeFetchRequest:error: A fetch request must have an entity.
warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'Activity' so +entity is unable to disambiguate.
warning: 'Activity' (0x30252c370) from NSManagedObjectModel (0x303131900) claims 'Activity'.
error: +[Activity entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
CoreData: error: +[Activity entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'executeFetchRequest:error: A fetch request must have an entity.'
*** First throw call stack:
(0x1a0120f20 0x197fce018 0x1a821ad88 0x1a82c0b18 0x1a82110dc 0x1a82870ec 0x1a8286600 0x1a828620c 0x1a493b6e8 0x1a5663f08 0x1a5664368 0x1a40c3b70 0x1a40bf504 0x1a40bf320 0x1a40bf294 0x1a40bf224 0x19ea10068 0x1a4139688 0x1a41373bc 0x1a40e9b30 0x1c8d41010 0x1c8d40bfc 0x1c8d3acc0 0x1c8d3a854 0x1a40f8810 0x1a40f8568 0x1a40e9b30 0x1c8d41010 0x1c8d40bfc 0x1c8d407d8 0x1a41536f8 0x1a415288c 0x1a415164c 0x1a414fd7c 0x1a414fb0c 0x1a4064c6c 0x1a232ea4c 0x1a178d3b4 0x1a178cf38 0x1a17e80e0 0x1a175d028 0x1a24e3678 0x1a0102c9c 0x1a00f0dec 0x1a00f0498 0x1a00efcd8 0x1e4fa01a8 0x1a272890c 0x1a27dc9d0 0x1a42e0148 0x1a428c714 0x1a42984d0 0x100441530 0x1004415e0 0x1c37a1e4c)
libc++abi: terminating due to uncaught exception of type NSException
I'm not sure why I left in the code path to create a new NSPersistentStoreCoordinator but it meant that if a user was updating their app and there was more than one migration to apply, it would create a new NSPersistentStoreCoordinator and the app would crash. Changing this to always use the already created NSPersistentStoreCoordinator (appPersistentStoreCoordinator) resolves the issue.
I would have expected to see some reference to the migration functionality in one of the other threads in the crash log but perhaps it's because the migration was already complete and the crash occurred on the next fetch. Hopefully this fixes the crash I've been seeing in the crash reports.
Thanks for your help. I'm not sure I would have stumbled across the code causing the crash if it hadn't been for your suggestions.