Save yourselves from hours of debugging, because I've just wasted 2 weeks after bug hunting mysterious app crashes. It turns out, if you're adding a lot o (see answer for more details) notification requests to the UNUserNotificationCenter
, it will abruptly crash the Springboard. I haven't found a way around this yet, as the same code worked fine for iOS 9 and below. You can't seem to bulk-add notification requests like before either. Following is the crash I receive every single time (and so does hundreds of app users). Any idea what I could do instead of going back to using UILocalNotification
s?
Incident Identifier: 17BC9D5B-AF74-4592-8427-038375C27AE7
CrashReporter Key: a819553d1e72ee25a5ced9ddc79dbf00a7d3851f
Hardware Model: iPad5,3
Process: SpringBoard [2371]
Path: /System/Library/CoreServices/SpringBoard.app/SpringBoard
Identifier: com.apple.springboard
Version: 50 (1.0)
Code Type: ARM-64 (Native)
Role: Foreground
Parent Process: launchd [1]
Coalition: com.apple.springboard [71]
Date/Time: 2016-11-16 14:57:04.9159 +0400
Launch Time: 2016-11-16 14:49:20.9981 +0400
OS Version: iPhone OS 10.0 (14A5309d)
Report Version: 104
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 13
Filtered syslog:
None found
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0:
0 libsystem_kernel.dylib 0x0000000180624194 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x0000000180624004 mach_msg + 72
2 CoreFoundation 0x0000000180a61e8c __CFRunLoopServiceMachPort + 192
3 CoreFoundation 0x0000000180a5faa8 __CFRunLoopRun + 1132
4 CoreFoundation 0x000000018098f8d8 CFRunLoopRunSpecific + 444
5 GraphicsServices 0x0000000182396198 GSEventRunModal + 180
6 UIKit 0x00000001869327c8 -[UIApplication _run] + 664
7 UIKit 0x000000018692d534 UIApplicationMain + 208
8 libdyld.dylib 0x00000001805305b8 start + 4
Thread 1 name: com.apple.uikit.eventfetch-thread
Thread 1:
0 libsystem_kernel.dylib 0x0000000180624194 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x0000000180624004 mach_msg + 72
2 CoreFoundation 0x0000000180a61e8c __CFRunLoopServiceMachPort + 192
3 CoreFoundation 0x0000000180a5faa8 __CFRunLoopRun + 1132
4 CoreFoundation 0x000000018098f8d8 CFRunLoopRunSpecific + 444
5 Foundation 0x000000018142ce3c -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 304
6 Foundation 0x000000018144d92c -[NSRunLoop(NSRunLoop) runUntilDate:] + 96
7 UIKit 0x000000018727af2c -[UIEventFetcher threadMain] + 136
8 Foundation 0x00000001815293ac __NSThread__start__ + 1024
9 libsystem_pthread.dylib 0x00000001807079ec _pthread_body + 240
10 libsystem_pthread.dylib 0x00000001807078fc _pthread_body + 0
11 libsystem_pthread.dylib 0x0000000180704ef8 thread_start + 4
Thread 2:
0 libsystem_kernel.dylib 0x0000000180624194 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x0000000180624004 mach_msg + 72
2 CoreFoundation 0x0000000180a61e8c __CFRunLoopServiceMachPort + 192
3 CoreFoundation 0x0000000180a5faa8 __CFRunLoopRun + 1132
4 CoreFoundation 0x000000018098f8d8 CFRunLoopRunSpecific + 444
5 Foundation 0x000000018142ce3c -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 304
6 Foundation 0x0000000181481584 -[NSRunLoop(NSRunLoop) run] + 88
7 UIKit 0x0000000186f73298 -[UIStatusBarServerThread main] + 840
8 Foundation 0x00000001815293ac __NSThread__start__ + 1024
9 libsystem_pthread.dylib 0x00000001807079ec _pthread_body + 240
10 libsystem_pthread.dylib 0x00000001807078fc _pthread_body + 0
11 libsystem_pthread.dylib 0x0000000180704ef8 thread_start + 4
Thread 3:
0 libsystem_kernel.dylib 0x0000000180624194 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x0000000180624004 mach_msg + 72
2 CoreFoundation 0x0000000180a61e8c __CFRunLoopServiceMachPort + 192
3 CoreFoundation 0x0000000180a5faa8 __CFRunLoopRun + 1132
4 CoreFoundation 0x000000018098f8d8 CFRunLoopRunSpecific + 444
5 Foundation 0x000000018142ce3c -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 304
6 CoreBrightness 0x0000000190ec5d10 -[BrightnessSystemClientInternal main] + 1392
7 Foundation 0x00000001815293ac __NSThread__start__ + 1024
8 libsystem_pthread.dylib 0x00000001807079ec _pthread_body + 240
9 libsystem_pthread.dylib 0x00000001807078fc _pthread_body + 0
10 libsystem_pthread.dylib 0x0000000180704ef8 thread_start + 4
Thread 4:
0 libsystem_kernel.dylib 0x0000000180624194 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x0000000180624004 mach_msg + 72
2 CoreFoundation 0x0000000180a61e8c __CFRunLoopServiceMachPort + 192
3 CoreFoundation 0x0000000180a5faa8 __CFRunLoopRun + 1132
4 CoreFoundation 0x000000018098f8d8 CFRunLoopRunSpecific + 444
5 SpringBoard 0x00000001001a0b00 0x1000f0000 + 723712
6 libsystem_pthread.dylib 0x00000001807079ec _pthread_body + 240
7 libsystem_pthread.dylib 0x00000001807078fc _pthread_body + 0
8 libsystem_pthread.dylib 0x0000000180704ef8 thread_start + 4
Thread 5 name: com.apple.springboard.icongeneration
Thread 5:
0 libsystem_kernel.dylib 0x0000000180624194 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x0000000180624004 mach_msg + 72
2 CoreFoundation 0x0000000180a61e8c __CFRunLoopServiceMachPort + 192
3 CoreFoundation 0x0000000180a5faa8 __CFRunLoopRun + 1132
4 CoreFoundation 0x000000018098f8d8 CFRunLoopRunSpecific + 444
5 SpringBoard 0x00000001001a0c00 0x1000f0000 + 723968
6 libsystem_pthread.dylib 0x00000001807079ec _pthread_body + 240
7 libsystem_pthread.dylib 0x00000001807078fc _pthread_body + 0
8 libsystem_pthread.dylib 0x0000000180704ef8 thread_start + 4
Thread 6 name: com.apple.CoreMotion.MotionThread
Thread 6:
0 libsystem_kernel.dylib 0x0000000180624194 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x0000000180624004 mach_msg + 72
2 CoreFoundation 0x0000000180a61e8c __CFRunLoopServiceMachPort + 192
3 CoreFoundation 0x0000000180a5faa8 __CFRunLoopRun + 1132
4 CoreFoundation 0x000000018098f8d8 CFRunLoopRunSpecific + 444
5 CoreFoundation 0x00000001809dd094 CFRunLoopRun + 112
6 CoreMotion 0x0000000187762994 0x187702000 + 395668
7 libsystem_pthread.dylib 0x00000001807079ec _pthread_body + 240
8 libsystem_pthread.dylib 0x00000001807078fc _pthread_body + 0
9 libsystem_pthread.dylib 0x0000000180704ef8 thread_start + 4
Thread 7 name: SBWiFiManager callback thread
Thread 7:
0 libsystem_kernel.dylib 0x0000000180624194 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x0000000180624004 mach_msg + 72
2 CoreFoundation 0x0000000180a61e8c __CFRunLoopServiceMachPort + 192
3 CoreFoundation 0x0000000180a5faa8 __CFRunLoopRun + 1132
4 CoreFoundation 0x000000018098f8d8 CFRunLoopRunSpecific + 444
5 Foundation 0x000000018142ce3c -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 304
6 Foundation 0x0000000181481584 -[NSRunLoop(NSRunLoop) run] + 88
7 SpringBoard 0x0000000100215e44 0x1000f0000 + 1203780
8 Foundation 0x00000001815293ac __NSThread__start__ + 1024
9 libsystem_pthread.dylib 0x00000001807079ec _pthread_body + 240
10 libsystem_pthread.dylib 0x00000001807078fc _pthread_body + 0
11 libsystem_pthread.dylib 0x0000000180704ef8 thread_start + 4
Thread 8:
0 libsystem_kernel.dylib 0x0000000180624194 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x0000000180624004 mach_msg + 72
2 CoreFoundation 0x0000000180a61e8c __CFRunLoopServiceMachPort + 192
3 CoreFoundation 0x0000000180a5faa8 __CFRunLoopRun + 1132
4 CoreFoundation 0x000000018098f8d8 CFRunLoopRunSpecific + 444
5 Foundation 0x000000018142ce3c -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 304
6 HomeKit 0x00000001913e8974 -[_HMLocationHandler createLocationManager] + 508
7 Foundation 0x00000001815293ac __NSThread__start__ + 1024
8 libsystem_pthread.dylib 0x00000001807079ec _pthread_body + 240
9 libsystem_pthread.dylib 0x00000001807078fc _pthread_body + 0
10 libsystem_pthread.dylib 0x0000000180704ef8 thread_start + 4
Thread 9:
0 libsystem_kernel.dylib 0x0000000180624194 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x0000000180624004 mach_msg + 72
2 CoreFoundation 0x0000000180a61e8c __CFRunLoopServiceMachPort + 192
3 CoreFoundation 0x0000000180a5faa8 __CFRunLoopRun + 1132
4 CoreFoundation 0x000000018098f8d8 CFRunLoopRunSpecific + 444
5 Foundation 0x000000018142ce3c -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 304
6 CoreBrightness 0x0000000190ec5d10 -[BrightnessSystemClientInternal main] + 1392
7 Foundation 0x00000001815293ac __NSThread__start__ + 1024
8 libsystem_pthread.dylib 0x00000001807079ec _pthread_body + 240
9 libsystem_pthread.dylib 0x00000001807078fc _pthread_body + 0
10 libsystem_pthread.dylib 0x0000000180704ef8 thread_start + 4
Thread 10 name: CommonUtilities-WiFi-Thread
Thread 10:
0 libsystem_kernel.dylib 0x0000000180624194 mach_msg_trap + 8
1 libsystem_kernel.dylib 0x0000000180624004 mach_msg + 72
2 CoreFoundation 0x0000000180a61e8c __CFRunLoopServiceMachPort + 192
3 CoreFoundation 0x0000000180a5faa8 __CFRunLoopRun + 1132
4 CoreFoundation 0x000000018098f8d8 CFRunLoopRunSpecific + 444
5 CoreFoundation 0x00000001809dd094 CFRunLoopRun + 112
6 CommonUtilities 0x0000000182d10c20 0x182d0a000 + 27680
7 Foundation 0x00000001815293ac __NSThread__start__ + 1024
8 libsystem_pthread.dylib 0x00000001807079ec _pthread_body + 240
9 libsystem_pthread.dylib 0x00000001807078fc _pthread_body + 0
10 libsystem_pthread.dylib 0x0000000180704ef8 thread_start + 4
Thread 11:
0 libsystem_kernel.dylib 0x0000000180642a88 __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x000000018070549c _pthread_wqthread + 1440
2 libsystem_pthread.dylib 0x0000000180704ef0 start_wqthread + 4
Thread 12:
0 libsystem_kernel.dylib 0x0000000180642a88 __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x000000018070549c _pthread_wqthread + 1440
2 libsystem_pthread.dylib 0x0000000180704ef0 start_wqthread + 4
Thread 13 name: Dispatch queue: com.apple.frontboard.sqlite.database
Thread 13 Crashed:
0 libsystem_kernel.dylib 0x0000000180642014 __pthread_kill + 8
1 libsystem_pthread.dylib 0x00000001807094f0 pthread_kill + 112
2 libsystem_c.dylib 0x00000001805b64b8 abort + 140
3 libsystem_malloc.dylib 0x0000000180686a38 _nano_vet_and_size_of_live + 0
4 libsystem_malloc.dylib 0x0000000180687db8 nano_free + 220
5 libsqlite3.dylib 0x000000018103a5f8 0x180f95000 + 677368
6 libsqlite3.dylib 0x0000000180fbac9c 0x180f95000 + 154780
7 libsqlite3.dylib 0x0000000180fe6074 0x180f95000 + 331892
8 libsqlite3.dylib 0x0000000180fd70b0 sqlite3_step + 588
9 FrontBoard 0x0000000190312ee4 __79-[_FBSqlitePreparedSimpleStatement executeWithBindings:resultRowHandler:error:]_block_invoke + 424
10 libdispatch.dylib 0x00000001804fd784 _dispatch_client_callout + 16
11 libdispatch.dylib 0x000000018050aca4 _dispatch_barrier_sync_f_invoke + 84
12 FrontBoard 0x000000019031e0d0 -[FBSqliteDatabaseConnection performSyncWithDatabase:] + 80
13 FrontBoard 0x0000000190312cbc -[_FBSqlitePreparedSimpleStatement executeWithBindings:resultRowHandler:error:] + 148
14 FrontBoard 0x000000019035a4d8 -[FBSqliteApplicationDataStoreRepository _dbQueue_executeStatement:bindings:resultRowHandler:error:] + 80
15 FrontBoard 0x000000019035a538 -[FBSqliteApplicationDataStoreRepository _dbQueue_executeStatement:bindings:resultRowHandler:] + 72
16 FrontBoard 0x0000000190359374 -[FBSqliteApplicationDataStoreRepository _dbQueue_objectForKey:forApplication:] + 504
17 FrontBoard 0x0000000190357a34 __81-[FBSqliteApplicationDataStoreRepository objectForKey:forApplication:withResult:]_block_invoke.44 + 40
18 libdispatch.dylib 0x00000001804fd784 _dispatch_client_callout + 16
19 libdispatch.dylib 0x000000018050aca4 _dispatch_barrier_sync_f_invoke + 84
20 FrontBoard 0x0000000190357990 -[FBSqliteApplicationDataStoreRepository objectForKey:forApplication:withResult:] + 92
21 FrontBoard 0x000000019038a5cc -[FBApplicationDataStoreInProcessRepositoryClient objectForKey:forApplication:withResult:checkPrefetch:] + 528
22 FrontBoardServices 0x00000001825c3e3c __40-[FBSApplicationDataStore objectForKey:]_block_invoke + 112
23 libdispatch.dylib 0x00000001804fd784 _dispatch_client_callout + 16
24 libdispatch.dylib 0x0000000180508f80 _dispatch_block_invoke_direct + 376
25 BaseBoard 0x00000001825415a8 -[NSObject(BaseBoard) bs_performSynchronously:timeout:] + 144
26 FrontBoardServices 0x00000001825c3d7c -[FBSApplicationDataStore objectForKey:] + 224
27 FrontBoardServices 0x00000001825c4044 -[FBSApplicationDataStore safeObjectForKey:ofType:] + 32
28 FrontBoardServices 0x00000001825c41d4 -[FBSApplicationDataStore archivedObjectForKey:] + 64
29 FrontBoardServices 0x00000001825c4314 -[FBSApplicationDataStore safeArchivedObjectForKey:ofType:] + 32
30 UserNotificationsServer 0x000000019c52169c -[UNSPendingNotificationRepository _pendingNotificationDictionariesForBundleIdentifier:] + 140
31 UserNotificationsServer 0x000000019c5219d0 -[UNSPendingNotificationRepository setPendingNotificationRecords:forBundleIdentifier:] + 72
32 UserNotificationsServer 0x000000019c5249b4 -[UNSLocalNotificationClient _setPendingNotificationRecords:] + 500
33 UserNotificationsServer 0x000000019c5235c4 -[UNSLocalNotificationClient addPendingNotificationRecords:] + 1124
34 UserNotificationsServer 0x000000019c51d648 -[UNSNotificationSchedulingService _queue_addPendingNotificationRecords:forBundleIdentifier:] + 84
35 UserNotificationsServer 0x000000019c51c6b0 __108-[UNSNotificationSchedulingService addPendingNotificationRecords:forBundleIdentifier:withCompletionHandler:]_block_invoke + 36
36 libdispatch.dylib 0x00000001804fd7c4 _dispatch_call_block_and_release + 24
37 libdispatch.dylib 0x00000001804fd784 _dispatch_client_callout + 16
38 libdispatch.dylib 0x000000018050b880 _dispatch_queue_serial_drain + 928
39 libdispatch.dylib 0x0000000180500f6c _dispatch_queue_invoke + 652
40 libdispatch.dylib 0x000000018050bd7c _dispatch_queue_override_invoke + 360
41 libdispatch.dylib 0x000000018050d718 _dispatch_root_queue_drain + 572
42 libdispatch.dylib 0x000000018050d478 _dispatch_worker_thread3 + 124
43 libsystem_pthread.dylib 0x00000001807053f8 _pthread_wqthread + 1276
44 libsystem_pthread.dylib 0x0000000180704ef0 start_wqthread + 4
UPDATE: It doesn't seem to be based on a specific number of notifications. I just happened to have it trigger frequently given I had around 30 to 40 notifications registered while the app was in background (push notification, app refresh, app going to background etc) - since it was taking longer than usual to asynchronously add these alerts, the app would in the meanwhile let go of the background task identifier it had held. I've explained this in detail below, along with a workaround.
This bug has been acknowledged by Apple and marked as duplicate of a previously reported bug. I hope this gets fixed as it continues to cause problems in certain edge cases where the app launches in the background and times out soon after (during background content refreshes).
I've found a workaround (bug already logged with Apple bug ID 29286162)
Essentially, it seems the SpringBoard crashes if the UNUserNotificationCenter
is busy adding notifications and it hasn't finished doing so, while the user presses the home button to return to the SpringBoard. Clearly, somehow the thread is dying (well, possibly since I've got to let go of the background task identifier, hoping the UNUserNotificationCenter
will happily consume the passed requests in its own system provided background thread), leaving the on-going asynchronous operation in limbo, causing Springboard to eventually crash. I now simply spawn a thread in a background task (UIBackgroundTaskIdentifier
) and hold on to it till it's finished adding all the notifications. This results in zero crashes - confirmed also by all the users previously complaining the same.
// arrTasksToSchedule -> holds UNNotificationRequests to add
__block NSInteger volatile processedAlerts = 0;
NSInteger totalToProcess = [arrTasksToSchedule count];
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
for (UNNotificationRequest* notifRequest in arrTasksToSchedule) {
[center addNotificationRequest:notifRequest withCompletionHandler:^(NSError * _Nullable error) {
processedAlerts++;
}];
}
// Let the runloop carry on processing events till we're done
while (processedAlerts != totalToProcess) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
// Okay we're done, and can now let go of our held UIBackgroundTaskIdentifier
The documentation says nothing about background tasks, perils of using UNUserNotificationCenter
in a background task or anything to do with multiple threads etc. I can only assume they didn't realize most apps do their notification registrations when their apps are sent to the background (or during a background content-refresh push notification).
Since the Springboard was crashing - crash reports were not being generated for the app itself. Users kept complaining and this was one of those terribly difficult situations where you've got no clue. I hope this saves someone a lot of headache.
UPDATE: Although the code above works just fine now, I've made a slightly modification as the while loop's condition may NOT be met in case the user closes the app and presses the power button to switch the screen off. In this case, the runloop obviously has nothing to process and will block. Instead, the following does the trick:
// Wait in a run loop
while (processedAlerts != totalToProcess) {
[NSThread sleepForTimeInterval:0.15];
// Don't use the following, as it will stop firing in case
// the runloop has no events (such as touch events) firing
// [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}