跳到主要内容

实现首次通话

本教程旨在帮助开发者快速了解和掌握 CallPlus SDK(融云呼叫增强能力库)的基础集成流程与核心通话功能。CallPlus 是在 RTCLib 基础上封装的音视频呼叫功能 SDK,支持一对一、多人音视频通话的各种场景。通过本教程,您将完成服务开通、SDK 初始化、事件监听、连接服务、发起呼叫、接听通话和挂断等全流程操作。

房间人数上限

考虑移动设备的带宽(主要是在多路视频情况下),建议单次通话或房间内,视频不超过 16 人,纯音频不超过 32 人。超过此上限可能影响通话效果。


环境要求

  • Xcode 需要使用 Xcode 9.0 及以上的版本
  • 苹果设备的系统需要使用 iOS 10.0 及以上的版本
  • 需要真机设备运行测试相关音视频通话功能
  • 如果您打算通过 CocoaPods 集成 SDK,需要使用 CocoaPods 1.10.0 及以上的版本。这是因为 CallPlus SDK 使用 XCFramework,而 CocoaPods 是从 1.10.0 版本后才完整支持 XCFramework 的集成方式
提示

如需安装 CocoaPods 环境,请参照 安装 CocoaPods


准备工作

  1. 访问融云控制台,注册您的开发者账号。注册成功后,控制台自动在开发环境中为您创建一个应用。

  2. 在控制台的基本信息页,获取您的应用在开发环境的 AppKey。您可在基本信息页查看应用的信息,如 App Key、App Secret、所属数据中心(默认为北京)。 alt text 如您想自己创建应用,参考如何创建应用,并获取对应环境 App Key 和 App Secret

    提示

    每个应用均拥有两个不同的 App Key,分别对应开发环境与生产环境,且两个环境之间数据相互隔离。在您的应用正式上线前,建议切换到生产环境的 App Key,以便完成上线前全流程测试和最终发布。

服务开通

您在融云创建的应用默认不会启用音视频服务。在使用融云提供的任何音视频服务前,您需要前往控制台,为应用开通音视频服务。

具体步骤请参阅控制台文档开通音视频服务

提示
  • 服务开通、关闭等设置完成后 15 分钟后生效
  • 客户端配置文件更新最长 2 小时,您可以在服务生效后卸载重装来立刻获取最新配置

导入 SDK

融云支持通过 CocoaPods 添加远程依赖和将 CallPlus 的相关 XCFramework 本地库导入应用工程两种集成方式。

CocoaPods 导入

  1. 如果您的项目中没有 Podfile 文件,您需要打开终端并进入到项目的根目录,在终端中运行 pod init 命令,之后系统会自动创建一个默认的 Podfile 文件,在项目中的 Podfile 文件中添加如下内容:

    ruby
    pod 'RongCallPlusLib'
  2. 打开终端并进入到 Podfile 文件所在的目录,在终端中运行以下命令:

    shell
    pod install
    提示

    如果终端中出现找不到相关版本的报错,可先在终端中执行 pod repo update 命令,再执行 pod install 命令。

  3. 通过 Xcode 打开项目目录下的 xcworkspace 文件加载工程。

Framework 手动集成

  1. 您可以前往 融云官网 SDK 下载页面,将 CallPlus for iOS SDK 下载到本地。

  2. 使用 Xcode 打开您的工程,然后将下载下来的 SDK 手动拖入到您的项目中,所需的 SDK 如下:

    Framework
    • RongCallPlusLib.xcframework
    • RongRTCLib.xcframework
    • RongIMLibCore.xcframework
  3. 修改您的项目配置。在 GeneralFrameworks, Libraries, and Embedded Binaries 中,将手动导入的 CallPlus SDK 所有的 Framework 全部改为 Embed & Sign


工程配置

  1. 音视频通话需要用到摄像头和麦克风权限,请在工程的 Info.plist 中添加如下键值:
    • Privacy - Microphone Usage Description
    • Privacy - Camera Usage Description
  2. 请将工程中 TargetSigning & CapabilitiesBackground Modes 如下内容勾选:
    • Audio, AirPlay, and Picture in Picture
    • Remote notifications

导入头文件

在需要使用的业务层导入 CallPlus 头文件,即可使用 SDK 的方法来实现呼叫相关业务,示例如下:

Objective C
#import <RongCallPlusLib/RongCallPlusLib.h>

CallLib 是基于 IMLibCore 作为信令通道的,您须导入 IMLib SDK 的头文件:

Objective C
#import <RongIMLibCore/RongIMLibCore.h>

初始化 SDK

CallPlus 是基于 IMLibCore 作为信令通道的,您须调用 init 方法初始化 IMLib SDK。初始化前,您须在融云控制台中获取 App Key,并设置好 RCInitOption(初始化配置)。

RCInitOption 中封装了 areaCode(数据中心的区域码),naviServer(导航服务地址)、fileServer(文件服务地址)、statisticServer(数据统计服务地址)和 crashMonitorEnable(崩溃监控开关)。

如果您使用北京数据中心,则不需设置 RCInitOption,IMLib SDK 默认连接北京数据中心。

Objective C
NSString *appKey = @"Your_AppKey"; // example: bos9p5rlcm2ba
RCInitOption *initOption = nil;

[[RCCoreClient sharedCoreClient] initWithAppKey:appKey option:initOption];

如果您使用海外数据中心,则须传入海外数据中心对应的 AreaCode。

Objective C
NSString *appKey = @"Your_AppKey"; // example: bos9p5rlcm2ba
RCInitOption *initOption = [[RCInitOption alloc] init];
initOption.areaCode = RCAreaCodeSG; // 新加坡数据中心

[[RCCoreClient sharedCoreClient] initWithAppKey:appKey option:initOption];

通话事件处理

通过设置通话事件相关监听器,用户可接收其他用户的通话申请以及监听通话状态的变化。 CallPlus SDK 提供了 RCCallPlusEventDelegateRCCallPlusResultDelegate 两个代理来处理通话相关事件。

提示

为确保接收离线通话,请在初始化 SDK 后,连接 IM 融云服务器之前设置监听器。

监听通话状态变化

  1. 通过 RCCallPlusClient 单例对象设置 RCCallPlusEventDelegate 代理。

    Objective C
    [[RCCallPlusClient sharedInstance] setCallEventDelegate:self];
  2. 在代理对象中实现 RCCallPlusEventDelegate 的相关的方法即可监听通话状态变化。

    Objective C
    - (void)didReceivedCall:(RCCallPlusSession *)session extra:(nullable NSString *)extra {
    // 被呼叫端,通过该方法接收到通话
    }

监听接口调用结果

  1. 通过 RCCallPlusClient 单例对象设置 RCCallPlusResultDelegate 代理。
Objective C
// 设置结果回调代理
[[RCCallPlusClient sharedInstance] setCallResultDelegate:self];
  1. 在代理对象中实现 RCCallPlusResultDelegate 的相关的方法即可监听接口调用结果。
Objective C
// 开始通话回调
- (void)didStartCallResultCode:(RCCallPlusCode)code
callId:(nullable NSString *)callId
busylineUsers:(nullable NSArray<RCCallPlusUser *> *)busylineUsers {
if (code == RCCallPlusCode_Success) {
// 发起通话,本端回调
}
}

// 接受通话回调
- (void)didAcceptCallResultCode:(RCCallPlusCode)code callId:(NSString *)callId {

}

连接融云 IM 服务器

用户 Token 是与用户 ID 对应的身份验证令牌,是应用程序的用户在融云的唯一身份标识。音视频用户之间的信令传输依赖于融云的即时通信(IM)服务,与融云建立 IM 连接,连接时必须传入 Token。

在实际业务运行过程中,应用客户端需要通过应用的服务端调用 IM Server API 申请取得 Token。详见 Server API 文档 注册用户

在本教程中,为了快速体验和测试 SDK,我们将使用控制台「北极星」开发者工具箱,从 API 调试页面调用 获取 Token 接口,获取到 userId 为 1 的用户的 Token。提交后,可在返回正文中取得 Token 字符串。

  1. 为模拟用户通过融云 IM 服务器进行通话,您需要首先注册一个用户。在实际业务中,应用客户端通过应用服务端调用融云 IM Server API 获取 token。详见 Server API 文档注册用户。在本教程中,为了快速体验融云服务,您可在控制台「北极星」的 API 调试页面调用获取 Token 接口,获取到 userId 为 1 的用户的 Token。调用返回如下:
HTTP
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"code":200,"userId":"1","token":"gxld6GHx3t1eDxof1qtxxYrQcjkbhl1V@sgyu.cn.example.com;sgyu.cn.example.com"}
  1. 设置连接监听器来实时获取连接状态。您可以将连接状态通过 UI 反馈给用户(例如提示 "网络连接中断" 或 "已重新连接"),提高用户体验。建议在应用生命周期内,初始化 SDK 之后,连接 IM 之前设置 IM 连接状态监听器,并在不需要的时候移除监听器。
Objective C
@protocol RCConnectionStatusChangeDelegate <NSObject>

// 添加代理委托
[[RCCoreClient sharedCoreClient] addConnectionStatusChangeDelegate:self];

// IMLib 连接状态的监听器
- (void)onConnectionStatusChanged:(RCConnectionStatus)status {
// 如果您设置了 IMLib 连接监听之后,当 SDK 与融云服务器的连接状态发生变化时,会回调此方法
}

@end
  1. 调用 connectWithToken 方法,将 userId 为 1 的用户连接融云 IM 服务。注:IMLib SDK 有重连机制,因此一个应用生命周期内调用一次 connect 即可。
Objective C
[[RCCoreClient sharedCoreClient] connectWithToken:@"融云 token" dbOpened:^(RCDBErrorCode code) {
// 消息数据库打开,可以进入到主页面
} success:^(NSString *userId) {
// 连接成功
} error:^(RCConnectErrorCode errorCode) {
if (errorCode == RC_CONN_TOKEN_INCORRECT) {
// 从 APP 服务获取新 token,并重连
} else {
// 无法连接到 IM 服务器,请根据相应的错误码作出对应处理
}
}];

进行一对一通话

CallPlus SDK 提供了仅限两位用户通话的一对一通话类型 RCCallPlusSingleType。发起一对一类型通话时,只允许传入一个被叫用户 ID 即可发起通话,在被叫接听成功后才会建立通话。融云会在被叫接听成功后开始计时。

发起呼叫

版本说明

从 CallPlus 2.X 开始,新增 startCallWithUserIds:callType:mediaType:pushConfig:extra: 方法,支持在发起呼叫时通过配置推送属性自定义远程推送标题等属性。支持携带自定义数据。如不需要配置推送属性,可以使用 startCallWithUserIds:callType:mediaType:

使用 RCCallPlusClientstartCallWithUserIds:callType:mediaType:pushConfig:extra: 方法发起一对一通话。方法调用后,SDK 内部会以异步方式执行。在主叫与被叫端触发以下回调:

如果远端被叫用户接听通话,本地主叫用户将通过 RCCallPlusEventDelegatedidRemoteUserStateChanged:userId:reason:userStatus: 回调获取到该用户状态变更,其中 RCCallPlusSessionUserState 枚举为 RCCallPlusUserStateConnecting 时表示用户已经接听,正在连接中。

Objective C

/// 开始呼叫动作
- (void)startCallAction {
// 打开摄像头
[[RCCallPlusClient sharedInstance] startCamera];
// 设置本地视图
RCCallPlusVideoView *localView = [RCCallPlusVideoView new];
localView.userId = @"localUserId";
localView.frame = CGRectMake(100, 100, 100, 100);
[self.view addSubview:localView];
[[RCCallPlusClient sharedInstance] setVideoView:localView];
// 设置远端视图
RCCallPlusRemoteVideoView *remoteView = [RCCallPlusRemoteVideoView new];
remoteView.frame = CGRectMake(200, 100, 100, 100);
remoteView.userId = @"remoteUserId";
[self.view addSubview:remoteView];
[[RCCallPlusClient sharedInstance] setVideoView:remoteView];
/// 开始呼叫,并携带推送配置
RCCallPlusPushConfig *pushConfig = [[RCCallPlusPushConfig alloc] init];
pushConfig.disablePushTitle = NO;
[[RCCallPlusClient sharedInstance] startCallWithUserIds:@[@"remoteUserId"]
callType:RCCallPlusSingleType
mediaType:RCCallPlusAudioVideoMediaType
pushConfig:pushConfig
extra:@"extraString"];

}

/// 开始通话回调
/// @param code 状态码, 0:成功 非0:失败
/// @param callId 通话id
/// @param busylineUsers 忙线用户列表
- (void)didStartCallResultCode:(RCCallPlusCode)code
callId:(nullable NSString *)callId
busylineUsers:(nullable NSArray<RCCallPlusUser *> *)busylineUsers {
if (code == RCCallPlusCode_Success) {

}
}

接听

重要说明

非兼容性变更:从 CallPlus 2.X 开始,不再提供 CallPlus 1.X 的 didReceivedCall: 回调方法。请改为使用携带 extra 字段的 didReceivedCall:extra: 方法。

被呼叫端通过协议 RCCallPlusEventDelegatedidReceivedCall:extra: 方法接收通话,然后使用 acceptWithCallId: 方法接听来电。

Objective C
/// 接收到呼入会话通知
/// @param session 会话
- (void)didReceivedCall:(RCCallPlusSession *)session {
// 接收到来电,记录 session
self.callSession = session;
// 判断通话类型决定是否开启摄像头并渲染视图
if (session.mediaType == RCCallPlusAudioVideoMediaType) {
[[RCCallPlusClient sharedInstance] startCamera];

// 被叫端设置本地视图
RCCallPlusVideoView *localView = [RCCallPlusVideoView new];
localView.userId = @"localUserId";
localView.frame = CGRectMake(100, 100, 100, 100);
[self.view addSubview:localView];
[[RCCallPlusClient sharedInstance] setVideoView:localView];

// 被叫端设置远端视图
RCCallPlusRemoteVideoView *remoteView = [RCCallPlusRemoteVideoView new];
remoteView.frame = CGRectMake(200, 100, 100, 100);
remoteView.userId = @"remoteUserId";
[self.view addSubview:remoteView];
[[RCCallPlusClient sharedInstance] setVideoView:remoteView];
}
}

/// 接听动作
- (void)acceptAction {
[[RCCallPlusClient sharedInstance] acceptWithCallId:self.callSession.callId];
}

/// 接受通话回调
/// @param code 状态码, 0:成功 非0:失败
/// @param callId 通话id
- (void)didAcceptCallResultCode:(RCCallPlusCode)code callId:(NSString *)callId {
NSLog(@"didAcceptCallResultCode:%@",@(code));
}

远程推送

应用未启动,被叫方通过远程通知接收来电。点击收到的推送通知后启动 App,在设置 RCCallPlusEventDelegate 代理并连接 IM 成功后,还是通过 didReceivedCall:extra: 接收到通话。


进行多人通话

CallPlus SDK 提供了支持多人呼叫的通话类型 RCCallPlusGroupType。发起多人通话与一对一通话使用相同的方法,但通话类型必须指定为 RCCallPlusGroupType

提示
  • 在实际项目中,我们建议您先按照一对一通话 实现完整的通话流程,再按照多人通话补充实现与一对一通话有差异的步骤。
  • 在一对一通话过程中可以邀请用户加入通话。一旦邀请成功,通话类型会自动转为多人通话。详见多人通话

发起多人通话

您可以使用 startCallWithUserIds:callType:mediaType: 方法发起多人通话,callType 参数必须为 RCCallPlusGroupType 多人通话类型。

Objective C
- (void)startGroupCall {
// 开始呼叫
[[RCCallPlusClient sharedInstance] startCallWithUserIds:@[@"userId1",@"userId2"]
callType:RCCallPlusGroupType
mediaType:RCCallPlusAudioVideoMediaType];
}

下一步

有关在您的应用程序中构建语音和视频通话功能的详细指南,请参阅完整的 一对一通话多人通话 文档。我们建议您先按照一对一通话实现完整的通话流程,再按照多人通话补充实现与一对一通话有差异的步骤。