didUpdatePushCredentials not get called

2020-04-05 06:31发布

I want to implement VoIP notifications in my iOS application, But the didUpdatePushCredentials method never got called, I can't get the device token.

I had implemented APNS in the application, May these two services conflict ?

Here is my AppDelegate codes

- (void)application:(UIApplication *)application
    didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    LOGI(@"%@", NSStringFromSelector(_cmd));

    //register for voip notifications
    self->pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
    [self->pushRegistry setDelegate:self];
    [self->pushRegistry setDesiredPushTypes:[NSSet setWithObject:PKPushTypeVoIP]];

    NSLog(@"VoIP push registered");

}

#pragma mark - VoIP push methods

- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
    NSLog(@"voip token: %@", credentials.token);
}

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
    NSDictionary *payloadDict = [payload.dictionaryPayload valueForKey:@"aps"];
    NSString *message = (NSString *)[payloadDict valueForKey:@"alert"];

    if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
        UILocalNotification *localNotification = [[UILocalNotification alloc] init];
        localNotification.alertBody = [message stringByAppendingString:@" - voip"];
        localNotification.applicationIconBadgeNumber = 1;
        localNotification.soundName = @"notes_of_the_optimistic.caf";

        [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
    } else {
        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"VoIP notification" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alert show];
        });
    }


    NSLog(@"incoming voip notfication: %@", payload.dictionaryPayload);
}

- (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(NSString *)type {
    NSLog(@"Voip token invalidate");
}
  • I enabled remote notifications, Certificate and provisioning profiles are installed.
  • I can push standard notifications using APNS.

Any solution to get it working ?

4条回答
你好瞎i
2楼-- · 2020-04-05 07:13

For me the solution was to enable:

enter image description here

P.S. I didn't forget to enable enter image description here But enabling general pushes was important too. So full code is:

import UIKit
import PushKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


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

        return true
    }

    // Register for VoIP notifications
    func voipRegistration() {
        let mainQueue = DispatchQueue.main
        // Create a push registry object
        let voipRegistry: PKPushRegistry = PKPushRegistry(queue: mainQueue)
        // Set the registry's delegate to self
        voipRegistry.delegate = self
        // Set the push type to VoIP
        voipRegistry.desiredPushTypes = [.voIP]
    }

}

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

    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
        print("payload = \(payload.dictionaryPayload)")
    }
}
查看更多
太酷不给撩
3楼-- · 2020-04-05 07:16

If you're running a newer xcode (I'm on xcode 9) then VOIP is not in the Background section on the Capabilities tab. This will prevent didUpdatePushCredentials from being called!

The trick is you have to go in your plist, and in Required Background Modes you need to add App provides Voice over IP services.

I can't believe Apple has done this to us. I wasted an 8 hour work day looking for this simple fix.

enter image description here

查看更多
放荡不羁爱自由
4楼-- · 2020-04-05 07:20

There was an issue with Certificates.

Regenerated and reimported certificates and issue fixed.

查看更多
迷人小祖宗
5楼-- · 2020-04-05 07:24

Use below code and Make sure about following things.

**`**// Register for VoIP notifications**`**

- (void) voipRegistration {
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    // Create a push registry object
    _voipRegistry = [[PKPushRegistry alloc] initWithQueue: mainQueue];
    // Set the registry's delegate to self
    [_voipRegistry setDelegate:(id<PKPushRegistryDelegate> _Nullable)self];
    // Set the push type to VoIP
    _voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}

Call Below method in didFinishLaunchingWithOptions

Other deleget method as follow

- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials: (PKPushCredentials *)credentials forType:(NSString *)type {
    // Register VoIP push token (a property of PKPushCredentials) with server

    if([credentials.token length] == 0) {
        NSLog(@"voip token NULL");
        return;
    }
    NSLog(@"%@",credentials.token);
}

//Make sure about this in project capabilities

1)Background mode is ON

2)VOIP

3)Background Fetch

4)remotenotification

5) Dont forgot to import delegate

inside the Background MODE

查看更多
登录 后发表回答