SDK 接入说明
接入SDK,有以下必要步骤:
- 下载与安装
- 获取必要的接入信息
- 开始集成
第一步:下载与安装
目前有两种方式安装SDK:
- 通过
CocoaPods
管理依赖。 - 手动导入
SDK
并管理依赖。
1. 使用 CocoaPods 导入SDK
在终端中运行以下命令:
pod search BQMM
如果运行以上命令,没有搜到SDK,或者搜不到最新的 SDK 版本,您可以运行以下命令,更新您本地的 CocoaPods 源列表。
pod repo update
在您工程的 Podfile中添加最新版本的SDK(在此以2.1版本为例):
pod 'BQMM', '2.1.2'
然后在工程的根目录下运行以下命令:
pod install
说明:pod中不包含gif表情的UI模块,可点击下载,手动导入BQMM_GIF
2. 手动导入SDK
下载当前最新版本,解压缩后获得3个文件夹
BQMM
BQMM_EXT
BQMM_GIF
BQMM
中包含SDK所需的资源文件BQMM.bundle
和库文件BQMM.framework
;BQMM_EXT
提供了SDK的默认消息显示控件和消息默认格式的开源代码,开发者们导入后可按需修改;BQMM_GIF
中包含gif表情的UI模块,开发者导入后可按需修改。
3. 添加系统库依赖
您除了在工程中导入 SDK 之外,还需要添加libz动态链接库。
第二步:获取必要的接入信息
开发者将应用与SDK进行对接时,必要接入信息如下
appId
- 应用的App IDappSecret
- 应用的App Secret
如您暂未获得以上接入信息,可以在此申请
第三步:开始集成
0. 注册AppId&AppSecret、设置SDK语言和区域
在 AppDelegate
的 -application:didFinishLaunchingWithOptions:
中添加:
// 初始化SDK
[[MMEmotionCentre defaultCentre] setAppId:@“your app id” secret:@“your secret”]
//设置SDK语言和区域
[MMEmotionCentre defaultCentre].sdkLanguage = MMLanguageEnglish;
[MMEmotionCentre defaultCentre].sdkRegion = MMRegionChina;
1. 在App重新打开时清空session
在 AppDelegate
的 - (void)applicationWillEnterForeground:
中添加:
[[MMEmotionCentre defaultCentre] clearSession];
2. 使用表情键盘和GIF搜索模块
设置SDK代理
放在当前显示的UIViewController中,以接收表情键盘的事件
- (void)viewWillAppear:(BOOL)animated {
....
[MMEmotionCentre defaultCentre].delegate = self;
....
}
配置GIF搜索模块
放在当前显示的UIViewController中:
- (void)viewWillAppear:(BOOL)animated {
....
[[MMGifManager defaultManager] setSearchModeEnabled:true withInputView:_inputToolBar.inputTextView];
[[MMGifManager defaultManager] setSearchUiVisible:true withAttatchedView:_inputToolBar];
__weak typeof(self) weakSelf = self;
[MMGifManager defaultManager].selectedHandler = ^(MMGif * _Nullable gif) {
__strong MMChatViewController *strongSelf = weakSelf;
if (strongSelf) {
[strongSelf didSendGifMessage:gif];
}
};
....
}
-(void)didSendGifMessage:(MMGif *)gif {
//发送GIF表情
//Code Demo见:消息的编码及发送
}
实现SDK代理方法
#pragma mark - *MMEmotionCentreDelegate
//点击键盘中大表情的代理
- (void)didSelectEmoji:(MMEmoji *)emoji
{
//发送大表情消息
//清空输入框
//Code Demo见:消息的编码及发送
}
//点击联想表情的代理 (`deprecated`)
- (void)didSelectTipEmoji:(MMEmoji *)emoji
{
//已废弃
}
//点击表情小表情键盘上发送按钮的代理
- (void)didSendWithInput:(UIResponder<UITextInput> *)input
{
//发送图文混排消息
//清空输入框
//Code Demo见:消息的编码及发送
}
//点击输入框切换表情按钮状态
- (void)tapOverlay
{
self.faceButton.selected = NO;
}
//点击键盘中的gif按钮
- (void)didClickGifTab {
//展示热门表情
[[MMGifManager defaultManager] setSearchModeEnabled:true withInputView:_inputToolBar.inputTextView];
[[MMGifManager defaultManager] setSearchUiVisible:true withAttatchedView:_inputToolBar];
[[MMGifManager defaultManager] showTrending];
}
触发表情键盘展示(点击打开表情键盘按钮触发)
if (!_inputTextView.isFirstResponder) {
[_inputTextView becomeFirstResponder];
}
[[MMEmotionCentre defaultCentre] attachEmotionKeyboardToInput:_inputTextView];
由表情键盘切换为普通键盘(点击打开表情键盘按钮触发)
[[MMEmotionCentre defaultCentre] switchToDefaultKeyboard];
3. 添加表情联想(deprecated
)
[[MMEmotionCentre defaultCentre] shouldShowShotcutPopoverAboveView:self.faceButton withInput:self.inputTextView];
4. 使用表情消息编辑控件
SDK提供UITextView+BQMM
作为表情编辑控件的扩展实现,可以以图文混排方式编辑,并提取编辑内容。 消息编辑框需要使用此控件,在适当位置引入头文件
#import <BQMM/BQMM.h>
5.消息的编码及发送(环信Demo):
表情相关的消息需要编码成extData
放入IM的普通文字消息的扩展字段,发送到接收方进行解析。
extData
是SDK推荐的用于解析的表情消息发送格式(在环信版Demo中作为消息扩展message.ext[@"msg_data"]
发送),格式是一个二维数组,内容为拆分完成的text
和emojiCode
,并且说明这段内容是否是一个emojiCode
。例:
@[@[@"你好", @"0"], @[@"hhd", @"1"]], @[@"hhd", @"2"]]
0
表示文本内容,1
表示小表情emojiCode
,2
表示大表情emojiCode
。
BQMM_EXT中提供了MMTextParser
,可以实现textImgArray
、characterMMText
、emoji
到extData
的转换。
+ (NSArray *)extDataWithTextImageArray:(NSArray *)textImageArray;
+ (NSArray *)extDataWithEmoji:(MMEmoji *)emoji;
编码示例:
图文混排消息
- (void)didSendTextMessageWithTextView:(UITextView *)textView {
/**获取数据**/
NSString *sendStr = textView.characterMMText;
NSArray *textImgArray = textView.textImgArray;
/**图文混排消息编码**/
NSDictionary *mmExt = @{
@"txt_msgType": @"emojitype",
@"msg_data": [MMTextParser extDataWithTextImageArray:textImgArray]};
[self sendTextMessage:sendStr withExt:mmExt];
}
大表情消息
-(void)sendMMFaceMessage:(MMEmoji *)emoji
{
/**大表情编码**/
NSDictionary *ext = @{
@"txt_msgType":@"facetype",
@"msg_data":[MMTextParser extDataWithEmoji:emoji]};
EMMessage *tempMessage = [ChatSendHelper sendTextMessageWithString:
[NSString stringWithFormat:@"[%@]", emoji.emojiName]
toUsername:_conversation.chatter
messageType:[self messageType]
requireEncryption:NO ext:ext];
[self addMessage:tempMessage];
}
Gif表情消息
-(void)sendGifMessage:(MMGif *)gif {
/**Gif表情编码**/
NSString *sendStr = [@"[" stringByAppendingFormat:@"%@]", gif.text];
NSDictionary *msgData = @{@"sticker_url": gif.mainImage,
@"is_gif": (gif.isAnimated ? @"1" : @"0"),
@"data_id": gif.imageId,
@"w": @((float)gif.size.width),
@"h": @((float)gif.size.height)};
NSDictionary *extDic = @{@"txt_msgType":TEXT_MESG_WEB_TYPE,
@"msg_data":msgData};
EMMessage *message = [EaseSDKHelper sendTextMessage:sendStr
to:self.conversation.conversationId
messageType:[self _messageTypeFromConversationType]
messageExt:extDic];
[self _sendMessage:message];
}
6. 表情消息的解析
混排消息的解析
从消息的扩展中解析出extData
NSDictionary *extDic = messageModel.ext;
if (extDic != nil && [extDic[@"txt_msgType"] isEqualToString:@"emojitype"]) {
NSArray *extData = extDic[@"msg_data"];
}
单个大表情解析
从消息的扩展中解析出大表情(MMEmoji)的emojiCode
NSDictionary *extDic = messageModel.ext;
if (extDic != nil && [extDic[@"txt_msgType"] isEqualToString:@"facetype"]) {
NSString *emojiCode = nil;
if (extDic[@"msg_data"]) {
emojiCode = extDic[@"msg_data"][0][0];
}
}
Gif表情解析
从消息的扩展中解析出Gif表情(MMGif)的imageId和mainImage
NSDictionary *extDic = messageModel.ext;
if (extDic != nil && [extDic[@"txt_msgType"] isEqualToString:@"webtype"]) {
NSDictionary *msgData = extDic[@"msg_data"];
if (msgData) {
NSString *gifUrl = msgData[@"sticker_url"];
NSString *gifId = msgData[@"data_id"];
}
}
7. 表情消息显示
混排消息
SDK提供MMTextView
作为显示图文混排表情消息的展示。使用方法:
初始化:
_textView = [[MMTextView alloc] initWithFrame:CGRectZero];
_textView.mmFont = [UIFont systemFontOfSize:LABEL_FONT_SIZE];
_textView.mmTextColor = [UIColor blackColor];
_textView.backgroundColor = [UIColor clearColor];
_textView.userInteractionEnabled = NO;
_textView.multipleTouchEnabled = NO;
[self addSubview:_textView];
设置数据:
[_textView setMmTextData:extData];
另外,开发者可参照MMTextView
中的updateAttributeTextWithData:completionHandler:
方法定义自己的表情消息显示方式。参数extData
是拆分过的文本和emojiCode
。
- (void)updateAttributeTextWithData:(NSArray*)extData completionHandler:(void(^)(void))completionHandler {
NSMutableArray *codes = [NSMutableArray array];
__block NSMutableArray *textImgArray = [NSMutableArray array];
for (NSArray *obj in extData) {
NSString *str = obj[0];
BOOL isEmoji = [obj[1] integerValue] == 0 ? NO : YES;
if (isEmoji) {
if (![codes containsObject:str]) {
[codes addObject:str];
}
}
[textImgArray addObject:str];
}
//
[[MMEmotionCentre defaultCentre] fetchEmojisByType:MMFetchTypeAll codes:codes completionHandler:^(NSArray *emojis) {
NSMutableAttributedString *mAStr = [[NSMutableAttributedString alloc] init];
for (MMEmoji *emoji in emojis) {
NSInteger objIndex = [textImgArray indexOfObject:emoji.emojiCode];
while (objIndex != NSNotFound) {
[textImgArray replaceObjectAtIndex:objIndex withObject:emoji];
objIndex = [textImgArray indexOfObject:emoji.emojiCode];
}
}
for (id obj in textImgArray) {
if ([obj isKindOfClass:[MMEmoji class]]) {
MMTextAttachment *attachment = [[MMTextAttachment alloc] init];
attachment.emoji = obj;
if ([attachment.image.images count] > 1) {
attachment.image = [attachment placeHolderImage];
}
[mAStr appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
} else {
[mAStr appendAttributedString:[[NSAttributedString alloc] initWithString:obj]];
}
}
if (self.mmFont) {
[mAStr addAttribute:NSFontAttributeName value:self.mmFont range:NSMakeRange(0, mAStr.length)];
}
if (self.mmTextColor) {
[mAStr addAttribute:NSForegroundColorAttributeName value:self.mmTextColor range:NSMakeRange(0, mAStr.length)];
}
self.attributedText = mAStr;
if (completionHandler) {
completionHandler();
}
}];
}
大表情消息 && gif表情消息
SDK 提供 MMImageView
来显示单个大表情及gif表情
大表情
imageView = [[MMImageView alloc] initWithFrame:CGRectZero];
//emojiCode是MMEmoji的emojiCode字段
[imageView setImageWithEmojiCode:emojiCode];
[imageView setImageWithEmojiCode:(NSString * _Nonnull)emojiCode completHandler:^(BOOL success) {}];
gif表情
imageView = [[MMImageView alloc] initWithFrame:CGRectZero];
//webStickerUrl是MMGif的mainImage字段,gifId是MMGif的imageId字段
[imageView setImageWithUrl:webStickerUrl gifId:webStickerId];
[imageView setImageWithUrl:webStickerUrl gifId:webStickerId completHandler:^(BOOL success) {}];
MMImageView
提供了类方法来计算图片的尺寸:
//size: 图片的尺寸
//imgMaxSize: 给定的最大的尺寸
+ (CGSize)sizeForImageSize:(CGSize)size imgMaxSize: (CGSize)mSize;
8. gif搜索模块UI定制
BQMM_GIF
是一整套gif搜索UI模块的实现源码,可用于直接使用或用于参考实现gif搜索,及gif消息的发送解析。
gif搜索源码说明
gif相关的功能由MMGifManager
集中管理:
1.设置搜索模式的开启和关闭;指定输入控件
- (void)setSearchModeEnabled:(BOOL)enabled withInputView:(UIResponder<UITextInput> *_Nullable)input;
2.设置是否显示搜索出的表情内容;指定表情内容的显示位置
- (void)setSearchUiVisible:(BOOL)visible withAttatchedView:(UIView *_Nullable)attachedView;
3.通过MMSearchModeStatus
管理搜索模式的开启和关闭及搜索内容的展示和收起(MMSearchModeStatus可自由调整)
typedef NS_OPTIONS (NSInteger, MMSearchModeStatus) {
MMSearchModeStatusKeyboardHide = 1 << 0, //收起键盘
MMSearchModeStatusInputEndEditing = 1 << 1, //收起键盘
MMSearchModeStatusInputBecomeEmpty = 1 << 2, //输入框清空
MMSearchModeStatusInputTextChange = 1 << 3, //输入框内容变化
MMSearchModeStatusGifMessageSent = 1 << 4, //发送了gif消息
MMSearchModeStatusShowTrendingTriggered = 1 << 5,//触发流行表情
MMSearchModeStatusGifsDataReceivedWithResult = 1 << 6, //收到gif数据
MMSearchModeStatusGifsDataReceivedWithEmptyResult = 1 << 7, //搜索结果为空
};
- (void)updateSearchModeAndSearchUIWithStatus:(MMSearchModeStatus)status;
9. UI定制
SDK通过MMTheme
提供一定程度的UI定制。具体参考类说明MMTheme。
创建一个MMTheme
对象,设置相关属性, 然后[[MMEmotionCentre defaultCentre] setTheme:]即可修改商店和键盘样式。
10. 清除缓存
调用clearCache
方法清除缓存,此操作会删除所有临时的表情缓存,已下载的表情包不会被删除。建议在- (void)applicationWillTerminate:(UIApplication *)application
方法中调用。
11. 设置APP UserId
开发者可以用setUserId
方法设置App UserId,以便在后台统计时跟踪追溯单个用户的表情使用情况。