【问题标题】:PushKit not conceiving credentialsPushKit 不包含凭据
【发布时间】:2016-01-05 18:52:33
【问题描述】:

我在这里挣扎了一段时间,这可能是我的错误,但我在任何地方都找不到,这是一个答案。

我已经在某些方面实现了 PushKit,但没有一个是有效的。

我添加了正确的背景模式,以正确的方式实现了回调,didUpdatePushCredentials 被正常调用...

但是,credentials: PKPushCredentials! 变量给了我一个错误指针...它不是 null...不是 nil...不是任何东西...它根本没有值...它s 分配了垃圾......因此......我收到了 EXC_BREAKPOINT..

我已经在 3 种不同的设备上尝试过...相同的行为...

我已经为 VoIP 推送创建了证书...

我以不同的方式做到了:

  • 通过在 didRegisterForRemotePushNotification 之后创建 void Push Registry 对象
  • 通过创建推送注册表而不注册远程推送通知...
  • 通过创建具有主队列、全局队列和自定义队列的注册表..

总是一样...

代码如下:

extension AppDelegate : PKPushRegistryDelegate {

func registerForVoipPush() {

    self.registry = PKPushRegistry(queue:nil)

    if self.registry != nil {

        self.registry!.delegate = self
        self.registry!.desiredPushTypes = Set<String>(arrayLiteral: PKPushTypeVoIP)
    }

    //let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories:nil)
    //UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
}

func pushRegistry(registry: PKPushRegistry!, didUpdatePushCredentials credentials: PKPushCredentials!, forType type: String!) {

    //print out the VoIP token. We will use this to test the nofications.
    NSLog("voip token: \(credentials.token)")

    if credentials != nil {

        let username = NSUserDefaults.standardUserDefaults().objectForKey("username") as? String
        if username != nil {

            ServerDefinitions.subscribeForPush(username!, token: NSString(data: credentials.token, encoding: NSUTF8StringEncoding) as! String, callback: { (retMsg) -> Void in

                print(retMsg)
            })

        }
    }

}

func pushRegistry(registry: PKPushRegistry!, didReceiveIncomingPushWithPayload payload: PKPushPayload!, forType type: String!) {

    let payloadDict = payload.dictionaryPayload["aps"] as? Dictionary<String, String>
    let message = payloadDict?["alert"]

    //present a local notifcation to visually see when we are recieving a VoIP Notification
    if UIApplication.sharedApplication().applicationState == UIApplicationState.Background {

        let localNotification = UILocalNotification();
        localNotification.alertBody = message
        localNotification.applicationIconBadgeNumber = 1;
        localNotification.soundName = UILocalNotificationDefaultSoundName;

        UIApplication.sharedApplication().presentLocalNotificationNow(localNotification);
    }

    else {

        dispatch_async(dispatch_get_main_queue(), { () -> Void in

            print("Incoming Call")
        })
    }

    NSLog("incoming voip notfication: \(payload.dictionaryPayload)")
}

func pushRegistry(registry: PKPushRegistry!, didInvalidatePushTokenForType type: String!) {

    NSLog("token invalidated")
}

}

编辑:

请注意,上面的代码是 AppDelegate 的扩展,只是为了分隔代码,所以它更具可读性。

我还在 AppDelegate 上添加了var registry : PKPushRegistry?。为了使它起作用,您必须在代码中的某处调用registerForVoipPush()。就我而言,我是通过一个按钮完成的。

请帮助我!

【问题讨论】:

  • 我正在尝试运行您的代码,但从未调用过 didRegisterUserNotificationSettings,我认为我不需要在开发者门户中设置任何 app-id 和证书即可接收令牌,或者我需要那个来获得令牌吗?我可以在开发模式下仅从模拟器或设备获取令牌吗?我将 PushKit 作为链接库,并设置了后台模式,然后复制了您的代码,但从未调用过委托方法。我想尝试帮助你:)
  • @Johannes,我已经编辑了我的答案,试图为你澄清事情。这些正是我想要回答的问题。我的猜测是 PushKit 和普通 Push 是两个独立的东西,所以,我不需要 registerForRemoteNotification 来使用 PushKit。我还做了一个启用推送通知和其他一些事情的开发配置文件,但是我认为我们需要正确配置一个 app-id 和一个配置文件。但是……这只是猜测……
  • 你能在 github 上放一个演示吗,我确实做了这些事情。我在 iOS9 上发现了报告的错误,你有什么基础 sdk?
  • 我将 ios 9.2 作为基础 SDK...我无法降低它,因为我使用了一些专门为该 SDK 编译的库
  • 我明白了,我想知道我哪里出错了,委托方法永远不会被调用:/

标签: ios push voip pushkit


【解决方案1】:

我遇到了同样的问题,我通过在启动 VoIP 注册之前添加一个经典的 Push 实现来解决这个问题...... 我猜想苹果希望确保您首先要求用户进行基本推送并获得用户的认可,然后再授权您处理进一步的无声 voip 内容......

为您的应用启用推送通知...

然后,这是整个生成的 AppDelegate 文件,与您的非常相似:

import UIKit
import PushKit


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.

        //Enable all notification type.
        let notificationSettings = UIUserNotificationSettings(forTypes: [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound] , categories: nil)

        //register the notification settings
        application.registerUserNotificationSettings(notificationSettings)


        NSLog("app launched with state \(application.applicationState.stringValue)")

        return true
    }



    func applicationWillResignActive(application: UIApplication) {

    }

    func applicationDidEnterBackground(application: UIApplication) {

    }

    func applicationWillEnterForeground(application: UIApplication) {

    }

    func applicationDidBecomeActive(application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.

        NSLog("app terminated")
    }


}


extension AppDelegate {

    func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {

        //register for voip notifications
        let voipRegistry = PKPushRegistry(queue: dispatch_get_main_queue())
        voipRegistry.desiredPushTypes = Set([PKPushTypeVoIP])
        voipRegistry.delegate = self;

        NSLog("didRegisterUserNotificationSettings")
    }
}

extension AppDelegate: PKPushRegistryDelegate {


    func pushRegistry(registry: PKPushRegistry!, didUpdatePushCredentials credentials: PKPushCredentials!, forType type: String!) {

        //print out the VoIP token. We will use this to test the nofications.
        NSLog("voip token: \(credentials.token)")
    }

    func pushRegistry(registry: PKPushRegistry!, didReceiveIncomingPushWithPayload payload: PKPushPayload!, forType type: String!) {

        let payloadDict = payload.dictionaryPayload["aps"] as? Dictionary<String, String>
        let message = payloadDict?["alert"]

        //present a local notifcation to visually see when we are recieving a VoIP Notification
        if UIApplication.sharedApplication().applicationState == UIApplicationState.Background {

            let localNotification = UILocalNotification();
            localNotification.alertBody = message
            localNotification.applicationIconBadgeNumber = 1;
            localNotification.soundName = UILocalNotificationDefaultSoundName;

            UIApplication.sharedApplication().presentLocalNotificationNow(localNotification);
        }

        else {

            dispatch_async(dispatch_get_main_queue(), { () -> Void in

                let alert = UIAlertView(title: "VoIP Notification", message: message, delegate: nil, cancelButtonTitle: "Ok");
                alert.show()
            })
        }

        NSLog("incoming voip notfication: \(payload.dictionaryPayload)")
    }

    func pushRegistry(registry: PKPushRegistry!, didInvalidatePushTokenForType type: String!) {

        NSLog("token invalidated")
    }
}

extension UIApplicationState {

    //help to output a string instead of an enum number
    var stringValue : String {
        get {
            switch(self) {
            case .Active:
                return "Active"
            case .Inactive:
                return "Inactive"
            case .Background:
                return "Background"
            }
        }
    }
}

更多信息,请参阅this post

【讨论】:

    【解决方案2】:

    作为@JBA,我忘记激活推送通知。看起来即使您只需要推送 VOIP,您也必须激活推送(传统)

    【讨论】:

      猜你喜欢
      • 2017-08-05
      • 1970-01-01
      • 2017-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-05
      • 2019-12-04
      • 2016-07-03
      相关资源
      最近更新 更多