1、单聊

✾ 发送文本\图片\附件 — 我们假设Tony给John发送文本消息,则代码如下:

//发送图片
/*
ECImageMessageBody *messageBody = [[ECImageMessageBody alloc] initWithFile:@"图片文件本地绝对路径" 
displayName:@"文件名称"];
*/

//发送文件
/*
ECFileMessageBody *messageBody = [[ECFileMessageBody alloc] initWithFile:@"文件本地绝对路径" 
displayName:@"文件名称"];
*/


//发送文本
ECTextMessageBody *messageBody = [[ECTextMessageBody alloc] initWithText:@"你好,欢迎来到云通讯"];
ECMessage *message = [[ECMessage alloc] initWithReceiver:@"John的账号Id" body:messageBody];

//如果需要跨应用发送消息,需通过appkey+英文井号+用户帐号的方式拼接,发送录音、发送群组消息等与此方式一致
//群组跨应用只是邀请成员时,被邀请的用户要用appid#账号的格式,向群组里发消息不需要。
//例如:appkey=20150314000000110000000000000010 
             帐号ID=john  
            传入帐号=20150314000000110000000000000010#john              
//ECMessage *message = [[ECMessage alloc] initWithReceiver:@"appkey#John的账号Id" body:messageBody];

#warning 取本地时间
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) {
        //发送成功
    }else if(error.errorCode == ECErrorType_Have_Forbid || error.errorCode == ECErrorType_File_Have_Forbid)
    {
        //您已被群组禁言
    }else{
    //发送失败
    }
}];

                    

✾ 发送语音

1、我们假设Tony给John发送语音消息,则代码如下:

                    //开始录音
-(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) {
            
            //录音超时,立即发送;应用也可以选择不发送
            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) {
                    //发送成功
                }else if(error.errorCode == ECErrorType_Have_Forbid || error.errorCode == 
                ECErrorType_File_Have_Forbid){
                    //您已被群组禁言
                }else{
                    //发送失败
                }
            }];
        }
    }];
}

//停止录音
-(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) {
                    //发送成功
                }else if(error.errorCode == ECErrorType_Have_Forbid || error.errorCode == 
                ECErrorType_File_Have_Forbid){
                    //您已被群组禁言
                }else{
                    //发送失败
                }
            }];
        } else if  (error.errorCode == ECErrorType_RecordTimeTooShort) {
            //录音时间过短
        }
    }];
}

                    

2、我们假设Tony给John发送录音变声消息,则代码如下:

ECSountTouchConfig *config = [[ECSountTouchConfig alloc] init];
config.pitch = 8;
config.pitch = 0;
config.rate = -20;
config.srcVoice = srcFile;
config.dstVoice = desFile;

[[ECDevice sharedInstance].messageManager changeVoiceWithSoundConfig:config 
completion:^(ECError *error, ECSountTouchConfig* dstSoundConfig) {

ECVoiceMessageBody * messageBody = [[ECVoiceMessageBody alloc] initWithFile:
[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) 
objectAtIndex:0] stringByAppendingPathComponent:[dstSoundConfig.dstVoice 
lastPathComponent]] displayName:[dstSoundConfig.dstVoice lastPathComponent]];


[[ECDevice sharedInstance].messageManager playVoiceMessage:messageBody completion:^(ECError *error) {

}];
}
参照demo

                    

✾ 接收消息 — 我们假设John收到Tony发送过来的消息,则代码如下:

/**
 @该通知回调接口在代理类里面
 @brief 接收即时消息代理函数
 @param message 接收的消息
 */
-(void)onReceiveMessage:(ECMessage*)message
{
//如果是跨应用消息,from为appkey+英文井号+用户帐号。
//例如:appkey=20150314000000110000000000000010 
             帐号ID=john  
             发送者=20150314000000110000000000000010#john    
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;
}
}

                    

✾ 阅后即焚 — 我们假设John收到Tony单聊时,john发送给tony一条消息,tony阅读后会自动删除,并且通知john这条消息已经被删除(暂时只支持单聊),则代码如下:

/**
 @brief 删除点对点消息(目前只支持删除接收到的消息)
 @param message 需要删除的消息
 @param completion 执行结果回调block
 */
-(void)deleteMessage:(ECMessage*)message completion:(void(^)(ECError *error, ECMessage* message)) completion;

接收方:
[[ECDevice sharedInstance].messageManager deleteMessage:self.displayMessage completion:^(ECError *error, ECMessage *message) {
                // 删除服务器上的消息后,你也需要将本地的消息清空
                
 }];

发送方:(当接收方调用删除消息接口,并且成功删除后,会给发送方发一条通知消息)
- (void)onReceiveMessageNotify:(ECMessageNotifyMsg *)message {
    NSLog(@"onReceiveMessageNotify:--%@",message);
    ECMessageDeleteNotifyMsg *msg = (ECMessageDeleteNotifyMsg*)message;
    
}

                    

✾ 地理位置 — 我们假设John收到Tony单聊时,john发送给tony一条位置消息,tony点击会自动跳转并点击右上角导航跳转苹果地图为您导航,则代码如下:

说明:关于发送地理位置,该功能需要用户自己在客户端通过发送消息的接口实现,SDK中没有封装具体的发送位置接口(android、ios均需用户自己在客户端实现)。

//经纬度
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
//位置信息
@property (nonatomic, readonly, copy)   NSString *title;

ECLocationPoint *point = [ECLocationPoint alloc] init];

ECMessage* message = [[DeviceChatHelper sharedInstance] sendLocationMessage:point.coordinate andTitle:point.title to:self.sessionId];

参照demo

                    

✾ 发送和接收自定义状态消息 — 当A收到B的第一条消息后,B如果还在输入,则A能获取B的输入状态,代码如下:

[ECDevice sharedInstance].messageManager 
sendMessage:[[ECMessage alloc] initWithReceiver:to 
body:[[ECUserStateMessageBody alloc] 
initWithUserState:[NSString stringWithFormat:@"%d", state]]] 
progress:nil completion:^(ECError *error, ECMessage *message) 
{}];

                    

✾ 发送链接消息 — 发送文本消息是链接是点击进入后,可将本网页的内容抓取后分享到云通讯平台的单人和群组讨论组,代码如下:

ECMessage *message = [[ECMessage alloc] init];
    ECPreviewMessageBody *msgBody = [[ECPreviewMessageBody alloc] 
initWithFile:”本地文件路径” displayName: ”本地文件路径后缀名”];
    msgBody.url = ”链接消息URL”;
    msgBody.title = ”网页的表头”;
    msgBody.remotePath = ”网页抓取图片的地址”;
    msgBody.desc = ”网页抓取的描述”;
    msgBody.thumbnailLocalPath = ”图片缩略图路径”;
    message = [[DeviceChatHelper sharedInstance] sendMediaMessage:msgBody to:self.sessionId];
    [ECDevice sharedInstance].messageManager sendMessage:message progress:nil completion:^(ECError *error, 
    ECMessage *amessage) {
    
    if (error.errorCode == ECErrorType_NoError) {
        //发送成功
    }else if(error.errorCode == ECErrorType_Have_Forbid || error.errorCode == ECErrorType_File_Have_Forbid)
    {
        //您已被群组禁言
    }else {}
}];


                    

✾ 消息撤回 — 发送消息成功后,如果用户想要撤回此消息时,此接口可以帮用户实现功能,但是发送成功消息必须在两分钟之内。

/**
 @brief 撤回消息
 @param message 需要撤回的消息
 @param completion 执行结果回调block
 */
[[ECDevice sharedInstance].messageManager revokeMessage:message 
completion:^(ECError *error, ECMessage *message) {
    __strong typeof(weakSelf)strongSelf = weakSelf;
    NSLog(@"撤回消息 error=%d", (int)error.errorCode);
    if (error.errorCode == ECErrorType_NoError) {
    // 撤回消息成功后,此位置显示为你撤回了一条消息,此消息是需要本地去做,因为不经过服务器。可以仿照demo具体实现
  }
}

                    

撤回消息通知增加ECMessageRevokeNotifyMsg — 当发送方撤回消息时,接收方会收到这一条通知消息-(void)onReceiveMessageNotify:(ECMessageNotifyMsg*)message,接受方可以在这里做接收方的逻辑判断处理,demo如下:

-(void)onReceiveMessageNotify:(ECMessageNotifyMsg*)message {
if(message.messageType==ECMessageNotifyType_RevokeMessage) {// 接收方收到对方撤回消息的逻辑处理
}
}

                    

✾ 消息回执 — 当用户接收到消息并且查看此消息时,可以向发送方发送消息已读,这样发送方就可以知道消息是否被读过。

/**
 @brief 消息已读(接收到的消息)
 @param message 设置已读的消息
 @param completion 执行结果回调block
 */
ECMessage *message(接收消息)
[[ECDevice sharedInstance].messageManager readedMessage:message 
completion:^(ECError *error, ECMessage *amessage) {
}

                    

消息回执通知增加ECMessageIsReadedNotifyMsg — 当接收方读完消息发送消息回执时,消息发送方会收到这一条通知消息-(void)onReceiveMessageNotify:(ECMessageNotifyMsg*)message,消息发送方可以在这里做发送方消息回执的逻辑判断处理,demo如下:

-(void)onReceiveMessageNotify:(ECMessageNotifyMsg*)message {
if(message.messageType==ECMessageNotifyType_MessageIsReaded) {// 消息发送方收到对方回执消息的逻辑处理
}
}

                    

✾ 置顶(取消置顶)会话 — 是否置顶会话场景:用户可以置顶本地的会话,并且在切换设备时可以调用获取置顶会话列表来达到会话置顶的功能。

/**
 @brief 是否置顶会话
 @param seesionId 会话id
 @param isTop 0 取消置顶 1 置顶
 */
seesionId = @”通讯号码”
isTop = 0/1(“是否置顶0“)
[[ECDevice sharedInstance].messageManager setSession:sessionId IsTop:isTop 
completion:^(ECError *error, NSString *seesionId) {
if (error.errorCode == ECErrorType_NoError) {//是否置顶成功失败}
}

/**
 @brief 获取置顶会话列表
 @param completion 执行结果回调block
 */
- (void)getTopSession:(void(^)(ECError *error, NSArray *topContactLists))completion{
// topContactLists里面包含会话sessionId
}

                    

2、群聊

✾ 发送文本\语音\图片\附件 — 我们假设Tony给群组名为"出彩中国人"的群组发送消息,则代码如下:

ECTextMessageBody *messageBody = [[ECTextMessageBody alloc] initWithText:@"你好,欢迎来到云通讯"];
ECMessage *message = [[ECMessage alloc] initWithReceiver:@"出彩中国人的群组Id,以字母g开头" body:messageBody];

#warning 取本地时间
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) {
        //发送成功
    }else if(error.errorCode == ECErrorType_Have_Forbid || error.errorCode == 
    ECErrorType_File_Have_Forbid){
        //您已被群组禁言
    }else{
    	//发送失败
    }
}];
                    

✾ 发送变声消息 — 我们假设Tony给群组名为"出彩中国人"的群组发送录音变声消息,则代码如下:


ECSountTouchConfig *config = [[ECSountTouchConfig alloc] init];
config.pitch = 8;
config.pitch = 0;
config.rate = -20;
config.srcVoice = srcFile;
config.dstVoice = desFile;

[[ECDevice sharedInstance].messageManager changeVoiceWithSoundConfig:config 
completion:^(ECError *error, ECSountTouchConfig* dstSoundConfig) {

ECVoiceMessageBody * messageBody = [[ECVoiceMessageBody alloc] 
initWithFile:[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) 
objectAtIndex:0] stringByAppendingPathComponent:[dstSoundConfig.dstVoice 
lastPathComponent]] displayName:[dstSoundConfig.dstVoice lastPathComponent]];


[[ECDevice sharedInstance].messageManager playVoiceMessage:messageBody completion:^(ECError *error) {

}];
}
参照demo


                    

✾ 地理位置 — 我们假设Tony给群组名为"出彩中国人"的群组发送消息, 点击会自动跳转并点击右上角导航跳转苹果地图为您导航则代码如下:

//经纬度
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
//位置信息
@property (nonatomic, readonly, copy)   NSString *title;

ECLocationPoint *point = [ECLocationPoint alloc] init];

ECMessage* message = [[DeviceChatHelper sharedInstance] sendLocationMessage:point.coordinate andTitle:point.title to:self.sessionId];

参照demo

                    

✾ 接收消息 — 我们假设John是"出彩中国人"群组中的一员,则代码如下:

/**
 @该通知回调接口在代理类里面,和单聊是同一个通知回调接口,只不过发送者id是以'g'开头。
 @brief 接收即时消息代理函数
 @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;
   }
  case MessageBodyType_Location:{
     ECLocationMessageBody*msgBody = (ECLocationMessageBody*)message.messageBody;
    
     break;
   }
   default:
     break;
}
}
     
                    

3、群组操作

✾ 创建群组/讨论组 — 我们假设Tony要创建一个名为"出彩中国人"具体代码如下:

ECGroup * newgroup = [[ECGroup alloc] init];
newgroup.name = @"出彩中国人";
newgroup.declared = @"欢迎来到容联云通讯";
newgroup.isDiscuss = NO;//讨论组该值为YES

[[ECDevice sharedInstance].messageManager createGroup:newgroup completion:^(ECError *error, 
ECGroup *group) {
    
    if (error.errorCode == ECErrorType_NoError) {
        
        NSLog(@"创建群组成功 群组ID:%@", group.groupId);
    }
    else{
        NSLog(@"创建群组失败 errorCode:%d\r\nerrorDescription:%@",
        (int)error.errorCode,error.errorDescription);
    }
}];
                    

✾ 主动加入 — 只要知道群组id,就可以主动加入群组。

1、我们假设"出彩中国人"群组已经有Tony和John两位成员,现在Smith要加入"出彩中国人"群组,则代码如下:

[[ECDevice sharedInstance].messageManager joinGroup:@"出彩中国人群组ID" reason:@"我要参加出彩中国人"
 completion:^(ECError *error, NSString *groupId) {
    __strong __typeof(weakSelf)strongSelf = weakSelf;
    if (error.errorCode==ECErrorType_Have_Joined) {
        NSLog(@"您已经在群组%@", groupId);
    }else if(error.errorCode==ECErrorType_NoError){
        if (strongSelf.applyGroup.mode == ECGroupPermMode_DefaultJoin) {
            NSLog(@"加入群组%@成功!", groupId);
        }else{
            NSLog(@"申请加入已发出,请等待群主同意请求");
        }
    }else{
        NSLog(@"加入群组失败 errorCode:%d\r\nerrorDescription:%@",
        (int)error.errorCode,error.errorDescription);
    }
}];
                    

注意:如果群组"出彩中国人"是公开群组,则smith直接被允许加入。 如果群组"出彩中国人"是私有群组
则smith加入需要群主Tony的的同意。

关于几种群组的解释:
公开群组:用户可以直接被允许加入群组,不需要群主进行验证;
验证群组:用户加入群组的时候需要群主同意才可以加入
私有群组:只能群主邀请加入

Tony首先收到Smith加入的请求,代码如下:

/**
@该通知回调接口是代理类里面统一的关于群组的"群组通知回调接口"—
onReceiveGroupNoticeMessage
 @brief 接收群组相关消息
 @discussion 参数要根据消息的类型,转成相关的消息类;
 解散群组、收到邀请、申请加入、退出群组、有人加入、移除成员等消息
 @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 执行结果回调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);
    }
}];
                    

2.Smith加入成功后,群组中成员Tony和John收到的通知回调方法代码如下:

/**
 @该通知回调接口是代理类里面统一的关于群组的"群组通知回调接口"—onReceiveGroupNoticeMessage
 @brief 接收群组相关消息
 @discussion 参数要根据消息的类型,转成相关的消息类;
 解散群组、收到邀请、申请加入、退出群组、有人加入、移除成员等消息
 @param groupMsg 群组消息
 */
-(void)onReceiveGroupNoticeMessage:(ECGroupNoticeMessage *)groupMsg{
    
    if (groupMsg.messageType == ECGroupMessageType_ReplyJoin)
    {
        ECReplyJoinGroupMsg *message = (ECReplyJoinGroupMsg *)groupMsg;
        NSLog(@"讨论组\"%@\"%@\"%@\"的加入申请",message.groupId,message.confirm==2?@"同意":@"拒绝",
        message.member);
    }
}
                    

✾ 邀请加入 — 只能群主邀请别人加入

1、我们假设"出彩中国人"群组的创建者Tony邀请Smith加入群组,则代码如下:

/**
 @brief 管理员邀请加入群组
 @param groupId 邀请加入的群组id
 @param reason 邀请理由
 @param members 邀请加入的人
 @param confirm 是否需要对方验证 1:直接加入(不需要验证) 2:需要对方验证
 @param completion 执行结果回调block
 */
[[ECDevice sharedInstance].messageManager inviteJoinGroup:@"出彩中国人群组ID" reason:@"欢迎来到云通讯" 
members:@[@"Smith的账号Id"] confirm:2 completion:^(ECError *error, NSString *groupId, NSArray *members) {
    [MBProgressHUD hideHUDForView:self.view animated:YES];
    if(error.errorCode ==ECErrorType_NoError)
    {
        NSLog(@"邀请请求已发出");
    }
    else
    {
        NSLog(@"errorCode:%d\rerrorDescription:%@",(int)error.errorCode,error.errorDescription);
    }
}];
                    

注意:如果Tony邀请Smith加入的时候,接口参数不指定加入需要Smith确认,则smith直接被邀请加入。
如果指定需要Smith同意才能加入,则Smith收到如下通知回调,并在回调里面回复"同意"或"拒绝"加入。代码如下:

                    /**
@该通知回调接口是代理类里面统一的关于群组的"群组通知回调接口"—
onReceiveGroupNoticeMessage
 @brief 接收群组相关消息
 @discussion 参数要根据消息的类型,转成相关的消息类;
 解散群组、收到邀请、申请加入、退出群组、有人加入、移除成员等消息
 @param groupMsg 群组消息
 */
-(void)onReceiveGroupNoticeMessage:(ECGroupNoticeMessage *)groupMsg{
    
    if (groupMsg.messageType == ECGroupMessageType_Invite)
    {
        ECInviterMsg * message = (ECInviterMsg *)groupMsg;
        NSString *declared = @"";
        if (message.declared.length>0) {
            declared = [NSString stringWithFormat:@",理由:%@",message.declared];
        }
        NSLog(@"\"%@\"邀请您加入\"%@\"讨论组\"%@",message.admin,message.groupId,declared);

        if (message.confirm==1) {
            [[ECDevice sharedInstance].messageManager ackInviteJoinGroupRequest:message.groupId 
            invitor:message.admin ackType:EAckType_Agree completion:^(ECError *error, NSString *gorupId){
                if (error.errorCode == ECErrorType_NoError) {
                    NSLog(@"回复已发出");
                }else{
                    NSLog(@"errorCode:%d\rerrorDescription:%@",
                    (int)error.errorCode,error.errorDescription);
                }
            }];
        }
    }
}
                    

2、Smith加入成功后,群组中成员Tony和John收到的通知回调方法代码如下:

/**
@该通知回调接口是代理类里面统一的关于群组的"群组通知回调接口"—
onReceiveGroupNoticeMessage
 @brief 接收群组相关消息
 @discussion 参数要根据消息的类型,转成相关的消息类;
 解散群组、收到邀请、申请加入、退出群组、有人加入、移除成员等消息
 @param groupMsg 群组消息
 */
-(void)onReceiveGroupNoticeMessage:(ECGroupNoticeMessage *)groupMsg{
    
    if (groupMsg.messageType == ECGroupMessageType_ReplyInvite)
    {
        ECReplyInviteGroupMsg *message = (ECReplyInviteGroupMsg *)groupMsg;
        NSLog(@"\"%@\"%@讨论组\"%@\"的邀请加入", message.member, 
        message.confirm==2?@"同意":@"拒绝", message.groupId);
    }
}

                    

✾ 退出群组

1、我们假设Smith要退出群组,则代码如下:

/**
 @brief 退出群组
 @param groupId 退出的群组id
 @param completion 执行结果回调block
 */
[[ECDevice sharedInstance].messageManager quitGroup:@"出彩中国人群组ID" 
 completion:^(ECError *error, NSString *groupId) {
    [MBProgressHUD hideHUDForView:self.view animated:YES];
    if (error.errorCode == ECErrorType_NoError) {
        NSLog(@"退出群组");
    }
    else
    {
        NSLog(@"errorCode:%d\rerrorDescription:%@",(int)error.errorCode,error.errorDescription);
    }
}];                  
                    

2、Smith退出成功后,群组中成员Tony和John收到的通知回调方法代码如下:

/**
@该通知回调接口是代理类里面统一的关于群组的"群组通知回调接口"—
onReceiveGroupNoticeMessage
 @brief 接收群组相关消息
 @discussion 参数要根据消息的类型,转成相关的消息类;
 解散群组、收到邀请、申请加入、退出群组、有人加入、移除成员等消息
 @param groupMsg 群组消息
 */
-(void)onReceiveGroupNoticeMessage:(ECGroupNoticeMessage *)groupMsg{
    
    if (groupMsg.messageType == ECGroupMessageType_Quit)
    {
        ECQuitGroupMsg *message = (ECQuitGroupMsg *)groupMsg;
        NSLog(@"\"%@\"退出讨论组\"%@\"",message.member, message.groupId);
    }
}
                    

✾ 群主踢人

1、我们假设群主Tony要把Smith要踢出群组,则代码如下:

/**
 @brief 删除成员
 @param groupId 删除成员的群组id
 @param member 删除的成员
 @param completion 执行结果回调block
 */
[[ECDevice sharedInstance].messageManager deleteGroupMember:@"出彩中国人群组ID" 
 member:@"Smith的账号Id" completion:^(ECError *error, NSString *groupId, NSString *member) {
    
    if (error.errorCode ==ECErrorType_NoError) {
        NSLog(@"踢人成功");
    }
    else
    {
        NSLog(@"errorCode:%d\rerrorDescription:%@",(int)error.errorCode,error.errorDescription);
    }
}];

                    

2、群组中所有成员都会收到的Smith被踢的消息,包括Smith自己,Smith判断被踢用户的id等于自己,则从本地删除群组,
此通知回调方法代码如下:

/**
@该通知回调接口是代理类里面统一的关于群组的"群组通知回调接口"—
onReceiveGroupNoticeMessage
 @brief 接收群组相关消息
 @discussion 参数要根据消息的类型,转成相关的消息类;
 解散群组、收到邀请、申请加入、退出群组、有人加入、移除成员等消息
 @param groupMsg 群组消息
 */
-(void)onReceiveGroupNoticeMessage:(ECGroupNoticeMessage *)groupMsg{
    
    if (groupMsg.messageType == ECGroupMessageType_RemoveMember){
        
        ECRemoveMemberMsg *message = (ECRemoveMemberMsg *)groupMsg;
        NSLog(@"\"%@\"被移除讨论组\"%@\"", message.member, message.groupId);
    }
}

                    

✾ 解散群组 — 只有群主才能解散群组。

1、我们假设群主Tony要解散"出彩中国人",则代码如下:

/**
 @brief 删除群组
 @param groupId 删除的群组id
 @param completion 执行结果回调block
 */
[[ECDevice sharedInstance].messageManager deleteGroup:@"出彩中国人群组ID"
 completion:^(ECError *error, NSString *groupId) {
    [MBProgressHUD hideHUDForView:self.view animated:YES];
    if (error.errorCode == ECErrorType_NoError) {
        NSLog(@"解散群组成功");
    }
    else
    {
        NSLog(@"errorCode:%d\rerrorDescription:%@",(int)error.errorCode,error.errorDescription);
    }
}];


                    

2、群组中所有成员收到的通知回调方法代码如下:

/**
@该通知回调接口是代理类里面统一的关于群组的"群组通知回调接口"—
onReceiveGroupNoticeMessage

 @brief 接收群组相关消息
 @discussion 参数要根据消息的类型,转成相关的消息类;
 解散群组、收到邀请、申请加入、退出群组、有人加入、移除成员等消息
 @param groupMsg 群组消息
 */
-(void)onReceiveGroupNoticeMessage:(ECGroupNoticeMessage *)groupMsg{
    if (groupMsg.messageType == ECGroupMessageType_Dissmiss){
        NSLog(@"讨论组\"%@\"被解散", groupMsg.groupId);
    }
}

                    

✾ 获取群详情 — 代码如下:

/**
 @brief 获取群组属性
 @param groupId 获取信息的群组id
 @param completion 执行结果回调block
 */
[[ECDevice sharedInstance].messageManager getGroupDetail:@"出彩中国人群组ID"
 completion:^(ECError *error, ECGroup *group) {
    
    if (error.errorCode == ECErrorType_NoError) {
        NSLog(@"群主:%@",group.owner);
        NSLog(@"群名字:%@",group.name);
        NSLog(@"群公告:%@",group.declared);
        NSLog(@"是否讨论组:%d",group. isDiscuss);
    }else{
        NSLog(@"errorCode:%d\rerrorDescription:%@",(int)error.errorCode,error.errorDescription);
    }
}];

                    

✾ 获取群成员 — 代码如下:

/**
 @brief 查询群组成员
 @param groupId 查询的群组id
 @param completion 执行结果回调block
 */
[[ECDevice sharedInstance].messageManager queryGroupMembers:@"出彩中国人群组ID"
 completion:^(ECError *error, NSString* groupId, NSArray *members) {
    
    if (error.errorCode == ECErrorType_NoError) {
        NSLog(@"获取群组成员成功");
        for (ECGroupMember *member in members) {
            if (member.role == ECMemberRole_Creator) {
                NSLog(@"群组创建者:%@", member.memberId);
                break;
            }
        }
    }else{
        NSLog(@"errorCode:%d\rerrorDescription:%@",(int)error.errorCode,error.errorDescription);
    }
}];
                    
                    

✾ 群组搜索 — 可以根据群组名字或者群组ID来搜索群组(群组名称为纯数字或纯字母时需要输入完整的群名称) ,代码如下:

/**
 @brief 按条件搜索公共群组
 @param match 需要匹配的条件
 @param completion 执行结果回调block
 */
ECGroupMatch *match = [[ECGroupMatch alloc] init];
match.searchType = 2; //搜索类型 1: 群组ID  2:群组名称
match.keywords = @"出彩中国人";

[[ECDevice sharedInstance].messageManager searchPublicGroups:
 match completion:^(ECError *error, NSArray *groups) {

    if (error.errorCode == ECErrorType_NoError) {
        if(groups.count==0){
            NSLog(@"获取到的群组为空");
        }else{
            for (ECGroup* group in groups) {
                NSLog(@"群组ID:%@",group.groupId);
                NSLog(@"群主:%@",group.owner);
                NSLog(@"群名字:%@",group.name);
                NSLog(@"群公告:%@",group.declared);
            }
        }
    }else {
        NSLog(@"errorCode:%d\rerrorDescription:%@",(int)error.errorCode,error.errorDescription);
    }
}];

                    

✾ 获取个人所在的群组 — 通常登录之后,需要立即获取自己所在的群组,返回的群组信息包括
群组/讨论组id、群组名、群组创建者账号等信息

[[ECDevice sharedInstance].messageManager 
queryOwnGroupsWith: ECGroupType_Group/ECGroupType_Discuss 
completion:^(ECError *error, NSArray *groups) {
    
    if (error.errorCode == ECErrorType_NoError) {
        
        for (ECGroup *group in groups) {
            NSLog(@"群组ID:%@",group.groupId);
            NSLog(@"群主:%@",group.owner);
            NSLog(@"群名字:%@",group.name);
            NSLog(@"是否讨论组:%d",group. isDiscuss);
        }
    } else {
        
    }
}];
  
                    

✾ 设置群组成员角色(包括设置管理员和成员以及转让群主权限) — 群主权限最高、管理次之、成员最低,同等权限之间不可操作,代码如下:

/**
 @brief 管理员修改用户角色权限
 @param groupId 群组id
 @param memberId 成员id
 @param role 1群主 2管理员 3普通成员
 @param completion 执行结果回调block
 */
-(void)setGroupMemberRole:(NSString*)groupId 
member:(NSString*)memberId role:(ECMemberRole)role 
completion:(void(^)(ECError*error,NSString*groupId,NSString *memberId))completion;

[[ECDevice sharedInstance].messageManager 
setGroupMemberRole:”群组id” member:”成员id” role:”角色” 
completion:^(ECError *error, NSString *groupId, NSString *memberId) { 
   if (error.errorCode == ECErrorType_NoError) {
}
}
 
                    

✾ 查询消息已读和未读人数 — 群组消息发送方会知道消息多少人已读和未读。

/**
 @brief 获取消息状态(只支持群组,且发送的消息)
 @param message 设置已读的消息
 @param completion 执行结果回调block
 */ 
ECMessage *message(发送消息)
[[ECDevice sharedInstance].messageManager queryMessageReadStatus:_message 
completion:^(ECError *error, NSArray *readArray, NSArray *unreadArray) {  
 if (error.errorCode == ECErrorType_NoError) {
// readArray已读的通讯账号,unreadArray未读的通讯账号
}
}
 
                    

4、离线消息

1、用户登录以后,应该首先获取自己的云通讯服务端的离线条数,具体代码如下:

/**
 @该通知回调接口在代理类里面
 @brief 离线消息数
 @param count 消息数
 */
-(void) onOfflineMessageCount:(NSUInteger)count
{
    NSLog(@"onOfflineMessageCount =%lu",count);
}
                   
                    

2、根据总的离线条数,决定获取多少条离线消息,具体代码如下:

/**
 @该通知回调接口在代理类里面
 @brief 需要获取的消息数
 @return 消息数 -1:全部获取 0:不获取
 */
-(NSInteger) onGetOfflineMessage
{
    return -1;
}

                    

3、离线消息的接收

/**
 @该通知回调接口在代理类里面
 @brief 接收离线消息代理函数
 @param message 接收的消息
 */
-(void)onReceiveOfflineMessage:(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;
}
}
                    

4、离线消息接收结果

/**
 @该通知回调接口在代理类里面
 @brief 离线消息接收是否完成
 @param isCompletion YES:拉取完成 NO:拉取未完成(拉取消息失败)
 */
-(void)onReceiveOfflineCompletion:(BOOL)isCompletion {
   //离线消息接收完成
}

                    

5、离线消息角标数显示

/**
 @brief 设置角标数
 @param badgeNumber 角标数字
 @param completion 执行结果回调block
 */
-(void)setAppleBadgeNumber:(NSInteger)badgeNumber completion:(void(^)(ECError* error)) completion;

                    

5、自定义消息

自定义消息通过发送文本消息接口扩展字段来实现,具体说明如下:

ECTextMessageBody *messageBody = [[ECTextMessageBody alloc] initWithText:@"你好,欢迎来到云通讯"];
ECMessage *message = [[ECMessage alloc] initWithReceiver:@"John的账号Id" body:messageBody];
message.userData = @"扩展字段";

//发送同上
              
                    

6、设置个人信息

可以通过接口设置个人信息,包括昵称、生日、性别,建议昵称必须设置,以便在推送消息的时候使用,具体代码如下:

ECPersonInfo *person = [[ECPersonInfo alloc] init];
person.nickName = @"云通讯";
person.sex = ECSexType_Male;
person.birth = @"2013-11-28";//时间格式 yyyy-MM-dd

/**
 @brief 设置个人信息
 @discussion 异步函数,断开与平台的连接
 @param person 个人信息
 @param completion 执行结果回调block
 */
[[ECDevice sharedInstance] setPersonInfo:person
 completion:^(ECError *error, ECPersonInfo *person) {
    
    if (error.errorCode == ECErrorType_NoError) {
        NSLog(@"修改成功");
    }else{
        NSLog(@"errorCode:%d\rerrorDescription:%@",
        (int)error.errorCode,error.errorDescription);
    }
}];

                    

7、获取个人信息

获取个人信息代码如下:

/**
 @brief 获取个人信息
 @discussion 异步函数,断开与平台的连接
 @param completion 执行结果回调block
 */
[[ECDevice sharedInstance] getPersonInfo:^(ECError *error, ECPersonInfo *person) {
    if (error.errorCode == ECErrorType_NoError)
    {
        NSLog(@"昵称:%@",person.nickName);
        NSLog(@"生日:%@",person.birth);
        NSLog(@"性别:%@",person.sex==ECSexType_Male?@"男":@"女");
        NSLog(@"个人信息版本号:%lld",person.version);
    }
}];

                    

8、设置免打扰

获取个人信息代码如下:

/**
 @brief 设置免打扰
 @param sessionId 会话id,个人账号或群组ID
 @param isMute 是否免打扰
 @param completion 执行结果回调block
 */
[[ECDevice sharedInstance] setMuteNotification:@ "个人账号或群组id" isMute:(BOOL)isMute 
    completion:(void(^)(ECError* error)) completion{
    if (error.errorCode == ECErrorType_NoError)
    {
    	NSLog(@"设置成功");
    }
}];