产品概述
产品优势
应用场景




sudo gem install cocoapods
pod init
platform :ios, '8.0'target 'App' do# TRTC 精简版# 安装包体积增量最小,仅支持实时音视频(TRTC)和 直播播放器(TXLivePlayer)两项功能。pod 'TXLiteAVSDK_TRTC', :podspec => 'https://liteav.sdk.qcloud.com/pod/liteavsdkspec/TXLiteAVSDK_TRTC.podspec'# Add the IM SDKpod 'TXIMSDK_Plus_iOS'# pod 'TXIMSDK_Plus_iOS_XCFramework'# pod 'TXIMSDK_Plus_Swift_iOS_XCFramework'# If you need to add the Quic plugin, please uncomment the next line.# Note: This plugin must be used with the Objective-C edition or XCFramework edition of the IM SDK, and the plugin version number must match the IM SDK version number.# pod 'TXIMSDK_Plus_QuicPlugin'end
pod install
pod update
pod setuppod repo updaterm ~/Library/Caches/CocoaPods/search_index.json
Privacy - Microphone Usage Description, 同时填入麦克风使用目的提示语Privacy - Camera Usage Description,并填入摄像头使用目的提示语。



// 从即时通信 IM 控制台获取应用 SDKAppID。// 添加 V2TIMSDKListener 的事件监听器,self 是 id<V2TIMSDKListener> 的实现类,如果您不需要监听 IM SDK 的事件,这个步骤可以忽略。[[V2TIMManager sharedInstance] addIMSDKListener:self];// 初始化 IM SDK,调用这个接口后,可以立即调用登录接口。[[V2TIMManager sharedInstance] initSDK:sdkAppID config:config];// SDK 初始化后会抛出一些事件,例如连接状态、登录票据过期等- (void)onConnecting {NSLog(@"IM SDK 正在连接到腾讯云服务器");}- (void)onConnectSuccess {NSLog(@"IM SDK 已经成功连接到腾讯云服务器");}// 移除事件监听器// self 是 id<V2TIMSDKListener> 的实现类[[V2TIMManager sharedInstance] removeIMSDKListener:self];// 反初始化 SDK[[V2TIMManager sharedInstance] unInitSDK];
// 创建 TRTC SDK 实例(单例模式)self.trtcCloud = [TRTCCloud sharedInstance];// 设置事件监听器self.trtcCloud.delegate = self;// 来自 SDK 的各类事件通知(比如:错误码,警告码,音视频状态参数等)- (void)onError:(TXLiteAVError)errCode errMsg:(nullable NSString *)errMsg extInfo:(nullable NSDictionary *)extInfo {NSLog(@"%d: %@", errCode, errMsg);}- (void)onWarning:(TXLiteAVWarning)warningCode warningMsg:(nullable NSString *)warningMsg extInfo:(nullable NSDictionary *)extInfo {NSLog(@"%d: %@", warningCode, warningMsg);}// 移除事件监听器self.trtcCloud.delegate = nil;// 销毁 TRTC SDK 实例(单例模式)[TRTCCloud destroySharedIntance];
// 登录:userID 可自定义,userSig 参考步骤一生成获取[[V2TIMManager sharedInstance] login:userID userSig:userSig succ:^{NSLog(@"success");} fail:^(int code, NSString *desc) {// 如果返回以下错误码,表示使用 UserSig 已过期,请您使用新签发的 UserSig 进行再次登录。// 1. ERR_USER_SIG_EXPIRED(6206)// 2. ERR_SVR_ACCOUNT_USERSIG_EXPIRED(70001)// 注意:其他的错误码,请不要在这里调用登录接口,避免 IM SDK 登录进入死循环。NSLog(@"failure, code:%d, desc:%@", code, desc);}];
// 登出[[V2TIMManager sharedInstance] logout:^{NSLog(@"success");} fail:^(int code, NSString *desc) {NSLog(@"failure, code:%d, desc:%@", code, desc);}];
- (void)setupTRTC {// 设置视频编码参数,决定远端用户看到的画面质量TRTCVideoEncParam *encParam = [[TRTCVideoEncParam alloc] init];encParam.videoResolution = TRTCVideoResolution_960_540;encParam.videoFps = 15;encParam.videoBitrate = 850;encParam.resMode = TRTCVideoResolutionModePortrait;[self.trtcCloud setVideoEncoderParam:encParam];// 开启本地摄像头预览(可指定使用前置/后置摄像头进行视频采集)[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.previewView];}
// 构造自定义数据NSDictionary *dic = @{@"cmd": @"av_call",@"msg": @{// 指定通话类型(视频通话、语音通话)@"callType": @"videoCall",// 指定 TRTC 房间号(主叫端可随机生成)@"roomId": @"xxxRoomId",},};NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dicoptions:NSJSONWritingPrettyPrintederror:nil];if (jsonData) {NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];// 发送呼叫邀请信令[[V2TIMManager sharedInstance] invite:self.receiverId data:jsonString onlineUserOnly:false offlinePushInfo:self.offlinePushInfo timeout:self.timeout succ:^{// 发送呼叫邀请信令成功// 渲染呼叫页面,播放呼叫铃声} fail:^(int code, NSString *desc) {// 发送呼叫邀请信令失败// 提示呼叫失败,可以尝试重试}];}
offlinePushInfo,详情参见 离线推送消息。timeout,单位为秒,SDK 会进行超时检测,从而实现呼叫超时自动挂断。[[V2TIMManager sharedInstance] addSignalingListener:self];#pragma mark - V2TIMSignalingListener// 被叫用户收到呼叫请求, inviteID 为该条请求 ID,inviter 为主叫用户 ID- (void)onReceiveNewInvitation:(NSString *)inviteID inviter:(NSString *)inviter groupID:(NSString *)groupID inviteeList:(NSArray<NSString *> *)inviteeList data:(NSString *)data {if (data && ![data isEqualToString:@""]) {NSData *jsonData = [data dataUsingEncoding:NSUTF8StringEncoding];NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:jsonDataoptions:NSJSONReadingMutableContainerserror:nil];if (dictionary) {NSString *command = dictionary[@"cmd"];NSDictionary *msg = dictionary[@"msg"];if ([command isEqualToString:@"av_call"]) {NSString *callType = msg[@"callType"];NSString *roomId = msg[@"roomId"];// 渲染呼叫页面,播放呼叫铃声}}}}
if ([callType isEqualToString:@"videoCall"]) {// 设置视频编码参数,决定远端用户看到的画面质量TRTCVideoEncParam *encParam = [[TRTCVideoEncParam alloc] init];encParam.videoResolution = TRTCVideoResolution_960_540;encParam.videoFps = 15;encParam.videoBitrate = 850;encParam.resMode = TRTCVideoResolutionModePortrait;[self.trtcCloud setVideoEncoderParam:encParam];// 开启本地摄像头预览(可指定使用前置/后置摄像头进行视频采集)[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.previewView];}
[[V2TIMManager sharedInstance] cancel:inviteId data:data succ:^{// 取消呼叫请求成功// 销毁呼叫页面,停止播放呼叫铃声} fail:^(int code, NSString *desc) {// 取消呼叫请求失败// 提示取消失败,可以尝试重试}];
#pragma mark - V2TIMSignalingListener- (void)onInvitationCancelled:(NSString *)inviteID inviter:(NSString *)inviter data:(NSString *)data {// 销毁呼叫页面,停止播放呼叫铃声}
#pragma mark - V2TIMSignalingListener- (void)onInvitationTimeout:(NSString *)inviteID inviteeList:(NSArray<NSString *> *)inviteeList {// 提示呼叫超时,销毁呼叫页面,停止播放呼叫铃声}
[[V2TIMManager sharedInstance] accept:inviteId data:data succ:^{// 接听成功,渲染通话页面,停止播放呼叫铃声if ([callType isEqualToString:@"videoCall"]) {// 开始视频通话[self startVideoCall];} else {// 开始语音通话[self startAudioCall];}} fail:^(int code, NSString *desc) {// 接听失败,提示异常或重试}];
#pragma mark - V2TIMSignalingListener- (void)onInviteeAccepted:(NSString *)inviteID invitee:(NSString *)invitee data:(NSString *)data {if ([self.callType isEqualToString:@"videoCall"]) {// 开始视频通话[self startVideoCall];} else {// 开始语音通话[self startAudioCall];}}
- (void)startAudioCall {TRTCParams *params = [[TRTCParams alloc] init];// TRTC鉴权凭证, 在服务端生成params.sdkAppId = SDKAPPID;// TRTC应用标识, 在控制台获取params.userSig = USERSIG;// 以字符串房间号为例params.strRoomId = self.roomId;// 用户名, 建议和IM保持同步params.userId = self.userId;[self.trtcCloud startLocalAudio:TRTCAudioQualitySpeech];[self.trtcCloud enterRoom:params appScene:TRTCAppSceneAudioCall];}
TRTCAppSceneAudioCall,同时无需指定进房角色 TRTCRoleType。startLocalAudio 可同时设置音质参数,语音通话模式建议采用 TRTCAudioQualitySpeech。// 标记是否正在通话中@property (nonatomic, assign) BOOL isOnCalling;#pragma mark - TRTCCloudDelegate// 进房结果事件回调- (void)onEnterRoom:(NSInteger)result {if (result > 0) {// 进房成功,标识正在通话中self.isOnCalling = YES;} else {// 进房失败,提示通话异常self.isOnCalling = NO;}}
- (void)startVideoCall {TRTCParams *params = [[TRTCParams alloc] init];// TRTC鉴权凭证, 在服务端生成params.sdkAppId = SDKAPPID;// TRTC应用标识, 在控制台获取params.userSig = USERSIG;// 以字符串房间号为例params.strRoomId = self.roomId;// 用户名, 建议和IM保持同步params.userId = self.userId;[self.trtcCloud startLocalAudio:TRTCAudioQualitySpeech];[self.trtcCloud enterRoom:params appScene:TRTCAppSceneVideoCall];}
TRTCAppSceneVideoCall,同时无需指定进房角色 TRTCRoleType。startLocalAudio 可同时设置音质参数,视频通话模式建议采用 TRTCAudioQualitySpeech。startRemoteView 拉取远端视频流渲染播放。// 标记是否正在通话中@property (nonatomic, assign) BOOL isOnCalling;#pragma mark - TRTCCloudDelegate// 进房结果事件回调- (void)onEnterRoom:(NSInteger)result {if (result > 0) {// 进房成功,标识正在通话中self.isOnCalling = YES;} else {// 进房失败,提示通话异常self.isOnCalling = NO;}}// 拉取远端视频流- (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {// 远端用户发布/取消了主路视频画面if (available) {// 订阅远端用户的视频流,并绑定视频渲染控件[self.trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig view:self.previewView];} else {// 停止订阅远端用户的视频流,并释放渲染控件[self.trtcCloud stopRemoteView:userId streamType:TRTCVideoStreamTypeBig];}}
NSDictionary *dic = @{@"cmd": @"av_call",@"msg": @{// 指定通话类型(视频通话、语音通话)@"callType": @"videoCall",// 指定拒接类型(主动拒接、忙线拒接)@"reason": @"active",},};NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dicoptions:NSJSONWritingPrettyPrintederror:nil];if (jsonData) {NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];[[V2TIMManager sharedInstance] reject:self.inviteId data:jsonString succ:^{// 拒接成功,销毁呼叫页面,停止播放呼叫铃声} fail:^(int code, NSString *desc) {// 拒接失败,提示异常或重试}];}
#pragma mark - V2TIMSignalingListener- (void)onInviteeRejected:(NSString *)inviteID invitee:(NSString *)invitee data:(NSString *)data {if (data && ![data isEqualToString:@""]) {NSData *jsonData = [data dataUsingEncoding:NSUTF8StringEncoding];NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:jsonDataoptions:NSJSONReadingMutableContainerserror:nil];if (dictionary) {NSString *command = dictionary[@"cmd"];NSDictionary *msg = dictionary[@"msg"];if ([command isEqualToString:@"av_call"]) {NSString *reason = msg[@"reason"];if ([reason isEqualToString:@"active"]) {// 提示对方拒绝接听} else if ([reason isEqualToString:@"busy"]) {// 提示对方忙线中}// 销毁呼叫页面,停止播放呼叫铃声}}}}
- (void)onReceiveNewInvitation:(NSString *)inviteID inviter:(NSString *)inviter groupID:(NSString *)groupID inviteeList:(NSArray<NSString *> *)inviteeList data:(NSString *)data {if (data && ![data isEqualToString:@""]) {NSData *jsonData = [data dataUsingEncoding:NSUTF8StringEncoding];NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:jsonDataoptions:NSJSONReadingMutableContainerserror:nil];if (dictionary) {NSString *command = dictionary[@"cmd"];NSDictionary *msg = dictionary[@"msg"];if ([command isEqualToString:@"av_call"] && self.isOnCalling) {NSDictionary *dic = @{@"cmd": @"av_call",@"msg": @{// 指定通话类型(视频通话、语音通话)@"callType": @"videoCall",// 指定拒接类型(主动拒接、忙线拒接)@"reason": @"busy",},};NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dicoptions:NSJSONWritingPrettyPrintederror:nil];if (jsonData) {NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];// 本地正在通话中,发送忙线拒接信令[[V2TIMManager sharedInstance] reject:inviteID data:jsonString succ:^{// 忙线拒接成功} fail:^(int code, NSString *desc) {// 忙线拒接失败}];}}}}}
- (void)hangup {[self.trtcCloud stopLocalAudio];[self.trtcCloud stopLocalPreview];[self.trtcCloud exitRoom];}#pragma mark - TRTCCloudDelegate- (void)onExitRoom:(NSInteger)reason {// 已成功退出房间并挂断通话self.isOnCalling = NO;}
#pragma mark - TRTCCloudDelegate- (void)onRemoteUserLeaveRoom:(NSString *)userId reason:(NSInteger)reason {[self hangup];}- (void)onExitRoom:(NSInteger)reason {// 已成功退出房间并挂断通话self.isOnCalling = NO;}
// 打开麦克风[self.trtcCloud muteLocalAudio:NO];// 关闭麦克风[self.trtcCloud muteLocalAudio:YES];
// 打开扬声器[self.trtcCloud muteAllRemoteAudio:NO];// 关闭扬声器[self.trtcCloud muteAllRemoteAudio:YES];
// 打开摄像头, 指定前置或后置摄像头及渲染控件[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.previewView];// 关闭摄像头[self.trtcCloud stopLocalPreview];
// 切换听筒[[self.trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteEarpiece];// 切换免提[[self.trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteSpeakerphone];
// 判断当前是否为前置摄像头BOOL isFrontCamera = [[self.trtcCloud getDeviceManager] isFrontCamera];// 切换前置或后置摄像头, true: 切换为前置; false: 切换为后置[[self.trtcCloud getDeviceManager] switchCamera:!isFrontCamera];
#pragma mark - TRTCCloudDelegate- (void)onNetworkQuality:(TRTCQualityInfo *)localQuality remoteQuality:(NSArray<TRTCQualityInfo *> *)remoteQuality {if (remoteQuality.count > 0) {switch(remoteQuality[0].quality) {case TRTCQuality_Excellent:NSLog(@"对方网络非常好");break;case TRTCQuality_Good:NSLog(@"对方网络比较好");break;case TRTCQuality_Poor:NSLog(@"对方网络一般");break;case TRTCQuality_Bad:NSLog(@"对方网络较差");break;case TRTCQuality_Vbad:NSLog(@"对方网络很差");break;case TRTCQuality_Down:NSLog(@"对方网络极差");break;default:NSLog(@"未定义");break;}}}
localQuality 代表本地用户网络质量评估结果,其 userId 字段为空。remoteQuality 代表远端用户网络质量评估结果,其结果受远端和本地共同影响。// 开始通话时间@property (nonatomic, assign) NSTimeInterval callStartTime;// 结束通话时间@property (nonatomic, assign) NSTimeInterval callFinishTime;// 通话持续时长(秒)@property (nonatomic, assign) NSInteger callDuration;// 远端用户进房回调- (void)onRemoteUserEnterRoom:(NSString *)userId {self.callStartTime = [[NSDate date] timeIntervalSince1970];}// 本地用户退房回调- (void)onExitRoom:(NSInteger)reason {self.callFinishTime = [[NSDate date] timeIntervalSince1970];self.callDuration = (NSInteger)(self.callFinishTime - self.callStartTime);}
NSString *beautyConfigPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];beautyConfigPath = [beautyConfigPath stringByAppendingPathComponent:@"beauty_config.json"];NSFileManager *localFileManager=[[NSFileManager alloc] init];BOOL isDir = YES;NSDictionary * beautyConfigJson = @{};if ([localFileManager fileExistsAtPath:beautyConfigPath isDirectory:&isDir] && !isDir) {NSString *beautyConfigJsonStr = [NSString stringWithContentsOfFile:beautyConfigPath encoding:NSUTF8StringEncoding error:nil];NSError *jsonError;NSData *objectData = [beautyConfigJsonStr dataUsingEncoding:NSUTF8StringEncoding];beautyConfigJson = [NSJSONSerialization JSONObjectWithData:objectDataoptions:NSJSONReadingMutableContainerserror:&jsonError];}NSDictionary *assetsDict = @{@"core_name":@"LightCore.bundle",@"root_path":[[NSBundle mainBundle] bundlePath],@"tnn_"@"beauty_config":beautyConfigJson};// 初始化SDK:width和height分别是texture的宽高self.xMagicKit = [[XMagic alloc] initWithRenderSize:CGSizeMake(width,height) assetsDict:assetsDict];
// TRTC SDK 设置第三方美颜的视频数据回调[self.trtcCloud setLocalVideoProcessDelegete:self pixelFormat:TRTCVideoPixelFormat_Texture_2D bufferType:TRTCVideoBufferType_Texture];#pragma mark - TRTCVideoFrameDelegate// 构造 YTProcessInput 传入到 SDK 内做渲染处理- (uint32_t)onProcessVideoFrame:(TRTCVideoFrame *_Nonnull)srcFrame dstFrame:(TRTCVideoFrame *_Nonnull)dstFrame {if (!self.xMagicKit) {[self buildBeautySDK:srcFrame.width and:srcFrame.height texture:srcFrame.textureId];//初始化XMagic SDKself.heightF = srcFrame.height;self.widthF = srcFrame.width;}if(self.xMagicKit!=nil && (self.heightF!=srcFrame.height || self.widthF!=srcFrame.width)){self.heightF = srcFrame.height;self.widthF = srcFrame.width;[self.xMagicKit setRenderSize:CGSizeMake(srcFrame.width, srcFrame.height)];}YTProcessInput *input = [[YTProcessInput alloc] init];input.textureData = [[YTTextureData alloc] init];input.textureData.texture = srcFrame.textureId;input.textureData.textureWidth = srcFrame.width;input.textureData.textureHeight = srcFrame.height;input.dataType = kYTTextureData;YTProcessOutput *output = [self.xMagicKit process:input withOrigin:YtLightImageOriginTopLeft withOrientation:YtLightCameraRotation0];dstFrame.textureId = output.textureData.texture;return 0;}
// 更新本地预览画面渲染控件[self.trtcCloud updateLocalView:self.previewView];// 更新远端用户视频渲染控件[self.trtcCloud updateRemoteView:self.previewView streamType:TRTCVideoStreamTypeBig forUser:self.userId];
streamType 仅支持 TRTCVideoStreamTypeBig 和 TRTCVideoStreamTypeSub。NSDictionary *dic = @{@"cmd": @"av_call",@"msg": @{// 指定通话类型(视频通话、语音通话)@"callType": @"videoCall",// 指定 TRTC 房间号(主叫端可随机生成)@"roomId": @"xxxRoomId",},};NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];V2TIMOfflinePushInfo *pushInfo = [[V2TIMOfflinePushInfo alloc] init];pushInfo.title = self.nickName;pushInfo.desc = @"You have a new call invitation";NSDictionary *ext = @{@"entity" : @{@"action" : @1,@"content" : jsonString,@"sender" : self.senderId,@"nickname" : self.nickName,@"faceUrl" : faceUrl,}};NSData *data = [NSJSONSerialization dataWithJSONObject:ext options:NSJSONWritingPrettyPrinted error:nil];pushInfo.ext = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];pushInfo.iOSSound = @"phone_ringing.mp3";// 以下是兼容安卓的字段,需要填写pushInfo.AndroidOPPOChannelID = @"tuikit";pushInfo.AndroidSound = @"phone_ringing";pushInfo.AndroidHuaWeiCategory = @"IM";pushInfo.AndroidVIVOCategory = @"IM";[[V2TIMManager sharedInstance] invite:@"receiverId" data:jsonString onlineUserOnly:false offlinePushInfo:pushInfo timeout:self.timeout succ:^{// 发送呼叫邀请信令成功} fail:^(int code, NSString *desc) {// 发送呼叫邀请信令失败}];
AppDelegate -> didReceiveRemoteNotification 系统回调获取到 ext 字段,然后根据 ext 字段内容跳转到指定的 UI 界面。// 启动 APP 后会收到以下回调- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfofetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {// 解析推送扩展字段if ([userInfo[@"ext"]) {// 跳转到指定的 UI 界面}}
枚举 | 取值 | 描述 |
ERR_TRTC_INVALID_USER_SIG | -3320 | 进房参数 userSig 不正确,请检查 TRTCParams.userSig 是否为空。 |
ERR_TRTC_USER_SIG_CHECK_FAILED | -100018 | UserSig 校验失败,请检查参数 TRTCParams.userSig 是否填写正确或已经过期。 |
枚举 | 取值 | 描述 |
ERR_TRTC_CONNECT_SERVER_TIMEOUT | -3308 | 请求进房超时,请检查是否断网或者是否开启 VPN,您也可以切换4G进行测试。 |
ERR_TRTC_INVALID_SDK_APPID | -3317 | 进房参数 sdkAppId 错误,请检查 TRTCParams.sdkAppId 是否为空 |
ERR_TRTC_INVALID_ROOM_ID | -3318 | 进房参数 roomId 错误,请检查 TRTCParams.roomId 或 TRTCParams.strRoomId 是否为空,注意 roomId 和 strRoomId 不可混用。 |
ERR_TRTC_INVALID_USER_ID | -3319 | 进房参数 userId 不正确,请检查 TRTCParams.userId 是否为空。 |
ERR_TRTC_ENTER_ROOM_REFUSED | -3340 | 进房请求被拒绝,请检查是否连续调用 enterRoom 进入相同 Id 的房间。 |
枚举 | 取值 | 描述 |
ERR_CAMERA_START_FAIL | -1301 | 打开摄像头失败,例如在 Windows 或 Mac 设备,摄像头的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序。 |
ERR_MIC_START_FAIL | -1302 | 打开麦克风失败,例如在 Windows 或 Mac 设备,麦克风的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序。 |
ERR_CAMERA_NOT_AUTHORIZED | -1314 | 摄像头设备未授权,通常在移动设备出现,可能是权限被用户拒绝了。 |
ERR_MIC_NOT_AUTHORIZED | -1317 | 麦克风设备未授权,通常在移动设备出现,可能是权限被用户拒绝了。 |
ERR_CAMERA_OCCUPY | -1316 | 摄像头正在被占用中,可尝试打开其他摄像头。 |
ERR_MIC_OCCUPY | -1319 | 麦克风正在被占用中,例如移动设备正在通话时,打开麦克风会失败。 |
deviceToken 可能会失败,生产环境暂时没有发现这个问题,请切换到生产环境测试。- application:didRegisterForRemoteNotificationsWithDeviceToken: 回调返回的是发布环境的 token,此时 businessID 需要设置生产环境的 证书 ID。- application:didRegisterForRemoteNotificationsWithDeviceToken: 回调返回的是开发环境的 token,此时 businessID 需要设置开发环境的 证书 ID。V2TIMAPNSConfig *confg = [[V2TIMAPNSConfig alloc] init];/* 用户自己到苹果注册开发者证书,在开发者账号中下载并生成证书(p12 文件),将生成的 p12 文件传到腾讯证书管理控制台,控制台会自动生成一个证书 ID,将证书 ID 传入以下 busiId 参数中。*///推送证书 IDconfg.businessID = sdkBusiId;confg.token = self.deviceToken;[[V2TIMManager sharedInstance] setAPNS:confg succ:^{NSLog(@"%s, succ, %@", __func__, supportTPNS ? @"TPNS": @"APNS");} fail:^(int code, NSString *msg) {NSLog(@"%s, fail, %d, %@", __func__, code, msg);}];
文档反馈