iOS10 — userNotificationCenter didReceiveNotificationResponse вызывается с задержкой в ​​10 секунд

Я только что обновил все свои push-уведомления iOS, регистрируемые для iOS 10, с помощью этого кода:

-(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];
    }
}

}

Все мои делегаты установлены в моем AppDelegate.

EDIT: теперь я смог определить проблему. Когда приложение возвращается на передний план после отправки уведомления, делегат:

- (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.

}

вызывается только через 10-15 секунд, в то время как обычно он вызывается немедленно. Как это возможно?

Сейчас я тестирую push-уведомления с помощью Localytics и реализую:

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

в моем AppDelegate для глубинных ссылок. Когда я добавляю точки останова, я вижу, что это происходит: я правильно получаю push-уведомление, я нажимаю на него, и пользовательский интерфейс приложения зависает примерно на 10 секунд. Затем, наконец, вызывается didReceiveNotificationResponse, и диплинкинг работает.

Как я могу избежать этой огромной задержки, которая зависает в приложении?

РЕДАКТИРОВАТЬ: это даже хуже, чем я. Когда я подключаю свой iPhone к xCode и запускаю сборку на своем телефоне, он зависает на десять секунд, прежде чем начать работу. Затем, если я просто запущу точно такую ​​же сборку, не запуская ее на xCode (то есть без точек останова), приложение зависнет на 10 секунд, а затем вылетит.

EDIT: вот скриншот моего основного потока, когда я приостанавливаю работу с xCode, пока он зависает: введите здесь описание изображения


person el-flor    schedule 22.03.2017    source источник
comment
Без диплинков проверь один раз, есть задержка или нет?   -  person karthikeyan    schedule 22.03.2017
comment
Да, даже без диплинкинга у меня все равно есть задержка. didReceiveNotificationResponse вызывается независимо от того, есть ли глубокая ссылка или нет, поэтому проблема возникает заранее.   -  person el-flor    schedule 22.03.2017
comment
@bloemy: код внутри - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler выполняется 10 секунд или это время для достижения этого метода? Почему бы вам не добавить точку останова в первую строку этого метода и проверить, требуется ли 10 секунд, чтобы достичь ее или нет.   -  person Poles    schedule 22.03.2017
comment
Пришло время добраться до метода. Моя первая точка останова находится на самом имени метода. Код внутри метода выполняется немедленно, потому что я вызываю основной поток. Это похоже на проблему с потоками...   -  person el-flor    schedule 22.03.2017
comment
Вы упомянули об аварии, можете ли вы добавить о ней больше подробностей?   -  person pckill    schedule 22.03.2017
comment
В основном в моем производственном приложении я получаю push-уведомление в фоновом режиме, нажимаю на него, оно открывает приложение. Затем пользовательский интерфейс зависает примерно на 10-15 секунд, я ничего не могу сделать, а затем приложение вылетает. Больше ничего...   -  person el-flor    schedule 22.03.2017
comment
просто проверяю: ваш симулятор не использует медленную анимацию, верно?   -  person Honey    schedule 22.03.2017
comment
Нет -- это происходит и на моем телефоне....   -  person el-flor    schedule 23.03.2017
comment
LLPushManager requestPushTest выглядит подозрительно.   -  person A-Live    schedule 28.11.2017


Ответы (1)


В вашей трассировке стека что-то странное. semaphore_wait_trap, semaphore_wait_slow. Попробуйте посмотреть здесь и здесь и здесь. При этом я предполагаю, что вы вызываете свой (void)registerForNotifications из неправильного потока, и это вызывает эту проблему.

Кроме того, я не понимаю, почему в вашей реализации есть dispatch_async(dispatch_get_main_queue. Это кажется ненужным. Попробуйте просмотреть ответы из здесь

person Honey    schedule 23.03.2017
comment
Привет, определенно есть что-то странное. Я видел все эти темы, но не смог найти проблему... И самое странное, что я вызываю regsiterForNotifications только при втором запуске приложения, а не при первом запуске. Отправка asynch была именно там, чтобы увидеть, не связана ли проблема с основным потоком, но это не помогло. - person el-flor; 23.03.2017
comment
@bloemy Я вызываю regsiterForNotifications только при втором запуске приложения ‹-- тогда вы делаете что-то очень неправильно. Вы звоните registerForNotifications в DidFinishLaunchingWithOptions? Если нет, то откуда вы его вызываете, вы должны следить за stackTrace и выяснять, откуда/когда он вызывается. - person Honey; 23.03.2017
comment
Нет, извините, я имею в виду следующее: я не вызываю registerForNotifications из AppDelegate при первом запуске, потому что хочу настроить сообщение о регистрации для пользователя. Но схема работает: на самом деле она работает с другими фреймворками, кроме Localytics, что действительно странно. - person el-flor; 23.03.2017
comment
@bloemy забудьте о локализации, просто отредактируйте свой вопрос и покажите весь связанный код. Покажите, как это начинается, как это заканчивается - person Honey; 23.03.2017