Подтвердить что ты не робот

Почему didReceiveRemoteNotification не вызывается, но didReceiveRemoteNotification: fetchCompletionHandler вызывается, когда мое приложение находится на переднем плане?

Если я переопределяю

override func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    println("hey)
}

Я успешно получил метод, вызванный с приложением на переднем плане, когда я отправляю push-уведомление.

Если я переопределяю

override func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
    println("hey")
}

Я не получаю никакого вызова метода при отправке уведомления с приложением на переднем плане. Почему первый работает, а второй - когда приложение находится на переднем плане?

Обратите внимание, что я выполняю только одно из них за раз. Не в то же время.

4b9b3361

Ответ 1

Вы должны использовать версию обратного вызова, если вам не нужна поддержка ios < 7 (когда она была введена). Поскольку вы используете Swift, я ожидаю, что это не так.

Более старый метод возвращается к ios3 и устарел для всех, кроме имени:

Внедрите метод application:didReceiveRemoteNotification:fetchCompletionHandler: вместо этого, когда это возможно. Если ваш делегат реализует оба метода, объект приложения вызывает метод application:didReceiveRemoteNotification:fetchCompletionHandler:.

Более старая версия также даст разные результаты в зависимости от того, является ли приложение живым (передний план или фон) или запускается с холодного запуска. В последнем случае он не будет вызван, и вам нужно будет перехватить launchOptions dict на didFinishLaunchingWithOptions, чтобы попасть в infoDict:

Если приложение не запускается при поступлении удаленного уведомления, метод запускает приложение и предоставляет соответствующую информацию в словаре параметров запуска. Приложение не вызывает этот метод для обработки этого удаленного уведомления.

Используйте обратную версию. Он работает для всех случаев. Вам не нужно использовать обработчик завершения/блок, и в этом случае эффект будет таким же (ну, в большей степени совместимым с более новым методом).

обновление

Извините, Apple заявляет, что вам нужно позвонить в блок завершения "как можно скорее" - у вас есть 30 секунд, чтобы сделать это, прежде чем ОС откажется от вас. Это может быть источником вашего предупреждения.

Как только вы закончите обработку уведомления, вы должны вызвать блок в параметре обработчика или ваше приложение будет прекращено. Ваше приложение имеет до 30 секунд времени настенных часов для обработки уведомления и вызова указанного блока обработчика завершения. На практике вы должны вызвать блок обработчика, как только вы закончите обработку уведомления.

Поэтому вызовите блок завершения:

        completionHandler(UIBackgroundFetchResult.NoData)

Я использую этот метод без вызова этого блока завершения и не испытывал никаких проблем, но теперь я добавлю его просто для того, чтобы быть в безопасности. Apple предполагает, что если вы этого не сделаете, ваше приложение не получит приоритет, но я не видел этого на практике.

Ответ 2

Вы зарегистрировали хотя бы один UIUserNotificationType с UIApplication:registerUserNotificationSettings:?

Если вы не регистрируетесь для значка, звука или оповещения, вы можете получать только тихие уведомления, которые доставляются только с помощью FetchCompletionHandler.