iOS没有使用apn nodejs接收后台推送通知

时间:2017-07-14 20:13:02

标签: ios node.js swift apple-push-notifications

我的设备未收到后台推送通知。我在智慧结束时,我已经尝试了我可以通过Stack Overflow找到和搜索的每个教程。

  • 设备和APN设置为调试/开发
  • 我可以成功注册设备令牌
  • 我有一个带推送通知服务的活动.p8密钥
  • APN说推送消息已成功发送
  • didReceiveRemoteNotification不会触发
  • 在背景和前景中尝试使用应用
  • 使用AWS:入站 - 端口22,出站 - 所有端口

这是回复:

  

{ “发送”:[{ “设备”: “cc7ec9a821cf232f9510193ca3ffe7d13dd756351794df3f3e44f9112c037c2a”}], “失败”:[]}

这是我的代码:

AppDelegate.swift

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        if #available(iOS 10, *) {
            let center  = UNUserNotificationCenter.current()
            center.delegate = self
            center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
                if error == nil {
                  UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {            
        var deviceTokenString: String = ""
        for i in 0..<deviceToken.count {
            deviceTokenString += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
        }
        UserDefaults.standard.set(deviceTokenString, forKey: "push_token")
    }


    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter,  willPresent notification: UNNotification, withCompletionHandler   completionHandler: @escaping (_ options:   UNNotificationPresentationOptions) -> Void) {
        print("Handle push from foreground")
        print("\(notification.request.content.userInfo)")
        completionHandler([.alert, .badge, .sound])
    }

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print("Handle push from background or closed")
        // if you set a member variable in didReceiveRemoteNotification, you  will know if this is from closed or background
        print("\(response.notification.request.content.userInfo)")
        completionHandler()
    }
}

的XCode:

enter image description here enter image description here

Node.js的

.p8密钥来自开发者控制台:密钥&gt;所有

var apn = require('apn');

var apnProvider = new apn.Provider({
    token: {
        key: "/path/to/AuthKey_1234ABCD.p8",
        keyId: "1234ABCD",
        teamId: "1234ABCD"
    },
    production: false
});

var note = new apn.Notification();
note.topic = "com.company.app";
note.payload = {
    aps: {
        "content-available" : 1
    },
    custom_field: {}
};

apnProvider.send(note, push_token).then(result => {
            console.log('result: ', result);
            console.log("sent:", result.sent.length);
            console.log("failed:", result.failed.length);
});

3 个答案:

答案 0 :(得分:1)

我很感激大家的意见,我想出了这个问题。

&#39; APS&#39;不属于有效负载字段,而应该属于通知构造函数。

Node.js的:

var note = new apn.Notification({
    aps: {
        "content-available" : 1
    }
});

note.payload = {
    custom_field_1: {},
    custom_field_2: ''
};

答案 1 :(得分:0)

我不确定是否是这种情况,因为您的服务器正在使用此APN节点模块并且我从未使用它,但我使用Firebase并且每当我尝试使用content_available : 1时,它都无效。工作是content_available : true

希望这适合你。

答案 2 :(得分:0)

您是在AppDelegate

上写的
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print("Silent push notification received: \(userInfo)")    
    }

但是你还写道:

center.delegate = notificationDelegate

这意味着你的AppDelegate 不是 notificationCenter的代表。

将其更改为

center.delegate = self

或者只是将该函数移除到采用它的类,即UYLNotificationDelegate

你似乎没事。虽然我不知道如何读取node.js,因此您可能已将错误配置为错误。有时候,如果服务器没有正确管理多个设备令牌,你可能根本没有得到无声通知或我们后端的另一个问题是他们在我们测试通知时将通知服务器重定向到他们的本地机器,显然他们没有进来!

来自Apple的示例有效负载应如下所示:

{
    "aps" : {
        "content-available" : 1
    },
    "acme1" : "bar",
    "acme2" : 42
}

您确定生成的有效负载具有类似的格式吗?!

  • 我错误地建议您将center.delegate = notificationDelegate更改为center.delegate = self,但如果我非常绝望,我会试一试:D。

  • 确保background App Refresh已启用(但仍未启用此功能,您应该在前台收到

  • 如果这不起作用,请尝试使用提醒/徽章发送并查看 如果那样的话。可能它不起作用:/

  • 删除应用,然后 再次安装。有时授权不正确,如果 你刚刚重新安装。
  • 清理派生数据,清理构建,重新启动Xcode。

编辑后:

您不应该删除didReceive 远程通知&lt; - 这是用于检索任何包含content-available : 1的推送通知。

  • 如果应用在FOREGROUND中,willPresent是回调操作。仅当有效载荷在有效载荷中具有警报或徽章或声音时才适用。
  • didReceiveNotificationResponse并非您认为的那样。它用于处理管理用户从通知中选择的动作,例如您的通知有两个操作(暂停,删除),点击如下: enter image description here

您使用此回调处理通知的响应

从技术上讲,如果你只是有一个无声通知,那么你只能得到第三个回调,而不是前两个。

如果您的应用程序位于前台并且有效负载具有:content-available :1也有操作并且用户点击了操作,那么您将首先获得第3个回调,然后是第1个回调,然后是第2个回调回调。