在 iOS swift 中使用 PushKit 令牌进行 PubNub 推送注册

PubNub Push Registration with PushKit token in iOS swift

我正在开发一个 iOS swift 项目,我需要在其中使用 WebRTC 和 PubNub 集成视频通话和聊天,我正在为 PubNub 使用 PubNubSwift SDK 版本 3.0.1。

我在前台集成了视频通话和聊天功能。但是我想在后台或被杀死状态下接到电话时通知用户。对于推送通知,后端团队正在使用 PubNub。所以在 PubNub 管理面板中,我启用了移动移动推送通知,我添加了 TeamID、AuthKeyID 并上传了 Auth Key 令牌(.p8 文件)。见下图。

并且在我的代码中,在 AppDelegate 中,我注册了 PushKit 通知。一旦 运行 应用程序,我将在以下方法中获取 pushKit 令牌。

func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) { 

} 

获得令牌后,我正在做的是使用 pushKit 令牌将我的设备和频道名称注册到 PubNub 中。我的代码是,

func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) { 
    print(credentials.token)
    let deviceToken = credentials.token.map { String(format: "%02x", [=13=]) }.joined()
    let dataStr: Data = Data(deviceToken.utf8)
    let stringNS = NSData(data: dataStr)
    
    if let channel = UserDefaults.standard.value(forKey: "pubnubUserName") as? String {
        let chatChannel = "\(channel).chat"
        let callChannel = "\(channel)-stdby"
        
        pubnub.modifyAPNSDevicesOnChannels(
            byRemoving: [],
            thenAdding: [chatChannel, callChannel],
            device: dataStr,
            on: "com.Qinnovation.Connect-Debug",
            environment: .development
        ) { result in
            switch result {
                case let .success(response):
                  print("Successful Push Modification Response: \(response)")

                case let .failure(error):
                  print("Failed Push List Response: \(error.localizedDescription)")
            }
        }
    }
    
    UserDefaults.standard.set(deviceToken, forKey: "PushToken")
    print("pushRegistry -> deviceToken :\(deviceToken)")
}

并且在向 PubNub 注册 pushKit 令牌时,我得到了成功响应。之后,我只是打印与同一令牌关联的频道名称(仅用于测试),并且在成功响应中我收到了我的频道名称。所以它正在工作。但是当我尝试从 PubNub 调试控制台发送示例负载时,我没有收到以下方法中的任何回调,

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
    print(payload.dictionaryPayload)
}

但是当我使用这个查询在终端中尝试时,

curl -v -d '{"aps":{"alert":"hello"}}' --http2 --cert VOIP.pem:Qinnovation1 https://api.development.push.apple.com/3/device/2923af68bf211ca1acf7d1b8dccd83432e8f5eaf30fdec65515a96db908f0c83

我在上面的方法中得到了回调。但为什么我没有收到来自 PubNub 的任何回调?我的示例负载是:

{
   "pn_apns":{
      "aps":{
         "content-available":1,
         "alert": "hello world"   
      },
      "pn_push":[
         {
            "push_type":"voip",
            "collapse_id":"1312414asdaqr124",
            "expiration":"2020-01-01 00:00:00.00Z",
            "targets":[
               {
                  "environment":"development",
                  "topic":"com.Qinnovation.Connect-Debug"
               }
            ],
            "version":"v2"
         }
      ],
      "custom_data_a":"important_string",
      "custom_data_b":{
         "important_string":true
      }
   }
}

当我在调试控制台中发送时,响应是

但是我没有收到任何回电。

我认为您不需要对设备令牌执行任何 String 编码,并且可以直接将 credentials.token 直接传递给(PubNub 和 UserDefaults)。

对于一般的远程通知调试,您可以阅读相关的 technical note。我发现在 macOS 上使用 Console 应用程序,过滤应用程序的 Bundle ID,有助于查看是否有与 Push 相关的有用系统日志。

对于 iOS 13+ 上的 PushKit,请确保您正在调用 reportNewIncomingCall(with:update:completion:) 以通知 CallKit 已收到来电。参见 pushRegistry(_:didReceiveIncomingPushWith:for:completion:)

如果这不能解决问题,您可以联系 PubNub support,他们可以提供额外的帮助。