didReceiveRemoteNotification nie jest wywoływany w iOS 13.3, gdy aplikacja jest w tle

10

Walę głową Wdrażam powiadomienie push. Wszystko działa dobrze (wypychanie jest odbierane, znaczek jest aktualizowany), ale w iOS 13.3 aplikacja metody (_: didReceiveRemoteNotification: fetchCompletionHandler :) nie jest wywoływana, gdy aplikacja jest w tle. Jeśli aplikacja znajduje się na pierwszym planie lub używa urządzenia z systemem iOS 12, wywoływana jest metoda. Rejestruję się w celu powiadomienia push w następujący sposób:

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

Ładunek jest ustawiony na następujące

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

Próbowałem dodać „Zdalne powiadomienia” i „Przetwarzanie w tle” jako funkcje aplikacji we wszystkich odmianach (tylko „Zdalne powiadomienia” / „Przetwarzanie w tle”, bez żadnej z tych możliwości, umożliwiając jedno i drugie) bez żadnych zmian. Ustawiłem delegata dla UNUserNotificationCenter, ale znowu bez powodzenia. Ustawiam odpowiednio nagłówki:

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

Z dokumentów wynika, że ​​ta metoda jest wywoływana nawet wtedy, gdy aplikacja działa w tle:

Ta metoda służy do przetwarzania przychodzących zdalnych powiadomień dotyczących aplikacji. W przeciwieństwie do aplikacji: didReceiveRemoteNotification: metoda, która jest wywoływana tylko wtedy, gdy aplikacja działa na pierwszym planie, system wywołuje tę metodę, gdy aplikacja działa na pierwszym planie lub w tle.

Czego mi brakuje tutaj na iOS 13?

MartinW1985
źródło
1
Zobacz wyżej: wszystko działa poprawnie (otrzymano wypychanie, znaczek został zaktualizowany), ale w iOS 13.3 aplikacja metody (_: didReceiveRemoteNotification: fetchCompletionHandler :) nie jest wywoływana, gdy aplikacja jest w tle.
MartinW1985
application (_: didReceiveRemoteNotification: fetchCompletionHandler :) zostanie wywołany po dotknięciu baneru powiadomienia
Tak, to jest poprawne. Moje pytanie brzmi: dlaczego nie jest wywoływane, gdy aplikacja jest w tle. Z mojego zrozumienia doktorzy tak twierdzą.
MartinW1985
Czy próbowałeś zaimplementować application(_:didReceiveRemoteNotification:withCompletionHandler:)metodę?
HardikS

Odpowiedzi:

2

Ustawiłeś?

"content-available": 1

w twoim backendie APS?

Upewnij się również, czy masz włączony tryb tła w pliku info.plist swojej aplikacji na iOS

<key>UIBackgroundModes</key>
<array>
    <string>processing</string>
    <string>remote-notification</string>
</array>
Zhang Zhan
źródło
@matt post został przypadkowo przesłany, zanim wpisałem wszystkie odpowiedzi. Teraz jest to zakończone zmianą po stronie aplikacji.
Zhang Zhan
1
Tak. Możesz zobaczyć z mojej prośby CURL w moim początkowym poście. Dodałem również „dostępne treści”: 1 i wypróbowałem wszystkie tryby tła (włączony, wyłączony, odmiany), ale nadal aplikacja (_: didReceiveRemoteNotification: fetchCompletionHandler :) nie zostaje wywołana. Tylko jeśli aplikacja jest aktywna.
MartinW1985
<string> processing </string> => to jest ważna linia
Dong Mai
@ZhangZhan: Czy kiedykolwiek rozwiązałeś ten problem? Występuje ten sam problem, w którym powiadomienia ciche / w tle nie są odbierane, nawet jeśli klucz dostępności treści jest ustawiony poprawnie. Na iOS 12 wszystko działa poprawnie, ale na iOS13 działają tylko powiadomienia dźwiękowe / wizualne. Wiem, że Apple wymaga dołączenia nowego typu nagłówka do powiadomienia, ale jest to już obsługiwane (korzystamy z SNS). Co ciekawe, nie działa to w symulatorze z plikiem apns z najnowszą wersją XCode.
co
2

Wydaję bilet na wsparcie, aby uzyskać odpowiedź na ten problem.

Okazuje się, że dokumentacja nie jest w 100% „poprawna” dla iOS 13 na ten temat. Urządzenie decyduje, czy się obudzić, czy nie. Chociaż dokumentacja mówi nieco inaczej.

Preferowany przez Apple sposób implementacji jako rozszerzenie powiadomienia. Następnie musisz dostosować ładunek, aby zawierał „treść zmienną”.

Zapytałem potem wsparcie, czy powinienem złożyć radar, a oni odpowiedzieli „tak”.

MartinW1985
źródło
jeśli podasz rozszerzenie powiadomienia, czy aplikacja się obudzi?
Peter Lapisu
0

Wdróż, didRegisterForRemoteNotificationsWithDeviceTokena także didFailToRegisterForRemoteNotificationsWithErrorw delegacie aplikacji, aby sprawdzić, czy urządzenie nawiązuje dobre połączenie z serwerem APN Apple. Jeśli tak nie jest, uruchom ponownie urządzenie i / lub spróbuj nawiązać połączenie za pośrednictwem innej sieci Wi-Fi i uruchom ponownie aplikację.

Ely
źródło
0

Ta metoda przekazania:

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

jest wywoływany, gdy klikamy powiadomienie dla iOS 13, a aplikacja jest w tle.

użytkownik13150044
źródło
1
Tak, ale szukałem sposobu na uzyskanie ładunku bez klikania powiadomienia.
MartinW1985
0

Musisz wdrożyć rozszerzenie treści powiadomienia

Ponieważ korzystałem z OneSignal i jego kodu instalacyjnego, działało to dobrze dla mnie https://documentation.onesignal.com/docs/ios-sdk-setup

Nie jestem pewien, czy bity OneSignal mają znaczenie, ale i tak je dołączam

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)
        }
    }

}
Peter Lapisu
źródło