swift - 如何正确接收PUSH通知?

标签 swift apple-push-notifications voip callkit pushkit

我正在使用 Xcode 9.2、Swift 4.0 编写 VoIP 应用程序,最低 iOS 版本为 10.3。即使 iPhone 处于 sleep 模式(就像 WhatsApp 或 Viber 一样),我也想接听来电。我已经知道我必须为此使用 CallKit。但我不知道如何正确接收推送通知。我的意思是,我有两种接收方式。首先是在 AppDelegate.swift 中,请看(此方法有效):

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        //Getting permissions for Notifications
        //222
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
        }
        application.registerForRemoteNotifications()
        //222

        return true
    }

    //For PUSH Notifications settings

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("NOTIFICATION ERROR: \(error)")
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let pushToken = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}).lowercased()
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        // Receiving call?
    }

}

但是,无论我在做什么,如果 iPhone 处于 sleep 状态,它都不会触发来电。最近我看到还有另一种接收推送通知的方法。请看:

import UIKit
import CallKit
import PushKit

class ViewController: UIViewController, CXProviderDelegate, PKPushRegistryDelegate {

    override func viewDidLoad() {
        let registry = PKPushRegistry(queue: nil)
        registry.delegate = self
        registry.desiredPushTypes = [PKPushType.voIP]
    }

    func providerDidReset(_ provider: CXProvider) {
    }

    func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
        action.fulfill()
    }

    func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
        action.fulfill()
    }

    func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
        print(pushCredentials.token.map { String(format: "%02.2hhx", $0) }.joined())
    }

    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
        // Receive call?
    }

}

问题是在第一种方法中我有这个 PUSH token :9bcf73ac3d6a68be07c26d8b6a972f5b716cd5308f1a19048b62d19b9b8d4bd1

第二种方法返回这个 PUSH token : 1e40fafb2963161b1bcf1bdde00d625a879c6934e19e2fb32f62b1c9272e956f

而且它们不相等!怎么会这样?因此,主要问题是:如何接收 PUSH 通知以及 AppDelegate 和 PushKit 方法之间的区别是什么以及哪个 token 是正确的?

感谢您的帮助!

最佳答案

有两种类型的通知(实际上更多,但在本例中只有两种):PUSH 通知和 VoIP 通知。他们有不同的 token 和不同的接收系统。 VoIP 服务仅用于调用 (Apple CallKit),相反的 PUSH 服务用于消息和其他通知。所以,事实上,这两种方法都是必要的,并不能替代另一种。这两种方法都需要 Apple 开发者帐户中的不同证书:用于 PUSH 通知的 Apple 推送通知服务 SSL 和用于 VoIP 的 VoIP 服务证书。 谢谢大家的帮助!如果您看到错误,请随意编辑。

关于swift - 如何正确接收PUSH通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48781124/

相关文章:

node.js - 如何在openshift服务器中生成apns证书

objective-c - 用反射修改字符串

ios - 无法控制单击时单元格的按钮图像变化

c# - Moon APNS 的未知错误 P12 文件

ios - 通过带有开发 SSL 证书的 xcode 在设备中推送通知测试

avfoundation - 使用 CallKit 的 VOIP 应用程序中的音频短路

android - android中的局域网调用

ios - 具有后台模式和来电通知的 SIP 应用程序

ios - 如何在 swift 中使用 MapKit 旋转自定义 userLocationAnnotationView 图像?

php - Swift 不解析来自 PHP 服务器的 JSON