目录
引入静态库
正常情况下需要引入MMCSDK和ProtocolBufferSDK两个静态库,但是若你的项目中也用到了ProtocolBuffer,为避免冲突,在项目中可以不引入MIMC提供的ProtocolBufferSDK静态库。
环境配置
(1) Build Settings的Framework Search Paths和Header Search Paths都引入MMCSDK的正确路径。
(2) Build Phases的Link Binary With Libraries中加入CoreTelephony.framework,SystemConfiguration.framework和已经引入的两个静态库。
(3) 需在github的sdk目录下根据链接下载ffmpeg库并放到demo中,否则demo无法正常运行。 (具体配置可参考demo)
日志
//SDK日志总开关,默认开
[MCUser setMIMCLogSwitch:YES];
/**
* 设置打印的日志级别,默认DEBUG级别
* @param[level]:
* MIMC_DEBUG(默认)
* MIMC_INFO
* MIMC_WARN
* MIMC_ERROR
*/
[MCUser setMIMCLogLevel:MIMC_DEBUG];
用户登录
用户初始化
参考 安全认证 ,初始化NSMutableURLRequest和parseToken
(1)创建URLRequest,用于访问AppProxyService服务
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableDictionary *dicObj = [[NSMutableDictionary alloc] init];
...
NSData *dicData = [NSJSONSerialization dataWithJSONObject:dicObj options:NSJSONWritingPrettyPrinted error:nil];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:dicData];
(2)实现协议解析,解析返回结果,获取小米认证服务下发的Token
/**
* @return[NSString]:从代理认证服务返回结果中获取[小米认证服务下发的原始数据]并返回
**/
@protocol parseTokenDelegate <NSObject>
- (void)parseProxyServiceToken:(void(^)(NSData *data))callback;
@end
parseProxyServiceToken回调函数实现之后,需要设置委托者的代理是谁。比如:_user.parseTokenDelegate = self,self指的是实现parseProxyServiceToken方法的当前类对>
象。
(3)创建user:
MCUser *user = [[MCUser alloc] initWithAppId:appId andAppAccount:appAccount];
登录
/**
* 默认支持多设备登录
* 进程整个生命周期内login()调用一次即可
*/
[user login];
单点登录
/**
* @param[enableSSO]: 默认NO,YES时打开启用标志,且实例化User对象时,传入相同resource时方可正式生效
* 注意:
* 必须在调用login()之前调用
* 当用户登录时,先前登录用户会收到下线回调,回调参数type = reason = desc = "single-resource-kick"
*/
[user enableSSO:YES];
在线状态变化回调
/**
* @param[user]: 在线状态发生变化的用户
* @param[status]: 1:在线,0:不在线
* @param[type]: 状态变化类型
* @param[reason]: 状态变化原因
* @param[desc]: 状态变化描述信息
**/
@protocol onlineStatusDelegate <NSObject>
- (void)statusChange:(MCUser *)user status:(int)status type:(NSString *)type reason:(NSString *)reason desc:(NSString *)desc;
@end
statusChange回调函数实现之后,需要设置委托者的代理是谁。比如:_user.onlineStatusDelegate = self,self指的是实现statusChange方法的当前类对象。
注销
[user logout];
发送消息
发送单聊消息
/**
* @param[toAppAccount] NSString: 消息接收者在APP账号系统内的账号
* @param[payload] NSData: 开发者自定义消息体,最大不超过15KB
* @param[isStore] BOOL: 消息是否存储在mimc服务端,YES:存储, NO:不存储, 默认存储
* @param[bizType] NSString: 消息类型,默认空字符串
* @return: 客户端生成的消息ID
**/
NSString packetId = [user sendMessage:toAppAccount payload:payload];
NSString packetId = [user sendMessage:toAppAccount payload:payload isStore:isStore];
NSString packetId = [user sendMessage:toAppAccount payload:payload bizType:bizType];
NSString packetId = [user sendMessage:toAppAccount payload:payload bizType:bizType isStore:isStore];
发送群聊消息
/**
* @param[topicId] int64_t: 接收消息的群ID
* @param[payload] NSData: 开发者自定义消息体,最大不超过15KB
* @param[isStore] BOOL: 消息是否存储在mimc服务端,YES:存储, NO:不存储, 默认存储
* @param[bizType] NSString: 消息类型,默认空字符串
* @return: 客户端生成的消息ID
**/
NSString packetId = [user sendGroupMessage:topicId payload:payload];
NSString packetId = [user sendGroupMessage:topicId payload:payload isStore:isStore];
NSString packetId = [user sendGroupMessage:topicId payload:payload bizType:bizType];
NSString packetId = [user sendGroupMessage:topicId payload:payload bizType:bizType isStore:isStore];
发送无限大群消息
/**
* @param[topicId] int64_t: 需要发送给哪个群的群ID
* @param[payload] NSData: 需要发送的群消息内容,最大不超过15KB
* @param[isStore] BOOL: 是否存储这条消息
* @param[bizType] NSString: 消息类型,默认空字符串
* @return: 客户端生成的消息ID
**/
NSString packetId = [user sendUnlimitedGroupMessage:topicId payload:payload];
NSString packetId = [user sendUnlimitedGroupMessage:topicId payload:payload isStore:isStore];
NSString packetId = [user sendUnlimitedGroupMessage:topicId payload:payload bizType:bizType];
NSString packetId = [user sendUnlimitedGroupMessage:topicId payload:payload bizType:bizType isStore:isStore];
发送在线消息
/**
* @param[toAppAccount]: 消息接收方在APP账号系统内的唯一账号ID
* @param[payload]: 开发者自定义消息体,最大不超过15KB
* @param[bizType]: 消息类型,默认空字符串
* @return 客户端生成的消息ID
*/
String packetId = [user sendOnlineMessage:toAppAccount payload:payload];
String packetId = [user sendOnlineMessage:toAppAccount payload:payload bizType:bizType];
接收消息回调
@protocol handleMessageDelegate <NSObject>
/**
* 收到单聊消息的回调函数
* @param[packets]: 单聊消息集
* @note: MIMCMessage 单聊消息
* MIMCMessage.packetId: 消息ID
* MIMCMessage.sequence: 序列号
* MIMCMessage.fromAccount: 发送方账号
* MIMCMessage.fromResource: 发送方设备标识
* MIMCMessage.toAccount: 接收方账号
* MIMCMessage.toResource: 接收方设备标识
* MIMCMessage.payload: 消息体
* MIMCMessage.timestamp: 时间戳
* MIMCMessage.bizType: 消息类型
* MIMCMessage.convIndex: 会话索引,默认0值,说明没有启用会话消息,该字段由服务器填充,在一个会话中连续自增,从1开始
* @return 返回YES说明消息被成功递交给应用层,若返回NO说明消息递交失败,会再次触发该回调,直到返回YES为止
**/
- (BOOL)handleMessage:(NSArray<MIMCMessage*> *)packets user:(MCUser *)user;
/**
* 收到群聊消息的回调函数
* @param[packets]: 群聊消息集
* @note: MIMCGroupMessage 群聊消息
* MIMCGroupMessage.packetId: 消息ID
* MIMCGroupMessage.topicId: 群ID
* MIMCGroupMessage.sequence: 序列号
* MIMCGroupMessage.fromAccount: 发送方账号
* MIMCGroupMessage.fromResource: 发送方设备标识
* MIMCGroupMessage.payload: 消息体
* MIMCGroupMessage.timestamp: 时间戳
* MIMCGroupMessage.bizType: 消息类型
* MIMCGroupMessage.convIndex: 会话索引,默认0值,说明没有启用会话消息,该字段由服务器填充,在一个会话中连续自增,从1开始
* @return 返回YES说明消息被成功递交给应用层,若返回NO说明消息递交失败,会再次触发该回调,直到返回YES为止
**/
- (BOOL)handleGroupMessage:(NSArray<MIMCGroupMessage*> *)packets;
/**
* 收到serverAck消息的回调函数
* @param[serverAck]: 服务器返回的serverAck对象
* @note: MIMCServerAck serverAck对象
* MIMCServerAck.packetId: 客户端生成的消息ID
* MIMCServerAck.timestamp: 消息发送到服务器的时间(单位:ms)
* MIMCServerAck.sequence: 服务器为消息分配的递增ID,单用户空间内递增唯一,可用于去重/排序
* MIMCServerAck.desc: 服务器返回的描述信息
* (1)MSG_CHECK_ACCEPT字段:表示消息被服务端正常接收。
* (2)BLACKLIST_REFUSAL字段:表示发送者在黑名单中。
* (3)MSG_CHECK_SENDER_NOT_IN_TOPIC字段:表示发送者不在群列表中。
* (4)RUBBISH_MSG_REFUSAL:表示发送的消息中含有垃圾消息。(目前垃圾消息功能没有开启)
* (5)P2P_MESSAGE_EXCEED_MAX_QPS字段:表示发送单聊的消息超过qps限制。
* (6)P2T_MESSAGE_EXCEED_MAX_QPS字段:表示发送群聊的消息超过qps限制。
* (7) TOPIC_BLACKLIST_REFUSAL字段:表示向群里发送消息的人被群禁言了。
* (8) TOPIC_ID_NOT_EXIST字段:表示群不存在。
* (9) NOT_IN_GROUP字段:表示用户不在群内。
* (10) MESSAGE_EXCEED_MAX_QPS:表示发送无限大群的消息超过qps限制。
* (11)FORBID_SNED_UC_MESSAGE:群用户被禁言
* MIMCServerAck.code: 服务器的返回码
* MSG_CHECK_ACCEPT返回100
* BLACKLIST_REFUSAL返回101
* MSG_CHECK_SENDER_NOT_IN_TOPIC返回102
* RUBBISH_MSG_REFUSAL返回103
* P2P_MESSAGE_EXCEED_MAX_QPS返回104
* TOPIC_BLACKLIST_REFUSAL返回105
* P2T_MESSAGE_EXCEED_MAX_QPS返回106
* TOPIC_ID_NOT_EXIST返回202
* NOT_IN_GROUP返回203
* MESSAGE_EXCEED_MAX_QPS返回204
* FORBID_SNED_UC_MESSAGE返回403
**/
- (void)handleServerAck:(MIMCServerAck *)serverAck;
/**
* 收到无限大群群消息的回调函数
* @param[packets]: 群聊消息集
**/
- (BOOL)handleUnlimitedGroupMessage:(NSArray<MIMCGroupMessage*> *)packets;
- (void)handleOnlineMessage:(MIMCMessage *)onlineMessage;
/**
* @param[onlineMessageAck]: 服务器返回的onlineMessageAck对象,即发送在线消息对应的反馈信息
* onlineMessageAck.packetId: 客户端生成的消息ID
* onlineMessageAck.code: 服务器的返回码
* OFFLINE返回0
* RECEIVED返回1
* TIMEOUT返回2
* onlineMessageAck.desc: 服务器返回的描述信息:
* OFFLINE字段:接收方离线
* RECEIVED字段:接收方成功接收
* TIMEOUT字段:发送超时,默认10s
*/
- (void)handleOnlineMessageAck:(MCOnlineMessageAck *)onlineMessageAck;
/**
* 通知主动拉取离线消息,拉取区间:(minSequence, maxSequence]
* 默认情况,当用户处于离线状态时,最多保留近7天内的离线消息,直到用户上线,持续下发缓存的离线消息。
* 若积压的离线消息过多,会一直下发离线消息,从而导致长时间无法接收最新消息,直到离线消息接收完毕为止。
* 我们支持设置一个阈值来控制离线消息是否持续下发,比如阈值设置为offlineMsgMaxCount=500,表示当离线消息达到500条时,触发onPullNotification(...)
* 回调,当回调接口返回true时,服务端会跳过离线消息,直接下发最新的实时消息,应用方可根据回调形参单独去拉取离线消息。
* 1)首先拉取会话列表;
* 2)然后用会话列表中的"sequence"字段和回调接口的“minSequence”形参进行比对,当sequence > minSequence时,说明需要拉取该会话的历史消息;
* 3)最后拉取历史消息,其中"fromAccount"字段从会话列表中提取即可。
* 会话列表:https://admin.mimc.chat.xiaomi.net/docs/13-chatlist.html
* 历史消息:https://admin.mimc.chat.xiaomi.net/docs/11-history.html
*/
- (BOOL)onPullNotification:(int64_t)minSequence maxSequence:(int64_t)maxSequence;
/**
* 发送单聊消息超时的回调函数
* @param[message]: 发送超时的单聊消息
**/
- (void)handleSendMessageTimeout:(MIMCMessage *)message;
/**
* 发送群聊消息超时的回调函数
* @param[groupMessage]: 发送超时的群聊消息
**/
- (void)handleSendGroupMessageTimeout:(MIMCGroupMessage *)groupMessage;
/**
* 发送无限大群消息超时的回调函数
* @param[groupMessage]: 发送超时的群聊消息
**/
- (void)handleSendUnlimitedGroupMessageTimeout:(MIMCGroupMessage *)groupMessage;
@end
开发者实现上面定义的几个回调函数之后,需要设置委托者的代理是谁。比如:_user.handleMessageDelegate = self,self指的是实现上述几个回调函数的当前类对象
无限大群
创建无限大群
/**
* @param[topicName] NSString: 需要创建的群组名称
* @param[context] id: 用户自定义传入的对象,通过回调函数原样传出
* @return: 创建无限大群过程中是否有异常,无异常为YES,否则为NO
**/
- (BOOL)createUnlimitedGroup:(NSString *)topicName context:(id)context;
加入无限大群
/**
* @param[topicId] int64_t: 需要加入的群ID
* @param[context] id: 用户自定义传入的对象,通过回调函数原样传出
* @return: 客户端生成的消息ID
**/
- (NSString *)joinUnlimitedGroup:(int64_t)topicId context:(id)context;
退出无限大群
/**
* @param[topicId] int64_t: 需要加入的群ID
* @param[context] id: 用户自定义传入的对象,通过回调函数原样传出
* @return: 客户端生成的消息ID
**/
- (NSString *)quitUnlimitedGroup:(int64_t)topicId context:(id)context;
解散无限大群
/**
* @param[topicId] int64_t: 需要解散的群ID
* @param[context] id: 用户自定义传入的对象,通过回调函数原样传出
* @return: 解散无限大群过程中是否有异常,无异常为YES,否则为NO
**/
- (BOOL)dismissUnlimitedGroup:(int64_t)topicId context:(id)context;
无限大群操作回调
@protocol handleUnlimitedGroupDelegate <NSObject>
/**
* 创建无限大群是否成功的回调函数
* @param[topicId] int64_t: 群ID
* @param[topicName] NSString: 群名称
* @param[code] int: 错误码,0成功,非0失败
* @param[desc] NSString: 描述信息
* @param[context] id: 用户自定义传入的对象
**/
- (void)handleCreateUnlimitedGroup:(int64_t)topicId topicName:(NSString *)topicName code:(int)code desc:(NSString *)desc context:(id)context;
/**
* 加入指定群ID是否成功的回调函数
* @param[topicId] int64_t: 群ID
* @param[code] int: 错误码,0成功,非0失败
* @param[desc] NSString: 描述信息
* @param[context] id: 用户自定义传入的对象
**/
- (void)handleJoinUnlimitedGroup:(int64_t)topicId code:(int)code desc:(NSString *)desc context:(id)context;
/**
* 退出无限大群是否成功的回调函数
* @param[topicId] int64_t: 群ID
* @param[code] int: 错误码,0成功,非0失败
* @param[desc] NSString: 描述信息
* @param[context] id: 用户自定义传入的对象
**/
- (void)handleQuitUnlimitedGroup:(int64_t)topicId code:(int)code desc:(NSString *)desc context:(id)context;
/**
* 解散无限大群是否成功的回调函数
* * @param[topicId] int64_t: 群ID
* @param[code] int: 错误码,0成功,非0失败
* @param[desc] NSString: 描述信息
* @param[context] id: 用户自定义传入的对象
**/
- (void)handleQuitUnlimitedGroup:(int64_t)topicId code:(int)code desc:(NSString *)desc context:(id)context;
/**
* 收到无限大群被解散消息的回调函数
* @param[topicId] int64_t: 被解散的群ID
**/
- (void)handleDismissUnlimitedGroup:(int64_t)topicId;
开发者实现上面定义的几个回调函数之后,需要设置委托者的代理是谁。比如:_user.handleUnlimitedGroupDelegate = self,self指的是实现上述几个回调函数的当前类对象。
@end