Applozic iOS 音频视频 SDK
此项目是一个用于带消息 SDK 的音频-视频通话的 Cocoapods 示例项目。AppLozic 音频-视频通话 SDK 提供高质量的 IP 音频和视频通话。使用此 SDK,您的应用用户可以进行安全的 1 到 1 通话。
示例
要运行示例项目,请克隆仓库,然后首先从示例目录运行 pod install
。
注意:您可以在模拟器中运行样本,但:
- 实时通话通知在模拟器中不会工作,因为它需要实时 VOIP 通知来获取您所需的通话通知,您需要使用 iPhone 设备。
- 本地视频将不会共享,因为模拟器无法访问摄像头。
项目状态
这是一个测试版 SDK
要求
-
安装以下内容
- Xcode 12.0 或更高版本
- CocoaPods 1.9.0 或更高版本
-
确保您的项目满足以下要求
- 您的项目必须针对 iOS 11 或更高版本。
-
设置一个物理 iOS 设备以运行您的应用
设置
在https://www.applozic.com/signup.html注册以获取应用ID,您可以将ALChatManager.h文件中的应用程序ID替换为相同的appID到这个字符串值APPLICATION_ID。
安装
Cocoapods
ApplozicAudioVideo可以通过CocoaPods获取。要安装它,只需将以下行添加到您的Podfile中
source 'https://github.com/CocoaPods/Specs'
use_frameworks! # Required to add
platform :ios, '11.0'
target 'TARGET_NAME' do
pod 'ApplozicAudioVideo' # Required to add
end
然后转到包含Podfile的项目目录,在终端中运行pod install
注意:
音频-视频通话SDK包含我们的消息SDK。如果您在Podfile中添加了pod 'Applozic'
,请删除它。
添加权限
App Store要求任何访问相机、联系人、图库、位置、麦克风的任何应用都在Info.plist文件中添加描述,解释为什么您的应用需要访问这些功能。
请在你项目的Info.plist文件中添加以下权限
<key>NSCameraUsageDescription</key>
<string>Allow Camera</string>
<key>NSContactsUsageDescription</key>
<string>Allow Contacts</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Allow location sharing!!</string>
<key>NSMicrophoneUsageDescription</key>
<string>Allow MicroPhone</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Allow Photos</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Allow write access</string>
<key>NSLocalNetworkUsageDescription</key>
<string>Allow LocalNetwork</string>
集成步骤
遵循基本集成步骤
参考从认证开始的集成步骤,从以下链接启动对话:链接
添加音频视频配置
在 ALChatManger.m 文件中的 ALDefaultChatViewSettings 方法中添加以下设置。
[ALApplozicSettings setAudioVideoClassName:@"ALAudioVideoCallVC"];
[ALApplozicSettings setAudioVideoEnabled:YES];
推送通知
设置 APNs 证书
Applozic 将负载发送到 Apple 服务器,然后 Apple 服务器将推送通知发送到您用户的设备。
创建 APNs 证书
为了 Apple 能够发送这些通知,需要在您的 Apple 开发者账户中创建 APNs 证书。
-
访问此 链接,创建 Apple Push Notification service SSL (Sandbox) 即开发证书
-
访问此 链接,创建 Apple Push Notification service SSL (Sandbox & Production) 即发布证书
证书创建后,您可以从 Mac 的 Keychain Access 中下载它们并导出用于开发和发布证书的 p12 文件,并带有密码。
上传APNs证书
根据以下图片,将您的推送通知证书(如上所述)上传到Applozic控制台。
转到Applozic 控制台 推送通知部分上传APNs开发和分发证书
创建VOIP证书
VOIP证书是用于从Applozic向您的APP发送来电通知所需的
- 访问此链接创建VoIP服务证书
证书创建完毕后,从下载的证书中下载并导出p12文件,带有密码,可以从Mac的Keychain Access中获取。
并通过电子邮件联系[email protected]
上传此VOIP证书,因为我们目前没有通过Applozic控制台上传此证书的选项。
将功能添加到您的应用中
添加功能以从Apple配置应用服务,如推送通知、后台模式
在Xcode项目的签名与功能选项卡中,单击(+功能)添加“推送通知”
下一步,单击(+功能)添加“后台模式”,从以下四个选项中启用后台模式
- “音频、AirPlay和画中画”
- “VoIP”
- “后台获取”
- “远程通知”
以下截图将提供帮助。
配置项目中的AppDelegate文件中推送通知
在Appdelegate文件中添加以下导入
#import <Applozic/Applozic.h>
#import <UserNotifications/UserNotifications.h>
#import <PushKit/PushKit.h>
#import <ApplozicAudioVideo/ALAudioVideoPushNotificationService.h>
#import <ApplozicAudioVideo/ALAudioVideoCallHandler.h>
处理通知点击时应用启动及为APNs和VOIP PushKit注册远程通知
在AppDelegate类中添加以下代码,此函数将在应用启动后调用以注册推送通知。
// UNUserNotificationCenterDelegate and PKPushRegistryDelegate are required for APNs and push kit call backs please add this delegate to your AppDelegate file
@interface AppDelegate () <UNUserNotificationCenterDelegate, PKPushRegistryDelegate>
@end
// didFinishLaunchingWithOptions method of your app
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// checks wheather app version is updated/changed then makes server call setting VERSION_CODE
[ALRegisterUserClientService isAppUpdated];
// Register APNs and Push kit
[self registerForNotification];
// Register for Applozic notification tap actions and network change notifications
ALAppLocalNotifications *localNotification = [ALAppLocalNotifications appLocalNotificationHandler];
[localNotification dataConnectionNotificationHandler];
[[ALAudioVideoCallHandler shared] dataConnectionNotificationHandler];
// Override point for customization after application launch.
NSLog(@"launchOptions: %@", launchOptions);
if (launchOptions != nil) {
NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil) {
NSLog(@"Launched from push notification: %@", dictionary);
ALPushNotificationService *pushNotificationService = [[ALPushNotificationService alloc] init];
BOOL applozicProcessed = [pushNotificationService processPushNotification:dictionary updateUI:[NSNumber numberWithInt:APP_STATE_INACTIVE]];
//IF not a appplozic notification, process it
if (!applozicProcessed) {
//Note: notification for app
}
}
}
return YES;
}
// Register APNs and Pushkit
-(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 );
}
}];
}
向applozic服务器发送APNs和VOIP设备令牌
如果Appdelegate文件中已经存在以下方法,则可以复制粘贴以下方法的代码。
// 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) {
}];
}
接收推送通知
一旦您的应用接收到了通知,传递给Applozic处理器进行聊天通知处理。
// UNUserNotificationCenter delegates for chat
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification*)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
ALPushNotificationService *pushNotificationService = [[ALPushNotificationService
alloc] init];
NSDictionary *userInfo = notification.request.content.userInfo;
NSLog(@"APNS willPresentNotification for userInfo: %@", userInfo);
if ([pushNotificationService isApplozicNotification:userInfo]) {
[pushNotificationService notificationArrivedToApplication:[UIApplication sharedApplication] withDictionary:userInfo];
completionHandler(UNNotificationPresentationOptionNone);
return;
}
completionHandler(UNNotificationPresentationOptionAlert|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(nonnull UNNotificationResponse* )response withCompletionHandler:(nonnull void (^)(void))completionHandler {
ALPushNotificationService *pushNotificationService = [[ALPushNotificationService
alloc] init];
NSDictionary *userInfo = response.notification.request.content.userInfo;
NSLog(@"APNS didReceiveNotificationResponse for userInfo: %@", userInfo);
if ([pushNotificationService isApplozicNotification:userInfo]) {
[pushNotificationService notificationArrivedToApplication:[UIApplication sharedApplication] withDictionary:userInfo];
completionHandler();
return;
}
completionHandler();
}
-(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();
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
[[ALDBHandler sharedInstance] saveContext];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
NSLog(@"APP_ENTER_IN_FOREGROUND");
[application setApplicationIconBadgeNumber:0];
}
注意:如果没有设置推送通知,通话将无法工作,因为通话通知需要VOIP通知。请确保 QPushButton 推送通知已正确设置。
许可证
ApplozicAudioVideo遵循BSD 3-Clause许可证。更多信息请参阅LICENSE文件。