容聯(lián): IM+短信驗證+語音驗證碼....功能
容聯(lián)iOS開發(fā)指南
http://www.yuntongxun.com/api/im/iosWiki#point_box
1圆裕、iOS集成指南
1.1柳恐、導入sdk
開發(fā)者集成云通訊sdk,需要:
(1)先下載sdk,解壓之后目錄如圖所示例:
Yuntx_IMLib_V5.0.1r.a庫是靜態(tài)庫玫霎,Manager文件夾是主調(diào)函數(shù)聲明鸽斟,Delegate文件夾是回調(diào)函數(shù)聲明酗捌。
(2)然后導入sdk呢诬。將解壓后的文件夾(Yuntx_IMLib_SDK)拖入您的工程中,并勾選上Destination,如圖所示:
點擊finish胖缤,完成SDK添加尚镰,工程目錄如下圖所示:
注意:由于iOS編譯的特殊性,靜態(tài)庫中包含i386哪廓、x86_64狗唉、armv7、arm64平臺涡真,導致SDK的靜態(tài)庫(.a文件)會比較大分俯,但您實際集成編譯出ipa后,只會增加2MB左右哆料。
1.2缸剪、設(shè)置工程屬性
向Build Phases -> Link Binary With Libraries 中添加系統(tǒng)依賴庫,操作步驟如下所示:
按照上圖,點擊加號后剧劝,顯示下圖:在搜索框中輸入需要的依賴庫名稱橄登,如添加sqlite庫抓歼,按圖步驟讥此,點擊Add添加依賴庫成功
SDK需要添加系統(tǒng)依賴庫如下:
libicucore.dylib
libsqlite3.dylib
libz.dylib
CoreTelephony.framework
MediaPlayer.framework
CFNetwork.framework
SystemConfiguration.framework MobileCoreServices.framework
AudioToolbox.framework
CoreGraphics.framework
AVFoundation.framework
添加完依賴庫之后,第一步即完成谣妻,可以進行下一步了萄喳。
編譯設(shè)置:
因為SDK采用的是C代碼編寫,所以需要應(yīng)用設(shè)置混編設(shè)置:
1蹋半、如圖選擇stdlibc++模式編譯
2他巨、在第一次調(diào)用的地方,如demo中减江,更改AppDelegate.m文件的后綴為.mm如果不設(shè)置這兩項染突,編譯時出現(xiàn)std::錯誤。
2辈灼、開發(fā)指南
2.1份企、請求回調(diào)和通知回調(diào)
SDK中和服務(wù)端的交互采取異步回調(diào)方法,有兩種異步回調(diào)方法巡莹,一種是請求回調(diào)方法司志,一種是通知回調(diào)方法甜紫,詳細介紹如下:
(1)請求回調(diào)方法:即由用戶主動發(fā)出一個操作請求,請求的結(jié)果在回調(diào)中返回骂远。具體說就是在調(diào)用sdk的方法時囚霸,sdk的方法參數(shù)中有回調(diào)方法,請求的結(jié)果直接在參數(shù)的回調(diào)方法中處理激才。例如發(fā)送消息的方法拓型,包含獲知消息是否發(fā)送成功的回調(diào),此方法就是請求回調(diào)方法贸营。
(2)通知回調(diào)方法:通知回調(diào)是指由云通訊服務(wù)端主動給客戶端發(fā)送的信令或業(yè)務(wù)消息吨述,如接收消息,就是由服務(wù)端通知應(yīng)用來收消息钞脂,此方法就是通知回調(diào)方法揣云。
2.2初始化、登陸及登出
? 在程序入口初始化SDK并設(shè)置代理
//設(shè)置回調(diào)代理
[ECDevice sharedInstance].delegate = [DeviceDelegateHelper sharedInstance];```
代理類示例:
DeviceDelegateHelper.h文件
@interface DeviceDelegateHelper : NSObject <ECDeviceDelegate>
/** *@brief 獲取DeviceDelegateHelper單例句柄 /
+(DeviceDelegateHelper)sharedInstance;
@end ```
DeviceDelegateHelper.m文件
@implementation DeviceDelegateHelper
+(DeviceDelegateHelper*)sharedInstance{
static DeviceDelegateHelper *devicedelegatehelper;
static dispatch_once_t devicedelegatehelperonce;
dispatch_once(&devicedelegatehelperonce, ^{
devicedelegatehelper = [[DeviceDelegateHelper alloc] init];
});
return devicedelegatehelper;
}
/**
@brief 連接狀態(tài)接口
@discussion 監(jiān)聽與服務(wù)器的連接狀態(tài) V5.0版本接口
@param state 連接的狀態(tài)
@param error 錯誤原因值
*/
-(void)onConnectState:(ECConnectState)state failed:(ECError*)error{
switch (state) {
case State_ConnectSuccess:
//連接成功 break;
case State_Connecting:
//連接中; break;
case State_ConnectFailed:
//與服務(wù)器斷開連接break;
default: break;
}
}
/**
@brief 個人信息版本號
@param version服務(wù)器上的個人信息版本號
*/
-(void)onServicePersonVersion:(unsigned long long)version{
}
/**
@brief 接收即時消息代理函數(shù)
@param message 接收的消息
*/
-(void)onReceiveMessage:(ECMessage*)message{
}
/**
@brief 離線消息數(shù)
@param count 消息數(shù)
*/
-(void) onOfflineMessageCount:(NSUInteger)count{
}
/**
@brief 需要獲取的消息數(shù)
@return 消息數(shù) -1:全部獲取 0:不獲取
*/
-(NSInteger) onGetOfflineMessage{
}
/**
@brief 接收離線消息代理函數(shù)
@param message 接收的消息
*/
-(void) onReceiveOfflineMessage:(ECMessage*)message{
}
/**
@brief 離線消息接收是否完成
@param isCompletion YES:拉取完成 NO:拉取未完成(拉取消息失敗)
*/
-(void) onReceiveOfflineCompletion:(BOOL)isCompletion{
}
/**
@brief 客戶端錄音振幅代理函數(shù)
@param amplitude 錄音振幅
*/
-(void)onRecordingAmplitude:(double) amplitude{
}
/**
@brief 接收群組相關(guān)消息
@discussion 參數(shù)要根據(jù)消息的類型冰啃,轉(zhuǎn)成相關(guān)的消息類邓夕; 解散群組、收到邀請阎毅、申請加入焚刚、退出群組、有人加入扇调、移除成員等消息
@param groupMsg 群組消息
*/
-(void)onReceiveGroupNoticeMessage:(ECGroupNoticeMessage *)groupMsg{}
@end ```
###? 登錄—具體代碼如下:
//默認模式矿咕、只對AppKey、AppToken和userName鑒權(quán)
ECLoginInfo * loginInfo = [[ECLoginInfo alloc] init];
loginInfo.username = @"用戶名";//用戶登錄app的用戶id即可狼钮。
loginInfo.appKey = @"appid";
loginInfo.appToken = @"apptoken";
loginInfo.authType = LoginAuthType_NormalAuth;//默認方式登錄
loginInfo.mode = LoginMode_InputPassword;
[[ECDevice sharedInstance] login:loginInfo completion:^(ECError *error){
if (error.errorCode == ECErrorType_NoError) {
//登錄成功
}else{
//登錄失敗 }
}];
//密碼模式碳柱、對AppKey、userName和userPassword鑒權(quán)
ECLoginInfo * loginInfo = [[ECLoginInfo alloc] init];
loginInfo.username = @"用戶名";
loginInfo.appKey = @"appid";
loginInfo. userPassword= @"用戶密碼";
loginInfo.authType = LoginAuthType_PasswordAuth;//密碼方式登錄
loginInfo.mode = LoginMode_InputPassword;
[[ECDevice sharedInstance] login:loginInfo completion:^(ECError *error){
if (error.errorCode == ECErrorType_NoError) {
//登錄成功 }
else
{ //登錄失敗 }
}];
###? 登出
退出當前賬號熬芜,具體代碼如下:
[[ECDevice sharedInstance] logout:^(ECError *error) {
//登出結(jié)果
}];
2.3莲镣、單聊
###? 發(fā)送文本\圖片\附件—我們假設(shè)Tony給John發(fā)送文本消息,則代碼如下:
//發(fā)送圖片
ECImageMessageBody *messageBody = [[ECImageMessageBody alloc] initWithFile:@"圖片文件本地絕對路徑" displayName:@"文件名稱"];
//發(fā)送文件
ECFileMessageBody *messageBody = [[ECFileMessageBody alloc] initWithFile:@"文件本地絕對路徑" displayName:@"文件名稱"];
//發(fā)送文本
ECTextMessageBody *messageBody = [[ECTextMessageBody alloc] initWithText:@"你好涎拉,歡迎來到云通訊"];
初始化消息, 并指定發(fā)送的內(nèi)容
ECMessage *message = [[ECMessage alloc] initWithReceiver:@"John的賬號Id" body:messageBody];
// 取本地時間
NSDate* date = [NSDate dateWithTimeIntervalSinceNow:0];
NSTimeInterval tmp =[date timeIntervalSince1970]*1000;
message.timestamp = [NSString stringWithFormat:@"%lld", (long long)tmp];
[[ECDevice sharedInstance].messageManager sendMessage:message progress:nil completion:^(ECError *error, ECMessage *amessage) {
if (error.errorCode == ECErrorType_NoError) {
//發(fā)送成功
}else if(error.errorCode == ECErrorType_Have_Forbid || error.errorCode == ECErrorType_File_Have_Forbid) {
//您已被群組禁言
}else{
//發(fā)送失敗
}
}];
###? 發(fā)送語音—我們假設(shè)Tony給John發(fā)送語音消息瑞侮,則代碼如下:
//開始錄音
-(void)startRecord{
ECVoiceMessageBody * messageBody = [[ECVoiceMessageBody alloc] initWithFile:@"語音文件路徑.arm" displayName:@"文件名.arm"];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[[ECDevice sharedInstance].messageManager startVoiceRecording:messageBody error:^(ECError *error, ECVoiceMessageBody messageBody) {
if (error.errorCode == ECErrorType_RecordTimeOut) {
//錄音超時,立即發(fā)送鼓拧;應(yīng)用也可以選擇不發(fā)送
ECMessage message = [[ECMessage alloc] initWithReceiver:@"John的賬號Id" body:messageBody];
NSDate date = [NSDate dateWithTimeIntervalSinceNow:0];
NSTimeInterval tmp =[date timeIntervalSince1970]1000;
message.timestamp = [NSString stringWithFormat:@"%lld", (long long)tmp];
[[ECDevice sharedInstance].messageManager sendMessage:message progress:nil completion:^(ECError *error, ECMessage *amessage) {
if (error.errorCode == ECErrorType_NoError) {
//發(fā)送成功
}else if(error.errorCode == ECErrorType_Have_Forbid || error.errorCode == ECErrorType_File_Have_Forbid){
//您已被群組禁言
}else{
//發(fā)送失敗
}
}];
}
}];
}
//停止錄音
-(void)stopRecord {
[[ECDevice sharedInstance].messageManager stopVoiceRecording:^(ECError *error, ECVoiceMessageBody messageBody) {
if (error.errorCode == ECErrorType_NoError) {
ECMessage message = [[ECMessage alloc] initWithReceiver:@"John的賬號Id" body:messageBody]; NSDate date = [NSDate dateWithTimeIntervalSinceNow:0];
NSTimeInterval tmp =[date timeIntervalSince1970]1000;
message.timestamp = [NSString stringWithFormat:@"%lld", (long long)tmp];
[[ECDevice sharedInstance].messageManager sendMessage:message progress:nil completion:^(ECError *error, ECMessage *amessage) {
if (error.errorCode == ECErrorType_NoError) {
//發(fā)送成功
}else if(error.errorCode == ECErrorType_Have_Forbid || error.errorCode == ECErrorType_File_Have_Forbid){
//您已被群組禁言
}else{
//發(fā)送失敗
}
}];
} else if (error.errorCode == ECErrorType_RecordTimeTooShort) {
//錄音時間過短
}
}];
}
###? 接收消息—我們假設(shè)John收到Tony發(fā)送過來的消息半火,則代碼如下:
/**
@該通知回調(diào)接口在代理類里面
@brief 接收即時消息代理函數(shù)
@param message 接收的消息
/
-(void)onReceiveMessage:(ECMessage)message{
NSLog:(@"收到%@的消息,屬于%@會話", message.from, message.sessionId);
switch(message.messageBody.messageBodyType){
case MessageBodyType_Text:{
ECTextMessageBody *msgBody = (ECTextMessageBody *)message.messageBody;
NSLog(@"收到的是文本消息------%@,msgBody.text");
break;
}
case MessageBodyType_Voice:{
ECVoiceMessageBody *msgBody = (ECVoiceMessageBody *)message.messageBody;
NSLog(@"音頻文件remote路徑------%@",msgBody. remotePath);
break;
}
case MessageBodyType_Video:{
ECVideoMessageBody *msgBody = (ECVideoMessageBody *)message.messageBody;
NSLog(@"視頻文件remote路徑------%@",msgBody. remotePath);
break;
}
case MessageBodyType_Image:{
ECImageMessageBody *msgBody = (ECImageMessageBody *)message.messageBody;
NSLog(@"圖片文件remote路徑------%@",msgBody. remotePath);
NSLog(@"縮略圖片文件remote路徑------%@",msgBody. thumbnailRemotePath);
break;
}
case MessageBodyType_File:{
ECFileMessageBody *msgBody = (ECFileMessageBody *)message.messageBody;
NSLog(@"文件remote路徑------%@",msgBody. remotePath);
break;
}
default: break;
}
}
2.5、群組操作
###? 創(chuàng)建群組—我們假設(shè)Tony要創(chuàng)建一個名為"出彩中國人"具體代碼如下:
ECGroup * newgroup = [[ECGroup alloc] init];
newgroup.name = @"出彩中國人";
newgroup.declared = @"歡迎來到容聯(lián)云通訊";
[[ECDevice sharedInstance].messageManager createGroup:newgroup completion:^(ECError *error, ECGroup *group) {
if (error.errorCode == ECErrorType_NoError) {
NSLog(@"創(chuàng)建群組成功 群組ID:%@", group.groupId);
} else{
NSLog(@"創(chuàng)建群組失敗 errorCode:%d\r\nerrorDescription:%@", (int)error.errorCode,error.errorDescription);
}
}];```
? 主動加入—只要知道群組id季俩,就可以主動加入群組钮糖。
1、我們假設(shè)"出彩中國人"群組已經(jīng)有Tony和John兩位成員种玛,現(xiàn)在Smith要加入"出彩中國人"群組藐鹤,則代碼如下:
[[ECDevice sharedInstance].messageManager joinGroup:@"出彩中國人群組ID" reason:@"我要參加出彩中國人" completion:^(ECError *error, NSString *groupId) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
if (error.errorCode==ECErrorType_Have_Joined) {
NSLog(@"您已經(jīng)在群組%@", groupId);
}else if(error.errorCode==ECErrorType_NoError){
if(strongSelf.applyGroup.mode == ECGroupPermMode_DefaultJoin) {
NSLog(@"加入群組%@成功!", groupId);
}else{
NSLog(@"申請加入已發(fā)出瓤檐,請等待群主同意請求");
} }else{
NSLog(@"加入群組失敗 errorCode:%d\r\nerrorDescription:%@", (int)error.errorCode,error.errorDescription);
}
}];```
注意:如果群組"出彩中國人"是公開群組,則smith直接被允許加入娱节。如果群組"出彩中國人"是私有群組挠蛉,則smith加入需要群主Tony的的同意。Tony首先收到Smith加入的請求肄满,代碼如下:
/**
@該通知回調(diào)接口是代理類里面統(tǒng)一的關(guān)于群組的"群組通知回調(diào)接口"—onReceiveGroupNoticeMessage
@brief 接收群組相關(guān)消息
@discussion 參數(shù)要根據(jù)消息的類型谴古,轉(zhuǎn)成相關(guān)的消息類; 解散群組稠歉、收到邀請掰担、申請加入、退出群組怒炸、有人加入带饱、移除成員等消息
@param groupMsg 群組消息
*/
-(void)onReceiveGroupNoticeMessage:(ECGroupNoticeMessage *)groupMsg{
if (groupMsg.messageType == ECGroupMessageType_Propose) {
ECProposerMsg * message = (ECProposerMsg *)groupMsg;
NSString *declared = @"";
if (message.declared.length>0) {
declared = [NSString stringWithFormat:@",理由:%@",message.declared];
}
NSLog(@"\"%@\" 昵稱:\"%@\" 申請加入討論組\"%@\"%@",message.proposer,message.nickName, message.groupId, declared);
}
}```
Tony同意Smith加入的請求,代碼如下:
/**
@brief 管理員驗證用戶申請加入群組
@param groupId 申請加入的群組id
@param memberId 申請加入的成員id
@param type 是否同意
@param completion 執(zhí)行結(jié)果回調(diào)block
*/
[[ECDevice sharedInstance].messageManager ackJoinGroupRequest:@"出彩中國人群組ID" member:@" Smith的賬號Id" ackType:EAckType_Agree completion:^(ECError *error, NSString *gorupId, NSString *memberId) {
if (error.errorCode == ECErrorType_NoError || error.errorCode == ECErrorType_Have_Joined) {
NSLog(@"加入群組");
}else{
NSLog(@"errorCode:%d\rerrorDescription:%@",(int)error.errorCode,error.errorDescription);
}
}];
Smith加入成功后阅羹,群組中成員Tony和John收到的通知回調(diào)方法代碼如下:
/**
@該通知回調(diào)接口是代理類里面統(tǒng)一的關(guān)于群組的"群組通知回調(diào)接口"—onReceiveGroupNoticeMessage
@brief 接收群組相關(guān)消息
@discussion 參數(shù)要根據(jù)消息的類型勺疼,轉(zhuǎn)成相關(guān)的消息類; 解散群組捏鱼、收到邀請执庐、申請加入、退出群組导梆、有人加入轨淌、移除成員等消息
@param groupMsg 群組消息
*/
-(void)onReceiveGroupNoticeMessage:(ECGroupNoticeMessage *)groupMsg{
if (groupMsg.messageType == ECGroupMessageType_ReplyJoin) {
ECReplyJoinGroupMsg *message = (ECReplyJoinGroupMsg *)groupMsg;
NSLog(@"討論組\"%@\"%@\"%@\"的加入申請",message.groupId,message.confirm==2?@"同意":@"拒絕", message.member);
}
} ```