当应用程序在后台运行时,iOS 13.3中未调用didReceiveRemoteNotification


10

我在敲头。我正在实施推送通知。一切正常(接收到推送,更新了徽章),但是在iOS 13.3下,当应用程序在后台运行时,不会调用application(_:didReceiveRemoteNotification:fetchCompletionHandler :)方法。如果应用程序在前台或使用iOS 12设备,则将调用该方法。我通过以下方式注册推送通知:

[[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

从文档中可以看出,即使应用程序处于后台,该方法也会被调用:

使用此方法可以为您的应用处理传入的远程通知。与application:didReceiveRemoteNotification:方法不同,该方法仅在您的应用程序在前台运行时才调用,而在您的应用程序在前台或后台运行时,系统会调用此方法。

对于iOS 13,我在这里缺少什么?



1
请参阅上面的内容:一切工作正常(收到推送,更新了徽章),但是在iOS 13.3下,当应用程序在后台运行时,不会调用application(_:didReceiveRemoteNotification:fetchCompletionHandler :)方法。
MartinW1985

当您点击通知横幅时,将调用application(_:didReceiveRemoteNotification:fetchCompletionHandler :)

是的,这是正确的。我的问题是:当应用程序在后台运行时为什么不调用它。根据我的理解,文档是这样说的。
MartinW1985

您尝试过实施application(_:didReceiveRemoteNotification:withCompletionHandler:)方法吗?
HardikS

Answers:


2

你设置好了吗

"content-available": 1

在您的后端APS有效载荷中?

还需要确保您已在iOS App的info.plist文件中启用了后台模式

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

@matt在我输入所有答案之前,该帖子是偶然提交的。现在完成了应用程序侧更改。
张展

1
是的,我做到了。您可以从我的初始帖子的CURL请求中看到。我还添加了“内容可用”:1,并尝试了所有后台模式(启用,禁用,变体),但仍然没有调用application(_:didReceiveRemoteNotification:fetchCompletionHandler :)。仅在应用程序处于活动状态时。
MartinW1985

<string> processing </ string> =>这是重要的一行
Dong Mai

@张展:你曾经解决过这个问题吗?我遇到了同样的问题,即使正确设置了内容可用的密钥,也无法接收静默/后台通知。在iOS 12上,一切正常,但在iOS13上,只有声音/视觉通知有效。我知道Apple要求在通知中包含新的标头类型,但该标头类型已被处理(我们正在使用SNS)。有趣的是,这在具有最新XCode版本的apns文件的模拟器中不起作用。
whawhat

2

我花了一张支持票来解决这个问题。

事实证明,此主题的文档对于iOS 13并非100%“有效”。设备决定是否唤醒。尽管文档指出有些不同。

Apple首选的实现方式是通知扩展。之后,您必须调整有效负载以包含“可变内容”。

之后我问支持者是否应该提出雷达要求,他们回答“是”。


如果您提供通知扩展名,该应用程序是否被唤醒?
Peter Lapisu

0

实施didRegisterForRemoteNotificationsWithDeviceTokendidFailToRegisterForRemoteNotificationsWithError在您的应用程序的委托中,检查设备是否与Apple的APN服务器建立了良好的连接。如果不是这种情况,请重新启动设备和/或尝试通过另一个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)
        }
    }

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.