Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PushKit not conceiving credentials

I'm struggling for some time here and probably this is my mistake but I can't find it anywhere, an answer for this.

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

I have added the correct background modes, implemented the callbacks in the correct way, didUpdatePushCredentials is getting called normally...

However, the credentials: PKPushCredentials! variable, is giving me an error pointer... It´s not null... not nil... not anything... It simply does not have a value... it´s allocated garbage... and for that reason.. I´m receiving EXC_BREAKPOINT..

I have tried in 3 different devices... Same behavior...

I have already created the Certificates for VoIP Push...

I have done it in different ways:

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

Allways the same...

Here´s 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 gets more readable.

I also added var registry : PKPushRegistry? on the AppDelegate's. In order for this to work, you have to call registerForVoipPush() somewhere in code. In my case, I did it from a button.

PLEASE HELP ME!

like image 513
Raphael Ayres Avatar asked Jan 05 '16 18:01

Raphael Ayres


1 Answers

I ran into the same issue and I solved this by adding a classic Push implementation before initiating the VoIP registration... I guess that somehow Apple wants to ensure you firstly ask the user for basic push and get the user's aknowledgment before authorizing you to process further silent voip stuff...

Enable the Push Notifications for your app... enter image description here

Then, this is the whole resulting AppDelegate file, that is quite 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 a bit more information, this is inspired by this post

like image 71
JBA Avatar answered Sep 21 '22 00:09

JBA