UNUserNotificationCenter causing SpringBoard to crash

)I've got hundreds of users complaining about device crashes and I couldn't figure it out. Turns out, it's UNUserNotificationCenter. Crashes on all current flavors and versions of iOS 10 if you are bulk adding a lot of notification requests, especially if the app just went into the background. I can reproduce it all the time. Following is the crash report I get. Should I move back to UILocalNotifications instead or are they using the same new underlying code? I've logged a bug: 29286162



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

Replies

It seems like you found your own workaround for this.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I think the problem is even worse than previously thought. I am able to trigger a springboard crash while my app is in the foreground. I am (currently!) configuring 64 notifications out into the future for a Pomodoro timer each time the user starts the timer or skips to advance to the next period. It takes about 6 seconds for all the async callbacks to complete!


Each time I skip the timer forewards my app calls removeAllDeliveredNotifications and removeAllPendingNotificationRequests on the UNUserNotificationCenter. It then calculates when the next 64 notifications need to occur and schedules them all, one-by-one, with addNotificationRequest:withCompletionHander: Debug logs (on an iPhone 6s) shows me that it takes about 6 seconds for all 64 completion handler invocations.


By repeatedly tapping to skip forwards I am backing up more and more work for the UNUserNotificationCenter and after about 2 minutes I get a Springboard crash. My app is in the foreground the entire time.


Obviously I will need to be smarter in the way I handle this situation by maybe using a serial queue to allow me to cancel not-yet-started iterations of the remove/reschedule group of work. That way I should only have at most one work package in progress with one pending.


I might also need to use the background task workaround that is posted on Stack Overflow, but that's not going to be possible in my Today Widget which doesn't have access to UIApplication.


6 seconds to schedule 64 notifications? Seriously guys!?!?

Some more information on my testing. I've created an NSOperationQueue with maxConcurrentOperationCount = 1 to serially process all the work I want to send to UNUserNotificationCenter. When I need to re-schedule my notifications because the user skipped forward in the timer, I cancel any existing operations on the queue then schedule my new work. This prevents the backlog growing indefinitely in worst-case scenarios where I'm repeatedly causing the notifications to be rescheduled faster than iOS is able to call all the completion handlers. My worst case is now around 12 seconds (two blocks of work) no matter how often I reschedule. That's still terrible, but does seem to prevent the crash.


I also added a dummy 20 second background task in `applicationDidEnterBackground` to ensure that the notifications are processed when my app goes to the background:


    UIBackgroundTaskIdentifier identifer = [application beginBackgroundTaskWithExpirationHandler:^{
        /
    }];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 20.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        HNCLog1(@"ending backgroung task");
        [application endBackgroundTask:identifer];
    });


That won't help my Today Widget, so I could still have problems when advancing my timer and re-scheduling notifications from the widget.


To try and improve this, I decided to split my operation that adds 64 notifications into four operations of 16 each. This makes the work more fine-grained so I can cancel more of it in my worst case testing. That did seem to work, but I also discovered the very surprising result that each block of work took progressively longer to execute. I.e. the time it takes to add a new notification seems to grow with the number of notifications that are already scheduled.


It's been a long time since I did my computer science degree, but isn't that (at least) O(n^2) behaviour?

That won't help my Today Widget, so I could still have problems when advancing my timer and re-scheduling notifications from the widget.

Just FYI, your widget should be able to use NSProcess info (specifically

-performExpiringActivityWithReason:usingBlock:
) to get some background time for this.

Regarding the overall performance of scheduling notifications, clearly this should be better. It would be helpful if you could file a bug report about this, describing how these notifications fit into the overall design of your app. Make sure you including a sysdiagnose log taken while you’re waiting for the scheduling to complete; for instructions on that, see the Bug Reporting > Profiles and Logs page.

Also, if you could include a small test project that demonstrates the issue, that’d be fab.

Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I'm still working on a test project and bug report, but I think I've found the important factor: using UNTimeIntervalNotificationTrigger is relatively fast (it still slows down with each notification), but using UNCalendarNotificationTrigger is *really* slow.


Time Interval:


2016-12-06 11:13:32.583932 NotificationsTest[3631:1983664] notification #0 took 0.03s to schedule (0.03s from start)

2016-12-06 11:13:32.623661 NotificationsTest[3631:1983664] notification #1 took 0.06s to schedule (0.07s from start)

2016-12-06 11:13:32.637687 NotificationsTest[3631:1983664] notification #2 took 0.07s to schedule (0.08s from start)

2016-12-06 11:13:32.637932 NotificationsTest[3631:1983664] notification #3 took 0.07s to schedule (0.08s from start)

...

2016-12-06 11:13:33.321781 NotificationsTest[3631:1983664] notification #60 took 0.65s to schedule (0.76s from start)

2016-12-06 11:13:33.338376 NotificationsTest[3631:1983664] notification #61 took 0.67s to schedule (0.78s from start)

2016-12-06 11:13:33.356936 NotificationsTest[3631:1983665] notification #62 took 0.68s to schedule (0.80s from start)

2016-12-06 11:13:33.374162 NotificationsTest[3631:1983664] notification #63 took 0.70s to schedule (0.82s from start)



Calendar:


2016-12-06 11:14:42.659609 NotificationsTest[3633:1984141] notification #0 took 0.03s to schedule (0.03s from start)

2016-12-06 11:14:42.688082 NotificationsTest[3633:1984143] notification #1 took 0.06s to schedule (0.06s from start)

2016-12-06 11:14:42.708078 NotificationsTest[3633:1984143] notification #2 took 0.08s to schedule (0.08s from start)

2016-12-06 11:14:42.730894 NotificationsTest[3633:1984143] notification #3 took 0.10s to schedule (0.10s from start)

...

2016-12-06 11:14:47.449785 NotificationsTest[3633:1984141] notification #60 took 4.73s to schedule (4.82s from start)

2016-12-06 11:14:47.605846 NotificationsTest[3633:1984143] notification #61 took 4.89s to schedule (4.98s from start)

2016-12-06 11:14:47.765557 NotificationsTest[3633:1984143] notification #62 took 5.05s to schedule (5.14s from start)

2016-12-06 11:14:47.927163 NotificationsTest[3633:1984143] notification #63 took 5.21s to schedule (5.30s from start)




My app (******) is a Pomodoro timer. The user works for 25 mins, takes a 5 minute break, works 25, break 25. That repeats 4 times when the last break is 15 mins. I have a notification that fires at the start of each period (25 mins, 30 mins, 55 mins etc. from the start).


It's not possible to schedule a notification to start in time X with a repeat interval that isn't X so this pattern, while very regular, can't be achieved without a separate notification for each event.


When moving to UNUserNotificationCenter during the iOS 10 betas and 10.0 release I found that UNTimeIntervalNotificationTrigger was not accurate. I'd ask for a notification in 25 minutes and it would be delivered several seconds later than expected, which looked awful when the user is using the app and seeing the countdown timer reach 0:00, start counting down the next period for several seconds and then get the notification. Maybe that's been fixed in a later version of IOS. I moved to UNCalendarNotificationTrigger to work around that issue and tried not to worry about the obvious problems that will occur on daylight savings changes!


I'll add a radar number when I've got my sample project to a decent state.

But report 29551302 submitted ("Scheduling notifications with UNCalendarNotificationTrigger is very slow"). I included my sample project, sysdiagnose log and a capture of the NSLogs when running the sample with UNCalendarNotificationTrigger and UNTimeIntervalNotificationTrigger.

But report 29551302 submitted

Thanks.

using

UNTimeIntervalNotificationTrigger
is relatively fast (it still slows down with each notification), but using
UNCalendarNotificationTrigger
is really slow.

That’s a great tidbit. Thanks for sharing.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hello sorry to bother everyone but I am seeing a very similar "crash" right now. It's not a normal crash which goes back to home screen, it seems like springboard crashes too and "iOS restarts", with the spinning thing and back to lock screen after a few seconds. It happens EVERYTIME using an iPhone SE iOS 10.1.1. It's working well on all other devices we tested, including an iPhone 5s at iOS 10.1.1. The one line that we have tracked it down to is this:


UNUserNotificationCenter.current().getPendingNotificationRequests



Yes, before even scheduling any notification at all, just trying to get current ones, it crashes very hard like described above. It is possible that this is fixed on iOS 10.2 and above, but we will likely have to fix the issue somehow because we can assume many users use iOS 10.0 ~ 10.1 still. What could be a good workaround?

So it seems there is a bug concering iOS 10 flavor notifications until 10.2 where people say it has been fixed. So I tried calling UIApplication.shared.scheduledLocalNotifications instead on my iPhone SE device - that crashes as well. DOOH. Is UIApplication.shared.scheduledLocalNotifications just a wrapper for UNUserNotificationCenter.current().getPendingNotificationRequests on iOS 10 devices?

I get crashes with a iPhone 5s, iOS 10.1.1 as well. Same story.

Also UNUserNotificationCenter.current().add() crashes.


I'll stress that the app itself does not crash, iOS (springboard?) does. I don't have access to many iOS 10.0-10.1 devices to test this with. Actually no other so far... I'll need to test if this is really fixed with iOS 10.2 also.


Did I mention I need to support iOS 9? To me, just supporting latest iOS like 10.3 would be a sane decision at this point, but unfortunately this time I cannot decide. I'm thinking that maybe I will refuse any notification relying features for users running iOS >=10.0 and < 10.2 ... It is possible however that like iPhone 6/7 does not have the problem even at iOS 10.0/10.1, but I just don't have enough devices to make sure.

Update: I seem to have found something that fixes it all. Well, it will need more testing but I seem to have found a magic fix:


Call center.removeAllPendingNotificationRequests() on first launch of app... that's it. Weird... maybe the bug comes back later.