Audio and Video Call

The AppLozic Audio-Video Call SDK provides high-quality IP audio and video calls. With this SDK, your application's users can take part in secure 1-to-1 calls.

Requirements

  • Install the following:

    • Xcode 12.0 or later
    • CocoaPods 1.9.0 or later
  • Make sure that your project meets these requirements:

    • Your project must target iOS 11 or later.
  • Set up a physical iOS device to run your app

Installation

Using CocoaPods

Add below pod dependency of Applozic Audio Video and also add the use_frameworks! in your Podfile :

source 'https://github.com/CocoaPods/Specs'
use_frameworks!  # Required to add 
platform :ios, '11.0' # Required to add

target 'TARGET_NAME' do
    pod 'ApplozicAudioVideo'  # Required to add 
end

And go to your project directory where Podfile there run pod install from the terminal

🚧

Note: The Audio-Video Call SDK includes our messaging SDK. If you have added pod 'Applozic' in your Podfile please remove that.

Integration Steps

Pre-requisites

  • Before setting up the audio-video call feature, make sure you follow our messaging setup from the registration
  • You will also need to have push notifications setup.

🚧

Pre-requisites steps need to follow them for basic integration

Note: Make sure Pre-requisites is followed then only you can go with the below steps

Add Audio-video configuration

Add below setting in ALChatManger.m's the file in the method ALDefaultChatViewSettings to enable the audio-video call

[ALApplozicSettings setAudioVideoClassName:@"ALAudioVideoCallVC"];
[ALApplozicSettings setAudioVideoEnabled:YES];
ALApplozicSettings.setAudioVideoClassName("ALAudioVideoCallVC")
ALApplozicSettings.setAudioVideoEnabled(true)

Push notification setup

Apart from the basic push notification of messaging APNs, you will need to do the VOIP push notification

Creating VOIP certificate

VOIP certificate is required for sending incoming call notification from applozic to your app

  1. Visit this link, to create VoIP Services Certificate it would look like below once you have created in Apple developer

Once the certificate is created download that and export the p12 file with password from the downloaded certificate either from Keychain Acess from Mac.

🚧

Contact [email protected] via email

For uploading the VOIP certificate as we don't have the option to upload this from the applozic console right now you will need to send an email with your applozic APP-ID and p12 VOIP Certificate and password for uploading the p12 VOIP certificate

Adding Capabilities to Your App

Add capabilities to configure app services from Apple, such as push notifications, Background modes

On the Xcode project’s Signing & Capabilities tab, Click (+ Capability) to add “Push Notifications”

Next Click (+ Capability) to add "Background modes" enable this below four options from Background modes

  • “Audio, AirPlay and Picture in Picture”
  • "Voice over IP"
  • "Background fetch"
  • "Remote notifications"

The following screenshot would be of help.

Configure the push notification in the Appdelegate file of your project.

Add the below imports in the Appdelegate file

#import <PushKit/PushKit.h>
#import <ApplozicAudioVideo/ALAudioVideoPushNotificationService.h>
#import <ApplozicAudioVideo/ALAudioVideoCallHandler.h>
import PushKit
import ApplozicAudioVideo

Make sure that your App delegate has these delegates

@interface AppDelegate () <UNUserNotificationCenterDelegate, PKPushRegistryDelegate>
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, PKPushRegistryDelegate {

Register PushRegistry for VOIP notification

Use the below code to register the notifications if you have added the method registerForNotification from the basic notification setup then you can replace it with the below registerForNotification method code

-(void)registerForNotification
{
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error)
     {
        if(!error)
        {
            dispatch_async(dispatch_get_main_queue(), ^ {
                [[UIApplication sharedApplication] registerForRemoteNotifications];  // required to get the app to do anything at all about push notifications
                NSLog(@"Push registration success." );
                /// Push kit Registry
                PKPushRegistry * pushKitVOIP = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
                pushKitVOIP.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
                pushKitVOIP.delegate = self;
            });
        }
        else
        {
            NSLog(@"Push registration FAILED" );
            NSLog(@"ERROR: %@ - %@", error.localizedFailureReason, error.localizedDescription );
            NSLog(@"SUGGESTIONS: %@ - %@", error.localizedRecoveryOptions, error.localizedRecoverySuggestion );
        }
    }];
}
func registerForNotification() {
        UNUserNotificationCenter.current().delegate = self
        UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in

            if granted {
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                    /// PUSHKIT Register
                    let pushKitVOIP = PKPushRegistry(queue: DispatchQueue.main)
                    pushKitVOIP.delegate = self
                    pushKitVOIP.desiredPushTypes = [.voIP]
                }
            }
        }
    }

Add the notification handler for VOIP

In your Appdelegate file find the method didFinishLaunchingWithOptions and add the below code just below the ALAppLocalNotifications handler

[[ALAudioVideoCallHandler shared] dataConnectionNotificationHandler];
let alAudioVideoCallHandler = ALAudioVideoCallHandler.shared()
 alAudioVideoCallHandler.dataConnectionNotificationHandler()

Sending an APNs and VOIP device token to applozic server

Add the below code in your Appdelegate file If you added the code from the basic push notification setup before for didRegisterForRemoteNotificationsWithDeviceToken you will need to remove that and add this below code

// APNs device token sending to applozic
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSLog(@"DEVICE_TOKEN :: %@", deviceToken);

    const unsigned *tokenBytes = [deviceToken bytes];
    NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                          ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                          ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                          ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];

    NSString *apnDeviceToken = hexToken;
    NSLog(@"APN_DEVICE_TOKEN :: %@", hexToken);

    if ([[ALUserDefaultsHandler getApnDeviceToken] isEqualToString:apnDeviceToken]) {
        return;
    }

    ALRegisterUserClientService *registerUserClientService = [[ALRegisterUserClientService alloc] init];
    [registerUserClientService updateAPNsOrVOIPDeviceToken:apnDeviceToken
                                          withApnTokenFlag:YES withCompletion:^(ALRegistrationResponse *response, NSError *error) {

    }];
}

// Pushkit VOIP token sending to applozic 
-(void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(PKPushType)type {

    NSLog(@"PUSHKIT : VOIP_TOKEN_DATA : %@",credentials.token);
    const unsigned *tokenBytes = [credentials.token bytes];
    NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                          ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                          ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                          ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];

    NSLog(@"PUSHKIT : VOIP_TOKEN : %@",hexToken);
    if ([[ALUserDefaultsHandler getVOIPDeviceToken] isEqualToString:hexToken]) {
        return;
    }

    NSLog(@"PUSHKIT : VOIP_TOKEN_UPDATE_CALL");
    ALRegisterUserClientService *registerUserClientService = [[ALRegisterUserClientService alloc] init];
    [registerUserClientService updateAPNsOrVOIPDeviceToken:hexToken
                                          withApnTokenFlag:NO withCompletion:^(ALRegistrationResponse *response, NSError *error) {

    }];
}
// APNs device token sending to applozic
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

        print("Device token data :: \(deviceToken.description)")

        var deviceTokenString: String = ""
        for i in 0..<deviceToken.count {
            deviceTokenString += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
        }

        print("Device token :: \(deviceTokenString)")

        if (ALUserDefaultsHandler.getApnDeviceToken() != deviceTokenString) {
            let alRegisterUserClientService: ALRegisterUserClientService = ALRegisterUserClientService()

            alRegisterUserClientService.updateAPNsOrVOIPDeviceToken(deviceTokenString, withApnTokenFlag: true) { (response, error) in

                guard error == nil else {
                    print("Error in Registration %@", error?.localizedDescription as Any)
                    return
                }
                guard let result = response, result.isRegisteredSuccessfully() else {
                    return
                }
                print("Update success in token for apns");
            }
        }
}

 // Pushkit VOIP token sending to applozic
 func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {

        var voipTokenString: String = ""
        for i in 0 ..< pushCredentials.token.count {
            voipTokenString += String(format: "%02.2hhx", pushCredentials.token[i] as CVarArg)
        }

        print("VOIP_DEVICE_TOKEN_STRING :: \(voipTokenString)")

        if ALUserDefaultsHandler.getVOIPDeviceToken() != voipTokenString {
            let alRegisterUserClientService = ALRegisterUserClientService()
            alRegisterUserClientService.updateAPNsOrVOIPDeviceToken(voipTokenString, withApnTokenFlag: false) { (response, error) in
                print("REGISTRATION_RESPONSE :: \(String(describing: response))")
            }
        }
}

Receiving push notification

Once your app receives notification, pass it to the Applozic handler for chat notification processing.

If you have added the didReceiveRemoteNotification UIBackgroundFetchResult method from the basic push notification please remove that UIBackgroundFetchResult method and replace it with the below code in the Appdelegate file

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{

    NSLog(@"RECEIVED_NOTIFICATION_WITH_COMPLETION :: %@", userInfo);
    ALPushNotificationService *pushNotificationService = [[ALPushNotificationService alloc] init];
    if ([pushNotificationService isApplozicNotification:userInfo]) {
        ALAudioVideoPushNotificationService * audioVideoPushNotificationService = [[ALAudioVideoPushNotificationService alloc] init];
        [audioVideoPushNotificationService processPushNotification:userInfo];
        [pushNotificationService notificationArrivedToApplication:application withDictionary:userInfo];
        completionHandler(UIBackgroundFetchResultNewData);
        return;
    }
    completionHandler(UIBackgroundFetchResultNewData);
}

// PushKit delegate for VOIP call notification 
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void(^)(void))completion {

    NSLog(@"PUSHKIT : INCOMING VOIP NOTIFICATION : %@", payload.dictionaryPayload.description);

    ALAudioVideoPushNotificationService *pushNotificationService = [[ALAudioVideoPushNotificationService alloc] init];
    NSDictionary * userInfoPayload = payload.dictionaryPayload;
    if ([pushNotificationService isApplozicNotification:userInfoPayload]) {
        [pushNotificationService processPushNotification:userInfoPayload];
        completion();
        return;
    }
    completion();
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

        print("Received notification With Completion :: \(userInfo.description)")
        let alPushNotificationService: ALPushNotificationService = ALPushNotificationService()
        if (alPushNotificationService .isApplozicNotification(userInfo)) {
            /// Audio Video notification proccessing
            let audioVideoPushNotificationService = ALAudioVideoPushNotificationService()
            audioVideoPushNotificationService.processPushNotification(userInfo)

            /// Messaging  notification proccessing
            alPushNotificationService.notificationArrived(to: application, with: userInfo)
            completionHandler(UIBackgroundFetchResult.newData)
            return
        }
        completionHandler(UIBackgroundFetchResult.newData)
 }

// PushKit delegate for VOIP call notification 
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {

        print("PUSHKIT : INCOMING VOIP NOTIFICATION : %@", payload.dictionaryPayload.description)

        let audioVideoPushNotificationService = ALAudioVideoPushNotificationService()
        if (audioVideoPushNotificationService.isApplozicNotification(payload.dictionaryPayload)) {
            audioVideoPushNotificationService.processPushNotification(payload.dictionaryPayload)
            completion()
        }
 }

If you are facing any difficulties, you can contact us at [email protected]
To check out our cocopods sample app, go here.

Customisation

App icon in CallKit UI screen :

As the Apple call screen needs an app icon to show it in call screen
Use the below settings in ALChatManager file in ALDefaultChatViewSettings method

NOTE: The call kit icon needs to be transparent and 40 * 40 size

[ALAudioVideoSettings setCallKitAppIconName:@"callkit-app-icon.png"];
ALAudioVideoSettings.setCallKitAppIconName("callkit-app-icon.png")

What’s Next
Did this page help you?