PushKit does not understand credentials

I have been scared for some time here, and this is probably my mistake, but I cannot find it anywhere else, the answer to this question.

I implemented PushKit in some way, but none of them were effective.

I added the correct background modes, correctly executed the callbacks, didUpdatePushCredentials normally called ...

However, the variable credentials: PKPushCredentials! gives me a pointer to an error ... It's not null ... not zero ... not something ... It just doesn't matter ... it's "garbage allocated ... and for that reason .. I get EXC_BREAKPOINT ..

I tried on three different devices ... Same behavior ...

I have already created Certificates for VoIP Push ...

I did it differently:

  • By creating a void Push Registry object after didRegisterForRemotePushNotification
  • By creating a push registry without registering for a remote push notification ...
  • By creating a registry with basic, global, and custom queues.

All the same...

Here is the code:

 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") } 

}

EDIT:

Please note that the above code is an extension of AppDelegate, made only to separate the code, so it becomes more readable.

I also added var registry : PKPushRegistry? in AppDelegate. For this to work, you must call registerForVoipPush() somewhere in the code. In my case, I did this with a button.

PLEASE HELP ME!

+6
source share
2 answers

I ran into the same problem and solved this by adding the classic Push implementation before starting VoIP registration ... I assume that somehow Apple wants you to first ask the user to do basic push and get a custom character before allowing you handle further quiet voip messages ...

Turn on push notifications for your application ... enter image description here

Then this is the entire resulting AppDelegate file, which is very similar to yours:

 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" } } } } 

For more info, this is inspired by this post.

+2
source

Like @JBA, I forgot to activate the push notification. This is similar to the fact that you only need to press VOIP to activate pressing (traditional)

0
source

All Articles