didReceiveRemoteNotification не викликається в iOS 13.3, коли програма знаходиться у фоновому режимі


10

Я стукаю головою. Я впроваджую push-сповіщення. Все працює нормально (натискання отримане, значок оновлюється), але в iOS 13.3 застосовано метод (_: didReceiveRemoteNotification: fetchCompletionHandler :) не викликається, коли програма знаходиться у фоновому режимі. Якщо додаток стоїть на передньому плані або використовується пристрій iOS 12, метод викликається. Я реєструюсь для push-повідомлення таким чином:

[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
    if (granted) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] registerForRemoteNotifications];
        });
    }
}];

Корисне навантаження встановлюється наступним чином

{"aps": {
    "badge": 10,
    "alert": "test",
    "content-available": 1
}}

Я намагався додавати "Віддалені сповіщення" та "Фонову обробку" як можливості додатків у всіх варіантах (лише "Віддалене сповіщення" / "Фонова обробка" без жодної з цих можливостей, що дозволяє обидва) без будь-яких змін. Я встановив делегата для UNUserNotificationCenter, але знову без успіху. Я встановив заголовки відповідно:

curl -v \
 -H 'apns-priority: 4' \
 -H 'apns-topic: xx.xxxxx.xxxx' \
 -H 'apns-push-type: alert' \
 -H 'Content-Type: application/json; charset=utf-8' \
 -d '{"aps": {"badge": 10,"alert": "test", "content-available":1}}' \
 --http2 \
 --cert pushcert.pem \
 https://api.sandbox.push.apple.com/3/device/1234567890

У документах зазначено, що цей метод викликається навіть тоді, коли програма знаходиться у фоновому режимі:

Використовуйте цей метод для обробки вхідних віддалених сповіщень для вашої програми. На відміну від програми: метод didReceiveRemoteNotification: який викликається лише тоді, коли ваша програма працює на передньому плані, система викликає цей метод, коли ваш додаток працює на передньому плані або на задньому плані.

Що мені тут не вистачає для iOS 13?


Перевірте, чи використовуєте ви цей метод: developer.apple.com/documentation/uikit/uiapplicationdelegate/…

1
Будь ласка, дивіться вище: Все працює нормально (натискання отримано, значок оновлюється), але в iOS 13.3 застосовано метод (_: didReceiveRemoteNotification: fetchCompletionHandler :) не викликається, коли програма знаходиться у фоновому режимі.
MartinW1985

додаток (_: didReceiveRemoteNotification: fetchCompletionHandler :) буде викликано, коли ви натиснете на банер повідомлень

Так, це правильно. Моє запитання: Чому його не називають, коли додаток знаходиться у фоновому режимі. З мого розуміння, документи говорять так.
MartinW1985

Ви пробували, реалізуючи application(_:didReceiveRemoteNotification:withCompletionHandler:)метод?
HardikS

Відповіді:


2

Ви встановили

"content-available": 1

у вас бекенд APS корисного навантаження?

Також потрібно переконатися, що ви увімкнули фоновий режим у файлі info.plist програми для iOS

<key>UIBackgroundModes</key>
<array>
    <string>processing</string>
    <string>remote-notification</string>
</array>

@matt повідомлення було випадково надіслано ще до того, як я надрукую всі відповіді. Тепер це завершено із зміною сторони програми.
Чжан Чжан

1
Так. Ви можете побачити з мого запиту CURL у моєму початковому дописі. Я також додав "content-available": 1 і спробував усі фонові режими (увімкнено, вимкнено, варіанти), але все ж додаток (_: didReceiveRemoteNotification: fetchCompletionHandler :) не викликається. Тільки якщо додаток активний.
MartinW1985

<string> обробка </string> => це рядок імпортерів
Dong Mai

@ZhangZhan: Ви коли-небудь вирішували цю проблему? У мене виникає та сама проблема, коли спокійні / фонові сповіщення не надходять, навіть якщо ключ, доступний для вмісту, встановлений правильно. На iOS 12 все працює належним чином, але на iOS13 працюють лише звукові / візуальні сповіщення. Мені відомо, що Apple вимагає, щоб новий тип заголовка був включений у сповіщення, але це вже обробляється (ми використовуємо SNS). Цікаво, що це не працює в тренажері з файлом apns з останньою версією XCode.
whawhat

2

Я витрачаю квиток на підтримку, щоб отримати відповідь на цю проблему.

Виявляється, документація не на 100% «дійсна» для iOS 13 з цієї теми. Пристрій вирішує, прокидатися чи ні. Хоча в документації зазначено трохи інакше.

Кращий спосіб реалізації Apple як розширення сповіщення. Після цього вам доведеться адаптувати корисну навантаження, щоб вона включала "змінні вміст".

Після цього я попросив підтримку, чи варто подавати радар, і вони відповіли "так".


якщо ви надаєте розширення сповіщення, чи додаток прокинувся?
Пітер Лапісу

0

Реалізація didRegisterForRemoteNotificationsWithDeviceToken а також didFailToRegisterForRemoteNotificationsWithErrorу представника програми, щоб перевірити, чи пристрій добре зв’язується з APN-сервером Apple. Якщо це не так, перезавантажте пристрій та / або спробуйте встановити з'єднання через іншу мережу Wi-Fi та перезавантажте програму.


0

Цей метод делегата: -

(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler

викликається, коли ми натискаємо сповіщення для iOS 13, і додаток знаходиться у фоновому режимі.


1
Так, але я шукав спосіб отримати корисну навантаження, не натискаючи сповіщення.
MartinW1985

0

Вам потрібно застосувати розширення вмісту сповіщень

Оскільки я використовував OneSignal і його інсталяційний код, для мене це добре працювало https://documentation.onesignal.com/docs/ios-sdk-setup

не впевнений, чи змінюють біти OneSignal, але додавши їх все одно

import UserNotifications
import OneSignal

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var receivedRequest: UNNotificationRequest!
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.receivedRequest = request;
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        if let bestAttemptContent = bestAttemptContent {
            OneSignal.didReceiveNotificationExtensionRequest(self.receivedRequest, with: self.bestAttemptContent)
            contentHandler(bestAttemptContent)
        }
    }

    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            OneSignal.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
            contentHandler(bestAttemptContent)
        }
    }

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.