Skip to main content

Since iOS 13, Apple requires VoIP push notifications to be used with CallKit for security reasons. Otherwise, iOS terminates the app process after receiving a VoIP push notification. Because of regulatory requirements, apps distributed through the China App Store cannot use Apple CallKit. Developers distributing in China should not use VoIP push notifications.

Import PushKit and Configure PKPushRegistry

#import <PushKit/PushKit.h>

@interface AppDelegate () <PKPushRegistryDelegate>
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// initialize PKPushRegistry
PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
return YES;
}

Register for VoIP Push Notifications and Handle Callbacks

#pragma mark - PKPushRegistryDelegate

// called when the VoIP token is generated
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(PKPushType)type {
// call the SDK API to send the VoIP token to the IM server
[JIM.shared.connectionManager registerVoIPToken:credentials.token];
}

// called when the device receives a VoIP push notification
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {
NSLog(@"Received VoIP push notification: %@", payload.dictionaryPayload);

// handle business logic based on the push payload, such as displaying the incoming-call UI
[self handleIncomingCallWithPayload:payload.dictionaryPayload];
}

// handle an incoming call
- (void)handleIncomingCallWithPayload:(NSDictionary *)payload {
// parse the push payload and display the incoming-call UI

//call ID
NSString *callId = payload[@"room_id"];
//inviter's user ID
NSString *inviterId = payload[@"inviter_id"];
//whether this is a group call
BOOL isMulti;
//call type
JCallMediaType mediaType;
id obj = payload[@"is_multi"];
if ([obj isKindOfClass:[NSNumber class]]) {
isMulti = [(NSNumber *)obj boolValue];
}
obj = payload[@"media_type"];
if ([obj isKindOfClass:[NSNumber class]]) {
mediaType = [(NSNumber *)obj integerValue];
}

// TODO: Use CallKit or a custom UI to display the incoming-call notification
}