2

I just upgraded my whole iOS push notifications registering for iOS 10, with this code:

-(void)registerForNotifications{
if(SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(@"10.0")){
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
        dispatch_async(dispatch_get_main_queue(), ^(void){
            if(!error){
                [[UIApplication sharedApplication] registerForRemoteNotifications];
            }
        });
    }];
}
else {
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)])
    {
        UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound);
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
}

}

All my delegates are set in my AppDelegate.

EDIT: I have now been able to further identify the issue. When the app comes back in foreground after notification push, the delegate:

- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.

}

is only called after about 10-15 seconds, while normally it is obviously called immediately. How is this possible?

I'm now testing push notifications with Localytics and I implement:

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {

in my AppDelegate for deep linking purposes. When I add breakpoints, I see that this happens: I receive the push notification correctly, I tap on it, and the app UI freezes for about 10 seconds. Then, finally, didReceiveNotificationResponse is called and the deep linking works.

How can I avoid this huge delay which freeezes the app?

EDIT: it's even worse than I though. When I connect my iPhone to xCode and run a build on my phone, it freezes for ten seconds before working. Then, if I just run the exact same build without running it on xCode (so without breakpoints), the app freezes for 10 seconds and then crashes.

EDIT: here is a screenshot of my main thread when I pause on xCode while it freezes: enter image description here

Cœur
  • 37,241
  • 25
  • 195
  • 267
el-flor
  • 1,466
  • 3
  • 18
  • 39
  • With out deep linking check it once, delay is there or not? – karthikeyan Mar 22 '17 at 12:12
  • Yes, even without deep linking I still have the delay. didReceiveNotificationResponse is called whether there is a deep-link or not, so the issue happens before hand. – el-flor Mar 22 '17 at 12:16
  • @bloemy : The code inside `- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler` takes 10 sec to execute or it the time to reach this method? Why don't you add a breakpoint on the first line of this method and checks if it takes 10 sec to reach there or not. – Poles Mar 22 '17 at 12:28
  • It's the time to reach the method. My first breakpoint is on the method name itself. The code inside the method is executed immediately because I call the main thread. It does seem like a threading issue... – el-flor Mar 22 '17 at 12:29
  • You mentioned a crash, can you add more details on it? – pckill Mar 22 '17 at 14:49
  • Basically on my production app, I receive the push notification in background, click on it, it opens the app. Then the UI freezes for about 10-15 seconds, I can't do anything, and then the app crashes. Nothing more... – el-flor Mar 22 '17 at 15:47
  • just checking: You're simulator is not on [slow animations](http://stackoverflow.com/questions/8624519/simulator-slow-motion-animations-are-now-on) right? – mfaani Mar 22 '17 at 19:22
  • No -- it happens on my phone too.... – el-flor Mar 23 '17 at 06:20
  • `LLPushManager requestPushTest` looks suspicious. – A-Live Nov 28 '17 at 16:58

1 Answers1

0

There's something weird in your stacktrace. semaphore_wait_trap, semaphore_wait_slow. Try seeing here and here and here. That being said my guess is that you're calling your (void)registerForNotifications from a wrong thread and it's causing this issue.

Additionally I don't understand why you have a dispatch_async(dispatch_get_main_queue in your implementation. It seems unnecessary. Try seeing answers from here

Community
  • 1
  • 1
mfaani
  • 33,269
  • 19
  • 164
  • 293
  • Hi, there is definitely something weird. I've seen all those threads but haven't been able to find the issue... And the weird part is that I only call regsiterForNotifications on a second app launch, not on first launch. The dispatch_asynch was exactly there to see if the issue was about the main thread, but it didn't help. – el-flor Mar 23 '17 at 17:22
  • @bloemy "I only call regsiterForNotifications on a second app launch" <-- then you're doing something very wrong. Are you calling `registerForNotifications` in `DidFinishLaunchingWithOptions`? If not then from where are you calling it, you should able to follow stackTrace and figure out where/when its being called from – mfaani Mar 23 '17 at 17:31
  • No sorry, what I mean is: I don't call registerForNotifications from the AppDelegate on first launch because I want to customize my registering message to the user. But the flow works: it actually works with other frameworks than Localytics, which is really weird. – el-flor Mar 23 '17 at 17:37
  • @bloemy forget localytics, just edit your question and show all the **related** code. Show how it begins, how it finishes – mfaani Mar 23 '17 at 17:52