sudo gem install cocoapods
pod init
platform :ios, '8.0'target 'App' do# TRTC Lite Version# The installation package has the minimum incremental size. It only supports two features of Real-Time Communication (TRTC) and TXLivePlayer for live streaming playback.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, and also enter a prompt specifying the purpose of microphone usePrivacy - Camera Usage Description, and enter a prompt specifying the purpose of camera use.
// Obtain the SDKAppID from the Instant Messaging (IM) console.// Add a V2TIMSDKListener event listener. The self is the implementation class of id<V2TIMSDKListener>. This step can be skipped if you do not need to listen for events from the IM SDK.[[V2TIMManager sharedInstance] addIMSDKListener:self];// Initialize the IM SDK. After calling this API, you can immediately call the log-in API.[[V2TIMManager sharedInstance] initSDK:sdkAppID config:config];// After the SDK is initialized, it will trigger various events, such as connection status and expiration of log-in credentials- (void)onConnecting {NSLog(@"The IM SDK is connecting to the Cloud Virtual Machine");}- (void)onConnectSuccess {NSLog(@"The IM SDK has successfully connected to the Cloud Virtual Machine");}// Remove event listener// The self is the implementation class of id<V2TIMSDKListener>[[V2TIMManager sharedInstance] removeIMSDKListener:self];// Deinitialize the SDK[[V2TIMManager sharedInstance] unInitSDK];
// Create TRTC SDK instance (single instance pattern)self.trtcCloud = [TRTCCloud sharedInstance];// Set event listenersself.trtcCloud.delegate = self;// Notifications from various SDK events (e.g., error codes, warning codes, audio and video status parameters, etc.)- (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);}// Remove event listenerself.trtcCloud.delegate = nil;// Destroy TRTC SDK instance (single instance pattern)[TRTCCloud destroySharedIntance];
// Log in: userID can be defined by the user and userSig can be generated as per step 1[[V2TIMManager sharedInstance] login:userID userSig:userSig succ:^{NSLog(@"success");} fail:^(int code, NSString *desc) {// The following error codes indicate an expired userSig, and you need to generate a new one for log-in again.// 1. ERR_USER_SIG_EXPIRED(6206).// 2. ERR_SVR_ACCOUNT_USERSIG_EXPIRED(70001).// Note: Do not call the log-in API in case of other error codes. Otherwise, the IM SDK may enter an infinite loop of log-in.NSLog(@"failure, code:%d, desc:%@", code, desc);}];
// Log out[[V2TIMManager sharedInstance] logout:^{NSLog(@"success");} fail:^(int code, NSString *desc) {NSLog(@"failure, code:%d, desc:%@", code, desc);}];
- (void)setupTRTC {// Set video encoding parameters to determine the picture quality seen by remote usersTRTCVideoEncParam *encParam = [[TRTCVideoEncParam alloc] init];encParam.videoResolution = TRTCVideoResolution_960_540;encParam.videoFps = 15;encParam.videoBitrate = 850;encParam.resMode = TRTCVideoResolutionModePortrait;[self.trtcCloud setVideoEncoderParam:encParam];// Enable local camera preview (you can specify to use the front/rear camera for video capture)[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.previewView];}
// Construct custom dataNSDictionary *dic = @{@"cmd": @"av_call",@"msg": @{// Specify the call type (video call, audio call)@"callType": @"videoCall",// Specify the TRTC room ID (caller can generate it randomly)@"roomId": @"xxxRoomId",},};NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dicoptions:NSJSONWritingPrettyPrintederror:nil];if (jsonData) {NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];// Send call invitation signaling[[V2TIMManager sharedInstance] invite:self.receiverId data:jsonString onlineUserOnly:false offlinePushInfo:self.offlinePushInfo timeout:self.timeout succ:^{// Successfully send call invitation signaling// Render call page, play call ringtone} fail:^(int code, NSString *desc) {// Failed to send call invitation signaling// Prompt call failure, you can try to retry}];}
offlinePushInfo
in the invitation signaling. For more details, see Offline Push Message.timeout
in the invitation signaling, in seconds. The SDK will perform timeout detection to realize auto hang up after call timeout.[[V2TIMManager sharedInstance] addSignalingListener:self];#pragma mark - V2TIMSignalingListener// Callee receives the call request. The inviteID is the request ID, and inviter is the caller 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"];// Render call page, play call ringtone}}}}
if ([callType isEqualToString:@"videoCall"]) {// Set video encoding parameters to determine the picture quality seen by remote usersTRTCVideoEncParam *encParam = [[TRTCVideoEncParam alloc] init];encParam.videoResolution = TRTCVideoResolution_960_540;encParam.videoFps = 15;encParam.videoBitrate = 850;encParam.resMode = TRTCVideoResolutionModePortrait;[self.trtcCloud setVideoEncoderParam:encParam];// Enable local camera preview (you can specify to use the front/rear camera for video capture)[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.previewView];}
[[V2TIMManager sharedInstance] cancel:inviteId data:data succ:^{// Successfully cancel the call request// Terminate the call page, and stop the call ringtone} fail:^(int code, NSString *desc) {// Failed to cancel call request// Prompt cancel failure, and you can retry}];
#pragma mark - V2TIMSignalingListener- (void)onInvitationCancelled:(NSString *)inviteID inviter:(NSString *)inviter data:(NSString *)data {// Terminate the call page, and stop the call ringtone}
#pragma mark - V2TIMSignalingListener- (void)onInvitationTimeout:(NSString *)inviteID inviteeList:(NSArray<NSString *> *)inviteeList {// Prompt call timeout. Terminate the call page, and stop the call ringtone}
[[V2TIMManager sharedInstance] accept:inviteId data:data succ:^{// Answer successfully, render the call page, and stop the call ringtoneif ([callType isEqualToString:@"videoCall"]) {// Start video call[self startVideoCall];} else {// Start audio call[self startAudioCall];}} fail:^(int code, NSString *desc) {// Answer failed, prompt for exception or retry}];
#pragma mark - V2TIMSignalingListener- (void)onInviteeAccepted:(NSString *)inviteID invitee:(NSString *)invitee data:(NSString *)data {if ([self.callType isEqualToString:@"videoCall"]) {// Start video call[self startVideoCall];} else {// Start audio call[self startAudioCall];}}
- (void)startAudioCall {TRTCParams *params = [[TRTCParams alloc] init];// TRTC authentication credential, generated on the serverparams.sdkAppId = SDKAPPID;// TRTC application ID, obtained from the consoleparams.userSig = USERSIG;// Take the room ID string as an exampleparams.strRoomId = self.roomId;// Username, it is recommended to stay sync with IMparams.userId = self.userId;[self.trtcCloud startLocalAudio:TRTCAudioQualitySpeech];[self.trtcCloud enterRoom:params appScene:TRTCAppSceneAudioCall];}
TRTCAppSceneAudioCall
, and there is no need to specify a room entry role TRTCRoleType
.startLocalAudio
allows you to set audio quality parameters at the same time. For audio call modes, it is recommended to select TRTCAudioQualitySpeech
.// Mark whether the call is in progress@property (nonatomic, assign) BOOL isOnCalling;#pragma mark - TRTCCloudDelegate// Event callback for the result of entering the room- (void)onEnterRoom:(NSInteger)result {if (result > 0) {// Room entry successful, indicates that the call is in progressself.isOnCalling = YES;} else {// Failed to enter the room, prompt for call exceptionself.isOnCalling = NO;}}
- (void)startVideoCall {TRTCParams *params = [[TRTCParams alloc] init];// TRTC authentication credential, generated on the serverparams.sdkAppId = SDKAPPID;// TRTC application ID, obtained from the consoleparams.userSig = USERSIG;// Take the room ID string as an exampleparams.strRoomId = self.roomId;// Username, it is recommended to stay sync with IMparams.userId = self.userId;[self.trtcCloud startLocalAudio:TRTCAudioQualitySpeech];[self.trtcCloud enterRoom:params appScene:TRTCAppSceneVideoCall];}
TRTCAppSceneVideoCall
, and there's no need to specify the room entry role TRTCRoleType
.startLocalAudio
allows you to set audio quality parameters at the same time. For video call modes, it is recommended to select TRTCAudioQualitySpeech
.startRemoteView
to pull and render the remote video stream.// Mark whether the call is in progress@property (nonatomic, assign) BOOL isOnCalling;#pragma mark - TRTCCloudDelegate// Event callback for the result of entering the room- (void)onEnterRoom:(NSInteger)result {if (result > 0) {// Room entry successful, indicates that the call is in progressself.isOnCalling = YES;} else {// Failed to enter the room, prompt for call exceptionself.isOnCalling = NO;}}// Pull remote video stream- (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {// The remote user publishes/unpublishes the primary videoif (available) {// Subscribe to the remote user's video stream and bind the video rendering control[self.trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig view:self.previewView];} else {// Unsubscribe to the remote user's video stream and release the rendering control[self.trtcCloud stopRemoteView:userId streamType:TRTCVideoStreamTypeBig];}}
NSDictionary *dic = @{@"cmd": @"av_call",@"msg": @{// Specify the call type (video call, audio call)@"callType": @"videoCall",// Specify rejection type (Proactive Rejection, Busy Line Rejection)@"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:^{// Rejection successful. Terminate the call page, and stop the call ringtone} fail:^(int code, NSString *desc) {// Rejection failed, prompt for exception or retry}];}
#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"]) {// Prompt that the other party rejects call} else if ([reason isEqualToString:@"busy"]) {// Prompt that the other party is busy}// Terminate the call page, and stop the call ringtone}}}}
- (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": @{// Specify the call type (video call, audio call)@"callType": @"videoCall",// Specify rejection type (Proactive Rejection, Busy Line Rejection)@"reason": @"busy",},};NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dicoptions:NSJSONWritingPrettyPrintederror:nil];if (jsonData) {NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];// Local call is in progress, and sends busy line rejection signal[[V2TIMManager sharedInstance] reject:inviteID data:jsonString succ:^{// Busy line rejection successful} fail:^(int code, NSString *desc) {// Busy line rejection failed}];}}}}}
reject
signaling for implementation, but it's important to distinguish them through the reason
field of the custom data
in the signaling.- (void)hangup {[self.trtcCloud stopLocalAudio];[self.trtcCloud stopLocalPreview];[self.trtcCloud exitRoom];}#pragma mark - TRTCCloudDelegate- (void)onExitRoom:(NSInteger)reason {// Successfully exited the room and hung up the callself.isOnCalling = NO;}
#pragma mark - TRTCCloudDelegate- (void)onRemoteUserLeaveRoom:(NSString *)userId reason:(NSInteger)reason {[self hangup];}- (void)onExitRoom:(NSInteger)reason {// Successfully exited the room and hung up the callself.isOnCalling = NO;}
// Turn the mic on[self.trtcCloud muteLocalAudio:NO];// Turn the mic off[self.trtcCloud muteLocalAudio:YES];
// Turn the speaker on[self.trtcCloud muteAllRemoteAudio:NO];// Turn the speaker off[self.trtcCloud muteAllRemoteAudio:YES];
// Turn the camera on, specifying front or rear camera and the rendering control[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.previewView];// Turn the camera off[self.trtcCloud stopLocalPreview];
// Switch to earpiece[[self.trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteEarpiece];// Switch to speakerphone[[self.trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteSpeakerphone];
// Determine if the current camera is front-facingBOOL isFrontCamera = [[self.trtcCloud getDeviceManager] isFrontCamera];// Switch between front and rear cameras, true: switch to front-facing; false: switch to rear-facing[[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(@"The other party's network is very good");break;case TRTCQuality_Good:NSLog(@"The other party's network is quite good");break;case TRTCQuality_Poor:NSLog(@"The other party's network is average");break;case TRTCQuality_Bad:NSLog(@"The other party's network is relatively poor");break;case TRTCQuality_Vbad:NSLog(@"The other party's network is very poor");break;case TRTCQuality_Down:NSLog(@"The other party's network is extremely poor");break;default:NSLog(@"Undefined ");break;}}}
localQuality
represents the local user network quality assessment result, and its userId field is empty.remoteQuality
represents the remote user network quality assessment result, which is influenced by factors on both the remote and local sides.// Start call time@property (nonatomic, assign) NSTimeInterval callStartTime;// End call time@property (nonatomic, assign) NSTimeInterval callFinishTime;// Call duration (seconds)@property (nonatomic, assign) NSInteger callDuration;// Callback for remote user entering room- (void)onRemoteUserEnterRoom:(NSString *)userId {self.callStartTime = [[NSDate date] timeIntervalSince1970];}// Callback for local user exiting room- (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};// Initialize SDK: Width and height are the width and height of the texture respectivelyself.xMagicKit = [[XMagic alloc] initWithRenderSize:CGSizeMake(width,height) assetsDict:assetsDict];
// Set the video data callback for third-party beauty features in the TRTC SDK[self.trtcCloud setLocalVideoProcessDelegete:self pixelFormat:TRTCVideoPixelFormat_Texture_2D bufferType:TRTCVideoBufferType_Texture];#pragma mark - TRTCVideoFrameDelegate// Construct the YTProcessInput and pass it into the SDK for rendering processing- (uint32_t)onProcessVideoFrame:(TRTCVideoFrame *_Nonnull)srcFrame dstFrame:(TRTCVideoFrame *_Nonnull)dstFrame {if (!self.xMagicKit) {[self buildBeautySDK:srcFrame.width and:srcFrame.height texture:srcFrame.textureId];// Initialize the XMagic SDK.self.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;}
// Update local preview screen rendering control[self.trtcCloud updateLocalView:self.previewView];// Update the remote user's video rendering control[self.trtcCloud updateRemoteView:self.previewView streamType:TRTCVideoStreamTypeBig forUser:self.userId];
streamType
only supports TRTCVideoStreamTypeBig
and TRTCVideoStreamTypeSub
.NSDictionary *dic = @{@"cmd": @"av_call",@"msg": @{// Specify the call type (video call, audio call)@"callType": @"videoCall",// Specify the TRTC room ID (caller can generate it randomly)@"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";// Below are fields compatible with Android, and need to be filled inpushInfo.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:^{// Successfully send call invitation signaling} fail:^(int code, NSString *desc) {// Failed to send call invitation signaling}];
ext
field in the AppDelegate -> didReceiveRemoteNotification
system callback, and then redirect to the specified UI interface based on the content of the ext
field.// After starting the APP, you will receive the following callbacks- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfofetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {// Parse push extension fieldsif ([userInfo[@"ext"]) {// Redirect to the specified UI interface}}
onError
callback. For details, see Error Code Table.Enumeration | Value | Description |
ERR_TRTC_INVALID_USER_SIG | -3320 | Room entry parameter userSig is incorrect. Check if TRTCParams.userSig is empty. |
ERR_TRTC_USER_SIG_CHECK_FAILED | -100018 | UserSig verification failed. Check if the parameter TRTCParams.userSig is filled in correctly or has expired. |
Enumeration | Value | Description |
ERR_TRTC_CONNECT_SERVER_TIMEOUT | -3308 | Room entry request timed out. Check if your internet connection is lost or if a VPN is enabled. You may also attempt to switch to 4G for testing. |
ERR_TRTC_INVALID_SDK_APPID | -3317 | Room entry parameter sdkAppId is incorrect. Check if TRTCParams.sdkAppId is empty |
ERR_TRTC_INVALID_ROOM_ID | -3318 | Room entry parameter roomId is incorrect.Check if TRTCParams.roomId or TRTCParams.strRoomId is empty. Nnote that roomId and strRoomId cannot be used interchangeably. |
ERR_TRTC_INVALID_USER_ID | -3319 | Room entry parameter userId is incorrect. Check if TRTCParams.userId is empty. |
ERR_TRTC_ENTER_ROOM_REFUSED | -3340 | Room entry request was denied. Check if enterRoom is called consecutively to enter rooms with the same ID. |
Enumeration | Value | Description |
ERR_CAMERA_START_FAIL | -1301 | Failed to enable the camera. For example, if there is an exception for the camera's configuration program (driver) on a Windows or Mac device, you should try disabling then re-enabling the device, restarting the machine, or updating the configuration program. |
ERR_MIC_START_FAIL | -1302 | Failed to open the mic. For example, if there is an exception for the camera's configuration program (driver) on a Windows or Mac device, you should try disabling then re-enabling the device, restarting the machine, or updating the configuration program. |
ERR_CAMERA_NOT_AUTHORIZED | -1314 | The device of camera is unauthorized. This typically occurs on mobile devices and may be due to the user having denied the permission. |
ERR_MIC_NOT_AUTHORIZED | -1317 | The device of mic is unauthorized. This typically occurs on mobile devices and may be due to the user having denied the permission. |
ERR_CAMERA_OCCUPY | -1316 | The camera is occupied. Try a different camera. |
ERR_MIC_OCCUPY | -1319 | The mic is occupied. This occurs when, for example, the user is currently having a call on the mobile device. |
deviceToken
from Apple may fail. This problem is not found in the production environment, you can switch to the production environment for testing.config
parameter of setAPNS API to nil
. This feature is supported starting from version 5.6.1200.- application:didRegisterForRemoteNotificationsWithDeviceToken:
callback will return a production environment token. At this time, the businessID needs to be set to the Certificate ID of the production environment.- application:didRegisterForRemoteNotificationsWithDeviceToken:
callback will return a development environment token. At this time, the businessID needs to be set to the Certificate ID of the development environment.V2TIMAPNSConfig *confg = [[V2TIMAPNSConfig alloc] init];/* You need to register a developer certificate with Apple, download and generate the certificate (p12 file) in the developer accounts, and upload the generated p12 file to the Certificate Management console. The console will automatically generate a certificate ID and pass it to the following busiId parameter.*/// Push certificate 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);}];
Was this page helpful?