iOS环信 实现发送轨迹+发送订单

第一次使用环信,只是使用EaseUI简单的实现了客户与客服聊天的功能,后来加了需求,要实现发送轨迹,什么事轨迹?就是用户在浏览一件商品,然后点击客服,我们会自动将用户正在浏览的商品发送给客服,这就是轨迹,发送订单是一样的意思。为了实现这个功能,我浏览了环信的文档,结果只是在客服文档->多渠道集成->APP渠道集成中发现了发送轨迹的一些东西:

当APP用户浏览某个商品页时点击“联系客服”,APP可自动将该商品链接发送给客服。
要实现该功能,需在消息中增加扩展字段msgtype。
消息格式:
{ ext:{
    msgtype:{
      // 用户轨迹消息
      track:{
        // 消息标题
        title:       "我正在看:",
        // 商品价格
        price:       "¥: 235.00",
        // 商品描述
        desc:        "女装小香风气质蕾丝假两件短袖",
        // 商品图片链接
        img_url:     "http://yourdomain.com/img/a.jpg",
        // 商品页面链接
        item_url:    "http://yourdomain.com/item/a.html"
      }
    }
  }
}

貌似文档里只有这个与轨迹沾边了,因为文档写的不具体,所以我去咨询了环信客服,客服告诉我需要使用拓展功能,在环信3.0文档->iOS客户端集成->消息 里

构造扩展消息
当 SDK 提供的消息类型不满足需求时,开发者可以通过扩展自 SDK 提供的文本、语音、图片、位置等消息类型,从而生成自己需要的消息类型。
这里是扩展自文本消息,如果这个自定义的消息需要用到语音或者图片等,可以扩展自语音、图片消息,亦或是位置消息。

// 以单聊消息举例
EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"要发送的消息"];
NSString *from = [[EMClient sharedClient] currentUsername];
//生成Message
EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt];
message.chatType = EMChatTypeChat;// 设置为单聊消息
//message.chatType = EMChatTypeGroupChat;// 设置为群聊消息
//message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息
message.ext = @{@"key":@"value"}; // 扩展消息部分

看到这,我刚明白了一些东西,需要把图1中的字典放到图2的message对象的ext属性下,图1的字典中的字段需要完全一样,写到这里,我以为就可以了,就可以发送轨迹了,但没有成功,代码如下,我是写在了viewDidLoad里了,这样一进来就可以发送了

- (void)sendOrder
{
    NSDictionary *photoDict = self.model.photos[0];
    NSDictionary *priceDict = self.model.price;
    NSString *item_url = [NSString stringWithFormat:@"%@goods/%@", GOODSURL, self.model.goodsId];
    NSDictionary *ext = @{@"msgtype":@{
                                  //用户轨迹消息
                                  @"track":@{
                                          // 消息标题
                                          @"title":@"我正在看:",
                                          // 商品价格
                                          @"price":[NSString stringWithFormat:@"%@ %@", priceDict[@"price"], ISSTRINGEMPTY(priceDict[@"currency"])],
                                          // 商品描述
                                          @"desc":self.model.name,
                                          // 商品图片链接
                                          @"img_url":photoDict[@"small"],
                                          // 商品页面链接
                                          @"item_url":item_url
                                          }
                                  }
                          };
    EMMessage *message = [EaseSDKHelper sendTextMessage:@"order"
                                                     to:self.conversation.conversationId
                                            messageType:EMChatTypeChat
                                             messageExt:ext];
    message.chatType = EMChatTypeChat;
    message.ext = ext;
    
    [self addMessageToDataSource:message progress:nil];
    [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {
        if (!aError) {
// // 这个方法本来是写在EaseMessageViewController这个类的.m里的,我把接口写在了.h里,这样我们就可以调用了
            [self _refreshAfterSentMessage:aMessage];
            [self.tableView reloadData];
        }else {
            [[Hud sharedHud] hudtipApprearWithView:self.view Title:@"发送失败"];
            [self.tableView reloadData];
        }
    }];
}

后来又咨询了环信客服,客服非常淡定的告诉我,UI需要自定义。。。瞬间一万个草泥马飘过啊,原来没有写好的,还需要自定义,没办法,继续开始查文档,后来看到了EaseUI的文档,发现了可以实现自定义Cell的方法:

实现自定义聊天样式
EaseMessageViewControllerDelegate
获取自定义消息 cell,根据 messageModel,用户自己判断是否显示自定义消息 cell。如果返回 nil 会显示默认;如果返回 cell 会显示用户自定义消息cell。
/*!
 @method
 @brief 获取消息自定义cell
 @discussion 用户根据messageModel判断是否显示自定义cell。返回nil显示默认cell,否则显示用户自定义cell
 @param tableView 当前消息视图的tableView
 @param messageModel 消息模型
 @result 返回用户自定义cell
 */
- (UITableViewCell *)messageViewController:(UITableView *)tableView
                       cellForMessageModel:(id)messageModel;
 
/*!
 @method
 @brief 获取消息cell高度
 @discussion 用户根据messageModel判断,是否自定义显示cell的高度
 @param viewController 当前消息视图
 @param messageModel 消息模型
 @param cellWidth 视图宽度
 @result 返回用户自定义cell
 */
- (CGFloat)messageViewController:(EaseMessageViewController *)viewController
           heightForMessageModel:(id)messageModel
                   withCellWidth:(CGFloat)cellWidth;
 
//具体创建自定义Cell的样例:
- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id)model
{
    //样例为如果消息是文本消息显示用户自定义cell
    if (model.bodyType == eMessageBodyType_Text) {
        NSString *CellIdentifier = [CustomMessageCell cellIdentifierWithModel:model];
        //CustomMessageCell为用户自定义cell,继承了EaseBaseMessageCell
        CustomMessageCell *cell = (CustomMessageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[CustomMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:model];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
        }
        cell.model = model;
        return cell;
    }
    return nil;
}
 
- (CGFloat)messageViewController:(EaseMessageViewController *)viewController
           heightForMessageModel:(id)messageModel
                   withCellWidth:(CGFloat)cellWidth
{
    //样例为如果消息是文本消息使用用户自定义cell的高度
    if (messageModel.bodyType == EMMessageBodyTypeText) {
        //CustomMessageCell为用户自定义cell,继承了EaseBaseMessageCell
        return [CustomMessageCell cellHeightWithModel:messageModel];
    }
    return 0.f;
}

ok,思路有了,开始照着这个文档写,自定义一个cell,继承于EaseBaseMessageCell,在自定义的.m里需要继承如下方法:

- (BOOL)isCustomBubbleView:(id)model
{
    return YES;
}

- (void)setCustomBubbleView:(id)model
{
   // 这里创建自定义的view
}

- (void)setCustomModel:(id)model
{
// 这里边给view赋值
}
- (void)updateCustomBubbleViewMargin:(UIEdgeInsets)bubbleMargin model:(id)mode
{
    NSLog(@"-----哈哈 %@ %@", mode.message.ext, self.bubbleView.backgroundImageView);
}

+ (NSString *)cellIdentifierWithModel:(id)model
{
    return @"CustomOrderCell";
}

+ (CGFloat)cellHeightWithModel:(id)model
{
    return 120;
}

然后在我自定义的VC里写代理回调,我自定义的VC继承与EaseUI的EaseMessageViewController类

#pragma mark - EaseMessageViewControllerDelegate
- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id)messageModel
{
// 因为bodyType类型选择text类型就行了,所以我给text传了个order,用来判断当前我是否用我自己写的自定义的cell,DMCustomOrderTableViewCell是我自定义的cell
    if (messageModel.bodyType == EMMessageBodyTypeText) {
        if ([messageModel.text isEqualToString:@"order"]) {
            NSString *CellIdentifier = [DMCustomOrderTableViewCell cellIdentifierWithModel:messageModel];
            DMCustomOrderTableViewCell *cell = (DMCustomOrderTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            if (cell == nil) {
                cell = [[DMCustomOrderTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:messageModel];
                //  此处的delegate为EaseMessageCellDelegate,我们的vc需要代理它,用来实现点击这个自定义的cell实现跳转的功能
                cell.delegate = self;
                cell.selectionStyle = UITableViewCellSelectionStyleNone;
            }
            cell.model = messageModel;
            return cell;
        }else {
            return nil;
        }
    }else {
        return nil;
    }
}
- (CGFloat)messageViewController:(EaseMessageViewController *)viewController heightForMessageModel:(id)messageModel withCellWidth:(CGFloat)cellWidth
{
    if (messageModel.bodyType == EMMessageBodyTypeText) {
        if ([messageModel.text isEqualToString:@"order"]) {
            return [DMCustomOrderTableViewCell cellHeightWithModel:messageModel];
        }else {
            return 0.f;
        }
    }else {
        return 0.f;
    }
}
// 这个方法会由下面代码块里的messageCellSelected方法回调回来,然后跳转到商品详情,你也可以自定义需要跳转到哪里
- (BOOL)messageViewController:(EaseMessageViewController *)viewController didSelectMessageModel:(id)messageModel
{
    if (messageModel.bodyType == EMMessageBodyTypeText) {
        if ([messageModel.text isEqualToString:@"order"]) {
            NSLog(@"商品链接 = %@", messageModel.message.ext[@"msgtype"][@"track"][@"item_url"]);
            DMServiceDetailViewController *detailVC = [[DMServiceDetailViewController alloc] init];
            detailVC.goodsDetailUrl = messageModel.message.ext[@"msgtype"][@"track"][@"item_url"];
            [self.navigationController pushViewController:detailVC animated:YES];
            return YES;
        }else {
            return NO;
        }
    }else {
        return NO;
    }
}

ok,这里基本上就实现了自定义的聊天cell显示出来的效果,下一步我们实现点击这个cell跳转的需求,上边的代码里我有写我们需要代理EaseMessageCellDelegate,实现如下方法:

#pragma mark - EaseMessageCellDelegate
// 这个方法会回调上边代码块里的- (BOOL)messageViewController:(EaseMessageViewController *)viewController didSelectMessageModel:(id)messageModel方法
- (void)messageCellSelected:(id)model
{
    NSLog(@"---0.0 %@", model.message.ext);
    if (model.bodyType == EMMessageBodyTypeText) {
        if ([model.text isEqualToString:@"order"]) {
            NSLog(@"商品链接 = %@", model.message.ext[@"msgtype"][@"track"][@"item_url"]);
            if (self.delegate && [self.delegate respondsToSelector:@selector(messageViewController:didSelectMessageModel:)]) {
                BOOL flag = [self.delegate messageViewController:self didSelectMessageModel:model];
                if (flag) {
// 这个方法本来是写在EaseMessageViewController这个类的.m里的,我把接口写在了.h里,这样我们就可以调用了
                    [self _sendHasReadResponseForMessages:@[model.message] isRead:YES];
                    return;
                }
            }
        }
    }
}
- (void)statusButtonSelcted:(id)model withMessageCell:(EaseMessageCell*)messageCell
{
    NSLog(@"+++0.0");
}
- (void)avatarViewSelcted:(id)model
{
    NSLog(@"\\\\0.0");
}

ok,我们已经完成了环信自定义cell的东西,时间比较赶,没有太细致的走这个流程,我感觉我的代理回调还是有问题,我只不过走歪路给写出来了,还没细致看具体的流程应该怎么写,希望能够帮到各位,欢迎各位指教,谢谢!

你可能感兴趣的:(iOS环信 实现发送轨迹+发送订单)