SDK 接入说明

优质
小牛编辑
120浏览
2023-12-01

接入SDK,有以下必要步骤:

  1. 下载与安装
  2. 获取必要的接入信息
  3. 开始集成

第一步:下载与安装

目前有两种方式安装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 ID
  • appSecret - 应用的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"]发送),格式是一个二维数组,内容为拆分完成的textemojiCode,并且说明这段内容是否是一个emojiCode。例:

@[@[@"你好", @"0"], @[@"hhd", @"1"]], @[@"hhd", @"2"]]

0表示文本内容,1表示小表情emojiCode2表示大表情emojiCode

BQMM_EXT中提供了MMTextParser,可以实现textImgArraycharacterMMTextemojiextData的转换。

+ (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,以便在后台统计时跟踪追溯单个用户的表情使用情况。