美文网首页ios 知识点
iOS开发集成腾讯云IM即时通讯

iOS开发集成腾讯云IM即时通讯

作者: mrChan1234 | 来源:发表于2019-03-23 17:31 被阅读0次

最近做的项目里公司说明确要用腾讯云的IM,传送门:https://cloud.tencent.com/product/im?fromSource=gwzcw.471467.471467.471467,刚开始集成会发现有很多坑点,下面让我们一步一步来集成:
首先 podfile加入:

pod 'TXIMSDK_iOS'

pod install一下就会发现 腾讯云的通讯基础SDK已经被引入进来了,可以进行socket连接互相发送消息了,但是UI框架是没有的,所以还是得去下载他的demo去研究一波,
,将下面这个TUIKit工程拖入项目文件目录下:


屏幕快照 2019-03-23 下午5.07.12.png

首先选择TUIKit的target编译一波,然后退出Xcode,然后再编译一波自己的工程target,如果不报错,那就可以集成进去了,注意,这里如果报错的话,几乎都是framework路径设置引用问题,自己直接去search path设置那里面看就行。
通常做IM最核心的东西人家已经给我们做好了,接下来就是自定义气泡消息了,这里得看懂他代码是怎么写的,进去你会发现有几个基类的类:我们要做的就是重写那几个基类就行:

公司职位信息气泡:CompanyInfoCell.h:

#import <UIKit/UIKit.h>
#import "TMessageCell.h"
#import "JobCell.h"
#import "JobModel.h"

@protocol companyInfoDelegate <NSObject>

- (void)companyInfoClickedWithContent:(JobModel *)model;


@end
NS_ASSUME_NONNULL_BEGIN

@interface CompanyInfoCellData :TMessageCellData

@property (nonatomic,strong)NSString *totalContent;

@end
@interface CompanyInfoCell : TMessageCell

@property (nonatomic, strong) UIView *containerView;

@property (nonatomic,strong)JobCell *jobCell;

@property(nonatomic,weak) id <companyInfoDelegate> companyInfoDelegate;


+ (NSString *)cellIdentifier;


@end

NS_ASSUME_NONNULL_END

CompanyInfoCell.m:

#import "CompanyInfoCell.h"
#import <TUIKit.h>
#import <THeader.h>
@implementation CompanyInfoCellData



@end

@interface CompanyInfoCell () {
    
}

@end
@implementation CompanyInfoCell

- (CGFloat)getHeight:(CompanyInfoCellData *)data;
{
    return 200;
}


- (void)setData:(CompanyInfoCellData *)data;
{
    //update layout
    _containerView.frame = CGRectMake(25, TMessageCell_Padding, Screen_Width -50, 180);
    _jobCell.frame = _containerView.bounds;
    [_containerView layoutSubviews];
    // MARK: - setCellWithData
    JobModel *model = [JobModel  new];
    NSDictionary *json  = [data.totalContent mj_JSONObject];
    NSDictionary *bodyJson = [[json objectForKey:kMessageBody] mj_JSONObject];
//    [_jobCell setCellWithData:[JobModel mj_objectWithKeyValues:bodyJson]];
    [_jobCell setPostion:[CompanyInFoDataModel mj_objectWithKeyValues:bodyJson]];
}

- (void)setupViews {
    self.backgroundColor = [UIColor clearColor];
    
    _containerView = [[UIView alloc] init];
    _containerView.backgroundColor = [UIColor whiteColor];
    _containerView.layer.borderColor = [UIColor grayColor].CGColor;
    _containerView.layer.cornerRadius = 5.0;
    [_containerView.layer setMasksToBounds:YES];
    [self addSubview:_containerView];
    self.selectionStyle = UITableViewCellSelectionStyleNone;
    _jobCell = [[JobCell alloc] initWithStyle:0 reuseIdentifier:NSStringFromClass([JobCell class])];
    [_containerView addSubview:_jobCell];
   UITapGestureRecognizer *tap =  [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(buttonAction:)];
    [_containerView addGestureRecognizer: tap];
}

// MARK: - private Method
- (void)buttonAction:(id)sender {
    if (_companyInfoDelegate &&[_companyInfoDelegate respondsToSelector:@selector(companyInfoClickedWithContent:)]) {
        [_companyInfoDelegate companyInfoClickedWithContent:_jobCell.model];
    }
}


+ (NSString *)cellIdentifier {
    return NSStringFromClass([self class]);
}

CompanyInFoDataModel.h:

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface CompanyInFoDataModel : NSObject

/*
 
 {"degreeRequirement":"博士",
 "enterpriseName":"深圳市xxxxx公司",
 "expectJobCity":"101280600",
 "experienceRequirement":"10年以上",
 "financingStage":"天使轮",
 "headPortrait":"http://.oss-cn-hangzhou.aliyuncs.com/S8PeJn_%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20190320174739.jpg",
 "launchCommunicativeTimeStamp":1553326495,
 "nickname":"苏海峰",
 "positionName":"前端开发",
 "salaryHighestRequirement":2000.00,
 "salaryMinimumRequirement":1000.00,
 "synopsis":"由你发起的沟通",
 "workDetailedAddress":"深圳市路通网络技术有限公司"}
 */

@property (nonatomic,strong)NSString *degreeRequirement;

@property (nonatomic,strong)NSString *enterpriseName;

@property (nonatomic,strong)NSString *financingStage;

@property (nonatomic,strong)NSString *expectJobCity;

@property (nonatomic,strong)NSString *experienceRequirement;

@property (nonatomic,strong)NSString *headPortrait;

@property (nonatomic,assign)NSInteger launchCommunicativeTimeStamp;

@property (nonatomic,strong)NSString *nickname;

@property (nonatomic,strong)NSString *positionName;

@property (nonatomic,strong)NSString *salaryHighestRequirement;

@property (nonatomic,strong)NSString *salaryMinimumRequirement;

@property (nonatomic,strong)NSString *synopsis;

@property (nonatomic,strong)NSString *workDetailedAddress;

@end

NS_ASSUME_NONNULL_END

接下来就是在消息控制器里加入我门自定义的气泡cell了:

#define kMessageType @"TIM_CUSTOM_MESSAGE_TYPE"
#define kMessageBody @"TIM_CUSTOM_MESSAGE_CONTENT"

// MARK: - bubbleType

#define  kTIM_CUSTOM_MESSAGE_CHAT_RESUME_INFO @"TIM_CUSTOM_MESSAGE_CHAT_RESUME_INFO"
#define kTIM_CUSTOM_MESSAGE_CHAT_POSITIONS_INFO @"TIM_CUSTOM_MESSAGE_CHAT_POSITIONS_INFO"

TMessageController.h:

#import <UIKit/UIKit.h>
#import "TMessageCell.h"
#import "TConversationCell.h"

@class TMessageController;
@protocol TMessageControllerDelegate <NSObject>
- (void)didTapInMessageController:(TMessageController *)controller;
- (void)didHideMenuInMessageController:(TMessageController *)controller;
- (BOOL)messageController:(TMessageController *)controller willShowMenuInView:(UIView *)view;
- (void)messageController:(TMessageController *)controller didSelectMessages:(NSMutableArray *)msgs atIndex:(NSInteger)index;
@end

@interface TMessageController : UIViewController
@property (nonatomic, weak) id<TMessageControllerDelegate> delegate;
- (void)sendMessage:(TMessageCellData *)msg;
- (void)scrollToBottom:(BOOL)animate;
- (void)setConversation:(TConversationCellData *)conversation;
- (void)sendImageMessage:(UIImage *)image;
- (void)sendVideoMessage:(NSURL *)url;
- (void)sendFileMessage:(NSURL *)url;

// MARK: - add
- (void)sendCompanyInfoMessage:(NSString *)companyJsonContent;


- (void)sendContctInfoAndResume:(NSString *)contactInfoContent;

@end

TMessageController.m:(致谢新增或者改动的几个method):

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSObject *data = _uiMsgs[indexPath.row];
    TMessageCell *cell = nil;
    if([data isKindOfClass:[TTextMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TTextMessageCell_ReuseId];
        if(!cell){
            cell = [[TTextMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TTextMessageCell_ReuseId];
            cell.delegate = self;
        }
    }
    else if([data isKindOfClass:[TVoiceMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TVoiceMessageCell_ReuseId];
        if(!cell){
            cell = [[TVoiceMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TVoiceMessageCell_ReuseId];
            cell.delegate = self;
        }
    }
    else if([data isKindOfClass:[TImageMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TImageMessageCell_ReuseId];
        if(!cell){
            cell = [[TImageMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TImageMessageCell_ReuseId];
            cell.delegate = self;
        }
    }
    else if([data isKindOfClass:[TSystemMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TSystemMessageCell_ReuseId];
        if(!cell){
            cell = [[TSystemMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TSystemMessageCell_ReuseId];
            cell.delegate = self;
        }
    }
    else if([data isKindOfClass:[TFaceMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TFaceMessageCell_ReuseId];
        if(!cell){
            cell = [[TFaceMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TFaceMessageCell_ReuseId];
            cell.delegate = self;
        }
    }
    else if([data isKindOfClass:[TVideoMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TVideoMessageCell_ReuseId];
        if(!cell){
            cell = [[TVideoMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TVideoMessageCell_ReuseId];
            cell.delegate = self;
        }
    }
    else if([data isKindOfClass:[TFileMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TFileMessageCell_ReuseId];
        if(!cell){
            cell = [[TFileMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TFileMessageCell_ReuseId];
            cell.delegate = self;
        }
        // MARK: - ####################add
    } else if ([data isKindOfClass:[CompanyInfoCellData class]]) {
        cell = [tableView dequeueReusableCellWithIdentifier:[CompanyInfoCell cellIdentifier]];
        if (!cell) {
            cell = [[CompanyInfoCell alloc] initWithStyle:0 reuseIdentifier:[CompanyInfoCell cellIdentifier]];
            cell.delegate = self;
            ((CompanyInfoCell *)cell).companyInfoDelegate = self;

        }
    } else if ([data isKindOfClass:[InfoCellData class]]) {
        // MARK: - add
        cell = [tableView dequeueReusableCellWithIdentifier:[InfoCell cellIdentifier]];
        if (!cell) {
            cell = [[InfoCell alloc] initWithStyle:0 reuseIdentifier:[InfoCell cellIdentifier]];
            cell.delegate = self;
            ((InfoCell *)cell).infoDelegate = self;
        }
    }
    [cell setData:_uiMsgs[indexPath.row]];
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGFloat height = 0;
    if(_heightCache.count > indexPath.row){
        return [_heightCache[indexPath.row] floatValue];
    }
    NSObject *data = _uiMsgs[indexPath.row];
    if([data isKindOfClass:[TTextMessageCellData class]]){
        TTextMessageCellData *text = _uiMsgs[indexPath.row];
        TTextMessageCell *cell = [[TTextMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TTextMessageCell_ReuseId];
        height = [cell getHeight:text];
    }else if([data isKindOfClass:[TVoiceMessageCellData class]]){
        TVoiceMessageCellData *voice = _uiMsgs[indexPath.row];
        TVoiceMessageCell *cell = [[TVoiceMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TVoiceMessageCell_ReuseId];
        height = [cell getHeight:voice];
    }
    else if([data isKindOfClass:[TImageMessageCellData class]]){
        TImageMessageCellData *image = _uiMsgs[indexPath.row];
        TImageMessageCell *cell = [[TImageMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TImageMessageCell_ReuseId];
        height = [cell getHeight:image];
    }
    else if([data isKindOfClass:[TSystemMessageCellData class]]){
        TSystemMessageCellData *system = _uiMsgs[indexPath.row];
        TSystemMessageCell *cell = [[TSystemMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TSystemMessageCell_ReuseId];
        height = [cell getHeight:system];
    }
    else if([data isKindOfClass:[TFaceMessageCellData class]]){
        TFaceMessageCellData *face = _uiMsgs[indexPath.row];
        TFaceMessageCell *cell = [[TFaceMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TFaceMessageCell_ReuseId];
        height = [cell getHeight:face];
    }
    else if([data isKindOfClass:[TVideoMessageCellData class]]){
        TVideoMessageCellData *video = _uiMsgs[indexPath.row];
        TVideoMessageCell *cell = [[TVideoMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TVideoMessageCell_ReuseId];
        height = [cell getHeight:video];
    }
    else if([data isKindOfClass:[TFileMessageCellData class]]){
        TFileMessageCellData *file = _uiMsgs[indexPath.row];
        TFileMessageCell *cell = [[TFileMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TFileMessageCell_ReuseId];
        height = [cell getHeight:file];
        // MARK:######################### - 计算高度
    } else if ([data isKindOfClass:[CompanyInfoCellData class]]) {
        CompanyInfoCellData *info = _uiMsgs[indexPath.row];
        CompanyInfoCell *cell = [[CompanyInfoCell alloc] initWithStyle:0 reuseIdentifier:NSStringFromClass([CompanyInfoCell class])];
        height = [cell getHeight:info];
    } else if ([data isKindOfClass:[InfoCellData class]]) {
        // MARK: - add
        InfoCellData *info = _uiMsgs[indexPath.row];
        InfoCell *cell = [[InfoCell alloc] initWithStyle:0 reuseIdentifier:NSStringFromClass([InfoCell class])];
        height = [cell getHeight:info];
    }
    [_heightCache insertObject:[NSNumber numberWithFloat:height] atIndex:indexPath.row];
    return height;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSObject *data = _uiMsgs[indexPath.row];
    TMessageCell *cell = nil;
    if([data isKindOfClass:[TTextMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TTextMessageCell_ReuseId];
        if(!cell){
            cell = [[TTextMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TTextMessageCell_ReuseId];
            cell.delegate = self;
        }
    }
    else if([data isKindOfClass:[TVoiceMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TVoiceMessageCell_ReuseId];
        if(!cell){
            cell = [[TVoiceMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TVoiceMessageCell_ReuseId];
            cell.delegate = self;
        }
    }
    else if([data isKindOfClass:[TImageMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TImageMessageCell_ReuseId];
        if(!cell){
            cell = [[TImageMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TImageMessageCell_ReuseId];
            cell.delegate = self;
        }
    }
    else if([data isKindOfClass:[TSystemMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TSystemMessageCell_ReuseId];
        if(!cell){
            cell = [[TSystemMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TSystemMessageCell_ReuseId];
            cell.delegate = self;
        }
    }
    else if([data isKindOfClass:[TFaceMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TFaceMessageCell_ReuseId];
        if(!cell){
            cell = [[TFaceMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TFaceMessageCell_ReuseId];
            cell.delegate = self;
        }
    }
    else if([data isKindOfClass:[TVideoMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TVideoMessageCell_ReuseId];
        if(!cell){
            cell = [[TVideoMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TVideoMessageCell_ReuseId];
            cell.delegate = self;
        }
    }
    else if([data isKindOfClass:[TFileMessageCellData class]]){
        cell = [tableView dequeueReusableCellWithIdentifier:TFileMessageCell_ReuseId];
        if(!cell){
            cell = [[TFileMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TFileMessageCell_ReuseId];
            cell.delegate = self;
        }
        // MARK: - ####################add
    } else if ([data isKindOfClass:[CompanyInfoCellData class]]) {
        cell = [tableView dequeueReusableCellWithIdentifier:[CompanyInfoCell cellIdentifier]];
        if (!cell) {
            cell = [[CompanyInfoCell alloc] initWithStyle:0 reuseIdentifier:[CompanyInfoCell cellIdentifier]];
            cell.delegate = self;
            ((CompanyInfoCell *)cell).companyInfoDelegate = self;

        }
    } else if ([data isKindOfClass:[InfoCellData class]]) {
        // MARK: - add
        cell = [tableView dequeueReusableCellWithIdentifier:[InfoCell cellIdentifier]];
        if (!cell) {
            cell = [[InfoCell alloc] initWithStyle:0 reuseIdentifier:[InfoCell cellIdentifier]];
            cell.delegate = self;
            ((InfoCell *)cell).infoDelegate = self;
        }
    }
    [cell setData:_uiMsgs[indexPath.row]];
    return cell;
}
#warning #############################add
// MARK: - #########################Add
-(void)sendCompanyInfoMessage:(NSString *)companyJsonContent {
    CompanyInfoCellData *data = [CompanyInfoCellData new];
    data.totalContent = [self buildExWithMessageType:InfoMessagePostion messageBody:companyJsonContent];
    data.head = TUIKitResource(@"default_head");
    data.isSelf = YES;
    [self sendMessage:data];
}

// MARK: - 发送联系方式  电话 微信 简历
- (void)sendContctInfoAndResume:(NSString *)contactInfoContent  {
    InfoCellData *data = [InfoCellData new];
    data.totalContent = [self buildExWithMessageType:0 messageBody:contactInfoContent];
    data.head = TUIKitResource(@"default_head");
    data.isSelf = YES;
    [self sendMessage:data];
    
}


- (TIMMessage *)transIMMsgFromUIMsg:(TMessageCellData *)data
{
    TIMMessage *msg = [[TIMMessage alloc] init];
    if([data isKindOfClass:[TTextMessageCellData class]]){
        TIMTextElem *imText = [[TIMTextElem alloc] init];
        TTextMessageCellData *text = (TTextMessageCellData *)data;
        imText.text = text.content;
        [msg addElem:imText];
    }
    else if([data isKindOfClass:[TFaceMessageCellData class]]){
        TIMFaceElem *imImage = [[TIMFaceElem alloc] init];
        TFaceMessageCellData *image = (TFaceMessageCellData *)data;
        imImage.index = (int)image.groupIndex;
        imImage.data = [image.faceName dataUsingEncoding:NSUTF8StringEncoding];
        [msg addElem:imImage];
    }
    else if([data isKindOfClass:[TImageMessageCellData class]]){
        TIMImageElem *imImage = [[TIMImageElem alloc] init];
        TImageMessageCellData *uiImage = (TImageMessageCellData *)data;
        imImage.path = uiImage.path;
        [msg addElem:imImage];
    }
    else if([data isKindOfClass:[TVideoMessageCellData class]]){
        TIMVideoElem *imVideo = [[TIMVideoElem alloc] init];
        TVideoMessageCellData *uiVideo = (TVideoMessageCellData *)data;
        imVideo.videoPath = uiVideo.videoPath;
        imVideo.snapshotPath = uiVideo.snapshotPath;
        imVideo.snapshot = [[TIMSnapshot alloc] init];
        imVideo.snapshot.width = uiVideo.snapshotItem.size.width;
        imVideo.snapshot.height = uiVideo.snapshotItem.size.height;
        imVideo.video = [[TIMVideo alloc] init];
        imVideo.video.duration = (int)uiVideo.videoItem.duration;
        imVideo.video.type = uiVideo.videoItem.type;
        [msg addElem:imVideo];
    }
    else if([data isKindOfClass:[TVoiceMessageCellData class]]){
        TIMSoundElem *imSound = [[TIMSoundElem alloc] init];
        TVoiceMessageCellData *uiSound = (TVoiceMessageCellData *)data;
        imSound.path = uiSound.path;
        imSound.second = uiSound.duration;
        imSound.dataSize = uiSound.length;
        [msg addElem:imSound];
    }
    else if([data isKindOfClass:[TFileMessageCellData class]]){
        TIMFileElem *imFile = [[TIMFileElem alloc] init];
        TFileMessageCellData *uiFile = (TFileMessageCellData *)data;
        imFile.path = uiFile.path;
        imFile.fileSize = uiFile.length;
        imFile.filename = uiFile.fileName;
        [msg addElem:imFile];
    } else if ([data isKindOfClass:[CompanyInfoCellData class]]) {
        // MARK: #######################公司信息
        //        TCompanyInfoElement *ele = [TCompanyInfoElement new];
        TIMCustomElem *elt = [TIMCustomElem new];
        CompanyInfoCellData *infoData = (CompanyInfoCellData *)data;
        elt.data = [infoData.totalContent mj_JSONData];
        elt.ext = infoData.totalContent;
        [msg  addElem:elt];
        // MARK: - j#############交换联系方式
    } else if ([data isKindOfClass:[InfoCellData class]]) {
        TIMCustomElem *elt = [TIMCustomElem new];
        InfoCellData *infoData = (InfoCellData *)data;
        elt.data = [infoData.totalContent mj_JSONData];
        elt.ext = infoData.totalContent;
        [msg  addElem:elt];
    }
    data.custom = msg;
    return msg;
    
}


// MARK: - 加载消息去区分
- (NSMutableArray *)transUIMsgFromIMMsg:(NSArray *)msgs
{
    NSMutableArray *uiMsgs = [NSMutableArray array];
    for (NSInteger k = msgs.count - 1; k >= 0; --k) {
        TIMMessage *msg = msgs[k];
        if(![[[msg getConversation] getReceiver] isEqualToString:_conv.convId]){
            continue;
        }
        if(msg.status == TIM_MSG_STATUS_HAS_DELETED){
            continue;
        }
        TMessageCellData *dateMsg = [self transSystemMsgFromDate:msg.timestamp];
        if(dateMsg){
            _msgForDate = msg;
            dateMsg.custom = nil;
            [uiMsgs addObject:dateMsg];
        }
        if(msg.status == TIM_MSG_STATUS_LOCAL_REVOKED){
            TSystemMessageCellData *revoke = [[TSystemMessageCellData alloc] init];
            revoke.content = @"你撤回了一条消息";
            revoke.custom = msg;
            [uiMsgs addObject:revoke];
            continue;
        }
        for (int i = 0; i < msg.elemCount; ++i) {
            TIMElem *elem = [msg getElem:i];
            TMessageCellData *data = nil;
            if([elem isKindOfClass:[TIMTextElem class]]){
                TIMTextElem *text = (TIMTextElem *)elem;
                TTextMessageCellData *textData = [[TTextMessageCellData alloc] init];
                textData.content = text.text;
                data = textData;
            } else if ([elem isKindOfClass:[TIMCustomElem class]]) {
                // MARK: #############################################add
                TIMCustomElem *elt = (TIMCustomElem*) elem;
 MARK: - 这里是根据扩展字段里的type和content来进行区分,这里还有一个坑底那就是 ext扩展字段里的json传据后台说只能进行base64编码,然后客户端这里再进行解码,
                NSString *extension =  [[self base64DecodeString:elt.ext] stringByReplacingOccurrencesOfString:@"this is a example" withString:@""];
//                NSString *extension =  [self base64DecodeString:elt.ext];
//                NSInteger type = [[((NSDictionary *)[extension mj_JSONObject]) objectForKey:kMessageType] integerValue];
                 NSString * type = [((NSDictionary *)[extension mj_JSONObject]) objectForKey:kMessageType];
                // MARK: - 区分消息类型
                /*if (type == InfoMessageTypeTel ||  type == InfoMessageTypeWeChat  ||  type == InfoMessageResume) {
                    // MARK: - 微信 电话 简历
                    InfoCellData *infoData = [InfoCellData new];
                    infoData.totalContent = extension;
                    data = infoData;
                } else if (type == InfoMessagePostion ) {
                    // MARK: - 职位信息
                    CompanyInfoCellData *companData  = [CompanyInfoCellData new];
                    companData.totalContent = extension;
                    data = companData;
                }*/
                
                if ([type isEqualToString:kTIM_CUSTOM_MESSAGE_CHAT_POSITIONS_INFO] ) {
                    // MARK: - 职位信息
                    CompanyInfoCellData *companData  = [CompanyInfoCellData new];
                    companData.totalContent = extension;
                    data = companData;
                }
            }
            else if([elem isKindOfClass:[TIMFaceElem class]]){
                TIMFaceElem *face = (TIMFaceElem *)elem;
                TFaceMessageCellData *faceData = [[TFaceMessageCellData alloc] init];
                faceData.groupIndex = face.index;
                faceData.faceName = [[NSString alloc] initWithData:face.data encoding:NSUTF8StringEncoding];
                for (TFaceGroup *group in [[TUIKit sharedInstance] getConfig].faceGroups) {
                    if(group.groupIndex == faceData.groupIndex){
                        NSString *path = [group.groupPath stringByAppendingPathComponent:faceData.faceName];
                        faceData.path = path;
                        break;
                    }
                }
                data = faceData;
            } else if([elem isKindOfClass:[TIMImageElem class]]){
                TIMImageElem *image = (TIMImageElem *)elem;
                TImageMessageCellData *imageData = [[TImageMessageCellData alloc] init];
                imageData.path = image.path;
                imageData.items = [NSMutableArray array];
                for (TIMImage *item in image.imageList) {
                    TImageItem *itemData = [[TImageItem alloc] init];
                    itemData.uuid = item.uuid;
                    itemData.size = CGSizeMake(item.width, item.height);
                    itemData.url = item.url;
                    if(item.type == TIM_IMAGE_TYPE_THUMB){
                        itemData.type = TImage_Type_Thumb;
                    }
                    else if(item.type == TIM_IMAGE_TYPE_LARGE){
                        itemData.type = TImage_Type_Large;
                    }
                    else if(item.type == TIM_IMAGE_TYPE_ORIGIN){
                        itemData.type = TImage_Type_Origin;
                    }
                    [imageData.items addObject:itemData];
                }
                data = imageData;
            }else if([elem isKindOfClass:[TIMSoundElem class]]){
                TIMSoundElem *sound = (TIMSoundElem *)elem;
                TVoiceMessageCellData *soundData = [[TVoiceMessageCellData alloc] init];
                soundData.duration = sound.second;
                soundData.length = sound.dataSize;
                soundData.uuid = sound.uuid;
                
                data = soundData;
            }else if([elem isKindOfClass:[TIMVideoElem class]]){
                TIMVideoElem *video = (TIMVideoElem *)elem;
                TVideoMessageCellData *videoData = [[TVideoMessageCellData alloc] init];
                videoData.videoPath = video.videoPath;
                videoData.snapshotPath = video.snapshotPath;
                
                videoData.videoItem = [[TVideoItem alloc] init];
                videoData.videoItem.uuid = video.video.uuid;
                videoData.videoItem.type = video.video.type;
                videoData.videoItem.length = video.video.size;
                videoData.videoItem.duration = video.video.duration;
                
                videoData.snapshotItem = [[TSnapshotItem alloc] init];
                videoData.snapshotItem.uuid = video.snapshot.uuid;
                videoData.snapshotItem.type = video.snapshot.type;
                videoData.snapshotItem.length = video.snapshot.size;
                videoData.snapshotItem.size = CGSizeMake(video.snapshot.width, video.snapshot.height);
                
                data = videoData;
            }
            else if([elem isKindOfClass:[TIMFileElem class]]){
                TIMFileElem *file = (TIMFileElem *)elem;
                TFileMessageCellData *fileData = [[TFileMessageCellData alloc] init];
                fileData.path = file.path;
                fileData.fileName = file.filename;
                fileData.length = file.fileSize;
                fileData.uuid = file.uuid;
                
                data = fileData;
            }
            else if([elem isKindOfClass:[TIMCustomElem class]]){
                TIMCustomElem *custom = (TIMCustomElem *)elem;
                TSystemMessageCellData *systemData = [[TSystemMessageCellData alloc] init];
                systemData.content = custom.ext;
                
                data = systemData;
            }
            if([[msg getConversation] getType] == TIM_GROUP && !msg.isSelf){
                data.showName = YES;
            }
            if(data){
                data.isSelf = msg.isSelf;
                data.head = TUIKitResource(@"default_head");
                //data.name = msg.sender;
                if([[msg getConversation] getType] == TIM_GROUP){
                    data.name = [msg getSenderGroupMemberProfile].nameCard;
                }
                else if([[msg getConversation] getType] == TIM_C2C){
                    data.name = [msg getSenderProfile].nickname;
                }
                if(data.name.length == 0){
                    data.name = msg.sender;
                }
                if(msg.status == TIM_MSG_STATUS_SEND_SUCC){
                    data.status = Msg_Status_Succ;
                    [uiMsgs addObject:data];
                }
                else if(msg.status == TIM_MSG_STATUS_SEND_FAIL){
                    data.status = Msg_Status_Fail;
                    [uiMsgs addObject:data];
                }
                data.custom = msg;
            }
            
            if([elem isKindOfClass:[TIMGroupTipsElem class]]){
                TIMGroupTipsElem *tips = (TIMGroupTipsElem *)elem;
                switch (tips.type) {
                    case TIM_GROUP_TIPS_TYPE_INFO_CHANGE:
                    {
                        for (TIMGroupTipsElemGroupInfo *info in tips.groupChangeList) {
                            TSystemMessageCellData *data = [[TSystemMessageCellData alloc] init];
                            switch (info.type) {
                                case TIM_GROUP_INFO_CHANGE_GROUP_NAME:
                                {
                                    data.content = [NSString stringWithFormat:@"\"%@\"修改群名为\"%@\"", tips.opUser, info.value];
                                }
                                    break;
                                case TIM_GROUP_INFO_CHANGE_GROUP_INTRODUCTION:
                                {
                                    data.content = [NSString stringWithFormat:@"\"%@\"修改群简介为\"%@\"", tips.opUser, info.value];
                                }
                                    break;
                                case TIM_GROUP_INFO_CHANGE_GROUP_NOTIFICATION:
                                {
                                    data.content = [NSString stringWithFormat:@"\"%@\"修改群公告为\"%@\"", tips.opUser, info.value];
                                }
                                    break;
                                case TIM_GROUP_INFO_CHANGE_GROUP_OWNER:
                                {
                                    data.content = [NSString stringWithFormat:@"\"%@\"修改群主为\"%@\"", tips.opUser, info.value];
                                }
                                    break;
                                default:
                                    break;
                            }
                            [uiMsgs addObject:data];
                        }
                    }
                        break;
                    case TIM_GROUP_TIPS_TYPE_KICKED:
                    {
                        TSystemMessageCellData *data = [[TSystemMessageCellData alloc] init];
                        NSString *users = [tips.userList componentsJoinedByString:@"、"];
                        data.content = [NSString stringWithFormat:@"\"%@\"将\"%@\"剔出群组", tips.opUser, users];
                        [uiMsgs addObject:data];
                    }
                        break;
                    case TIM_GROUP_TIPS_TYPE_INVITE:
                    {
                        TSystemMessageCellData *data = [[TSystemMessageCellData alloc] init];
                        NSString *users = [tips.userList componentsJoinedByString:@"、"];
                        data.content = [NSString stringWithFormat:@"\"%@\"邀请\"%@\"加入群组", tips.opUser, users];
                        [uiMsgs addObject:data];
                    }
                        break;
                    default:
                        break;
                }
            }
        }
    }
    return uiMsgs;
}

- (NSString *)buildExWithMessageType:(NSInteger)type messageBody:(NSString *)messageBody {
    /*
     @{
     @"messgeType": @"1"  // 0电话 1微信 2简历 3职位 4
     @"messageBody":@" {
     @"messageContent:@"xxxxx",
     @"messageIcon":@"http://xxx.png",
     ...
     }"
     }*/
    NSMutableDictionary  *extDic = [NSMutableDictionary new];
    [extDic setObject:[NSString stringWithFormat:@"%zd",type] forKey:kMessageType];
    [extDic setObject:messageBody forKey:kMessageBody];
    return [extDic mj_JSONString];
}

// MARK: - 解码
-(NSString *)base64DecodeString:(NSString *)string{
    NSData *data=[[NSData alloc]initWithBase64EncodedString:string options:0];
    return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
}

聊天会话列表可以自己自定义:
ChatListVC .m:

// MARK: - viewController's life Circle
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // MARK: - 监听消息
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateConversations) name:TUIKitNotification_TIMRefreshListener object:nil];
    [self updateConversations];
}

// MARK: - update message notify
- (void)updateConversations {
    _dataArray = [NSMutableArray arrayWithArray:[[TIMManager sharedInstance]getConversationList]];
    int sum = 0;
    for (TIMConversation *con in _dataArray) {
        sum = sum + [con getUnReadMessageNum];
    }
    //未读消息数
    if (sum >0) {
        self.tabBarItem.badgeValue = [NSString stringWithFormat:@"%i",sum];
    } else {
        self.tabBarItem.badgeValue = nil;
    }
    [_tableView reloadData];
}

// MARK: - UITableViewDataSource &Delegate
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _dataArray.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    ChatListCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([ChatListCell class])];
    if (!cell) {
        cell = [[ChatListCell alloc] initWithStyle:0 reuseIdentifier:NSStringFromClass([ChatListCell class])];
    }
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    [cell setCellWithConversation:_dataArray[indexPath.row]];
    return cell;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 72;
}

/*
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return 5.0;
}

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 5.0;
}
 */


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    ChatViewController *chat = [ChatViewController new];
    chat.conversation = [self _convertConversationToConversationData:_dataArray[indexPath.row]];
    chat.hidesBottomBarWhenPushed = YES;
    [self.navigationController pushViewController:chat animated:YES];
}

// MARK: - delete Action
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellEditingStyleDelete;
}

- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return @"删除";
}

- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // MARK: - 删除会话
    TIMConversation *con = _dataArray[indexPath.row];
    [[TIMManager sharedInstance] deleteConversationAndMessages:TIM_C2C receiver:con.getReceiver];
    
    [_dataArray removeObjectAtIndex:indexPath.row];
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationNone];
}

#warning ###################################消息转换方法
- (TConversationCellData *)_convertConversationToConversationData:(TIMConversation *)conv {
    //[conv getMessage:[[TUIKit sharedInstance] getConfig].msgCountPerRequest last:nil succ:nil fail:nil];
    TIMMessage *msg = [conv getLastMsg];
    TConversationCellData *data = [[TConversationCellData alloc] init];
    data.unRead = [conv getUnReadMessageNum];
    data.time = [self getDateDisplayString:msg.timestamp];
    data.subTitle = [self getLastDisplayString:conv];
    if([conv getType] == TIM_C2C){
        // MARK: - 对方的头像和名字
        data.head = TUIKitResource(@"default_head");
    }else if([conv getType] == TIM_GROUP){
        data.head = TUIKitResource(@"default_group");
    }
    data.convId = [conv getReceiver];
    data.convType = (TConvType)[conv getType];
    
    if(data.convType == TConv_Type_C2C){
        data.title = data.convId;
    }
    else if(data.convType == TConv_Type_Group){
        data.title = [conv getGroupName];
    }
    return data;
}

- (NSString *)getLastDisplayString:(TIMConversation *)conv {
    NSString *str = @"";
    TIMMessageDraft *draft = [conv getDraft];
    // MARK: - 草稿内容
    if(draft){
        for (int i = 0; i < draft.elemCount; ++i) {
            TIMElem *elem = [draft getElem:i];
            if([elem isKindOfClass:[TIMTextElem class]]){
                TIMTextElem *text = (TIMTextElem *)elem;
                str = [NSString stringWithFormat:@"[草稿]%@", text.text];
                break;
            }
            else{
                continue;
            }
        }
        return str;
    }
    
    TIMMessage *msg = [conv getLastMsg];
    if(msg.status == TIM_MSG_STATUS_LOCAL_REVOKED){
        if(msg.isSelf){
            return @"你撤回了一条消息";
        }
        else{
            return [NSString stringWithFormat:@"\"%@\"撤回了一条消息", msg.sender];
        }
    }
    for (int i = 0; i < msg.elemCount; ++i) {
        TIMElem *elem = [msg getElem:i];
        if([elem isKindOfClass:[TIMTextElem class]]){
            TIMTextElem *text = (TIMTextElem *)elem;
            str = text.text;
            break;
        }
        else if([elem isKindOfClass:[TIMCustomElem class]]){
            TIMCustomElem *custom = (TIMCustomElem *)elem;
            str = custom.ext;
            break;
        }
        else if([elem isKindOfClass:[TIMImageElem class]]){
            str = @"[图片]";
            break;
        }
        else if([elem isKindOfClass:[TIMSoundElem class]]){
            str = @"[语音]";
            break;
        }
        else if([elem isKindOfClass:[TIMVideoElem class]]){
            str = @"[视频]";
            break;
        }
        else if([elem isKindOfClass:[TIMFaceElem class]]){
            str = @"[动画表情]";
            break;
        }
        else if([elem isKindOfClass:[TIMFileElem class]]){
            str = @"[文件]";
            break;
        }
        else if([elem isKindOfClass:[TIMGroupTipsElem class]]){
            TIMGroupTipsElem *tips = (TIMGroupTipsElem *)elem;
            switch (tips.type) {
                case TIM_GROUP_TIPS_TYPE_INFO_CHANGE:
                {
                    for (TIMGroupTipsElemGroupInfo *info in tips.groupChangeList) {
                        switch (info.type) {
                            case TIM_GROUP_INFO_CHANGE_GROUP_NAME:
                            {
                                str = [NSString stringWithFormat:@"\"%@\"修改群名为\"%@\"", tips.opUser, info.value];
                            }
                                break;
                            case TIM_GROUP_INFO_CHANGE_GROUP_INTRODUCTION:
                            {
                                str = [NSString stringWithFormat:@"\"%@\"修改群简介为\"%@\"", tips.opUser, info.value];
                            }
                                break;
                            case TIM_GROUP_INFO_CHANGE_GROUP_NOTIFICATION:
                            {
                                str = [NSString stringWithFormat:@"\"%@\"修改群公告为\"%@\"", tips.opUser, info.value];
                            }
                                break;
                            case TIM_GROUP_INFO_CHANGE_GROUP_OWNER:
                            {
                                str = [NSString stringWithFormat:@"\"%@\"修改群主为\"%@\"", tips.opUser, info.value];
                            }
                                break;
                            default:
                                break;
                        }
                    }
                }
                    break;
                case TIM_GROUP_TIPS_TYPE_KICKED:
                {
                    NSString *users = [tips.userList componentsJoinedByString:@"、"];
                    str = [NSString stringWithFormat:@"\"%@\"将\"%@\"剔出群组", tips.opUser, users];
                }
                    break;
                case TIM_GROUP_TIPS_TYPE_INVITE:
                {
                    NSString *users = [tips.userList componentsJoinedByString:@"、"];
                    str = [NSString stringWithFormat:@"\"%@\"邀请\"%@\"加入群组", tips.opUser, users];
                }
                    break;
                default:
                    break;
            }
        }
        else{
            continue;
        }
    }
    return str;
}

// MARK: -最后一条消息的发送时间
- (NSString *)getDateDisplayString:(NSDate *)date
{
    NSCalendar *calendar = [ NSCalendar currentCalendar ];
    int unit = NSCalendarUnitDay | NSCalendarUnitMonth |  NSCalendarUnitYear ;
    NSDateComponents *nowCmps = [calendar components:unit fromDate:[ NSDate date ]];
    NSDateComponents *myCmps = [calendar components:unit fromDate:date];
    NSDateFormatter *dateFmt = [[NSDateFormatter alloc ] init ];
    
    NSDateComponents *comp =  [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekday fromDate:date];
    
    if (nowCmps.year != myCmps.year) {
        dateFmt.dateFormat = @"yyyy/MM/dd";
    }
    else{
        if (nowCmps.day==myCmps.day) {
            dateFmt.AMSymbol = @"上午";
            dateFmt.PMSymbol = @"下午";
            dateFmt.dateFormat = @"aaa hh:mm";
        } else if((nowCmps.day-myCmps.day)==1) {
            dateFmt.AMSymbol = @"上午";
            dateFmt.PMSymbol = @"下午";
            dateFmt.dateFormat = @"昨天";
        } else {
            if ((nowCmps.day-myCmps.day) <=7) {
                switch (comp.weekday) {
                    case 1:
                        dateFmt.dateFormat = @"星期日";
                        break;
                    case 2:
                        dateFmt.dateFormat = @"星期一";
                        break;
                    case 3:
                        dateFmt.dateFormat = @"星期二";
                        break;
                    case 4:
                        dateFmt.dateFormat = @"星期三";
                        break;
                    case 5:
                        dateFmt.dateFormat = @"星期四";
                        break;
                    case 6:
                        dateFmt.dateFormat = @"星期五";
                        break;
                    case 7:
                        dateFmt.dateFormat = @"星期六";
                        break;
                    default:
                        break;
                }
            }else {
                dateFmt.dateFormat = @"yyyy/MM/dd";
            }
        }
    }
    return [dateFmt stringFromDate:date];
}

ChatListCell.m:

- (void)setCellWithConversation:(TIMConversation *)model {
    if (model) {
        _model = model;
        [_avatar sd_setImageWithURL:[NSURL URLWithString:@"https://avatars0.githubusercontent.com/u/16589546?s=460&v=4"] placeholderImage:[UIImage imageNamed:@"AppIcon"]];
        _name.text = [model getReceiver];
        _time.text = [self getDateDisplayString:[model getLastMsg].timestamp];
        if (![model getUnReadMessageNum]) {
            _badge.hidden = YES;
        } else  {
            _badge.hidden = NO;
            _badge.text = [NSString stringWithFormat:@"%i",[model getUnReadMessageNum]];
        }
        _recieve.layer.borderColor = [UIColor orangeColor].CGColor;
        _recieve.layer.borderWidth = 1.0;
        _recieve.textColor = [UIColor orangeColor];
        BOOL isMe = [[model getLastMsg].sender isEqualToString:@"user1"];
        _recieve.text = isMe ? @"送达":@"已读";
        _content.text = [self getLastDisplayString:model];
    }
}


- (NSString *)getLastDisplayString:(TIMConversation *)conv
{
    NSString *str = @"";
    TIMMessageDraft *draft = [conv getDraft];
    if(draft){
        for (int i = 0; i < draft.elemCount; ++i) {
            TIMElem *elem = [draft getElem:i];
            if([elem isKindOfClass:[TIMTextElem class]]){
                TIMTextElem *text = (TIMTextElem *)elem;
                str = [NSString stringWithFormat:@"[草稿]%@", text.text];
                break;
            }
            else{
                continue;
            }
        }
        return str;
    }
    
    TIMMessage *msg = [conv getLastMsg];
    if(msg.status == TIM_MSG_STATUS_LOCAL_REVOKED){
        if(msg.isSelf){
            return @"你撤回了一条消息";
        }
        else{
            return [NSString stringWithFormat:@"\"%@\"撤回了一条消息", msg.sender];
        }
    }
    for (int i = 0; i < msg.elemCount; ++i) {
        TIMElem *elem = [msg getElem:i];
        if([elem isKindOfClass:[TIMTextElem class]]){
            TIMTextElem *text = (TIMTextElem *)elem;
            str = text.text;
            break;
        }
        else if([elem isKindOfClass:[TIMCustomElem class]]){
            TIMCustomElem *custom = (TIMCustomElem *)elem;
MARK://解码
            str = [self base64DecodeString: custom.ext];
            break;
        }
        else if([elem isKindOfClass:[TIMImageElem class]]){
            str = @"[图片]";
            break;
        }
        else if([elem isKindOfClass:[TIMSoundElem class]]){
            str = @"[语音]";
            break;
        }
        else if([elem isKindOfClass:[TIMVideoElem class]]){
            str = @"[视频]";
            break;
        }
        else if([elem isKindOfClass:[TIMFaceElem class]]){
            str = @"[动画表情]";
            break;
        }
        else if([elem isKindOfClass:[TIMFileElem class]]){
            str = @"[文件]";
            break;
        }
        else if([elem isKindOfClass:[TIMGroupTipsElem class]]){
            TIMGroupTipsElem *tips = (TIMGroupTipsElem *)elem;
            switch (tips.type) {
                case TIM_GROUP_TIPS_TYPE_INFO_CHANGE:
                {
                    for (TIMGroupTipsElemGroupInfo *info in tips.groupChangeList) {
                        switch (info.type) {
                            case TIM_GROUP_INFO_CHANGE_GROUP_NAME:
                            {
                                str = [NSString stringWithFormat:@"\"%@\"修改群名为\"%@\"", tips.opUser, info.value];
                            }
                                break;
                            case TIM_GROUP_INFO_CHANGE_GROUP_INTRODUCTION:
                            {
                                str = [NSString stringWithFormat:@"\"%@\"修改群简介为\"%@\"", tips.opUser, info.value];
                            }
                                break;
                            case TIM_GROUP_INFO_CHANGE_GROUP_NOTIFICATION:
                            {
                                str = [NSString stringWithFormat:@"\"%@\"修改群公告为\"%@\"", tips.opUser, info.value];
                            }
                                break;
                            case TIM_GROUP_INFO_CHANGE_GROUP_OWNER:
                            {
                                str = [NSString stringWithFormat:@"\"%@\"修改群主为\"%@\"", tips.opUser, info.value];
                            }
                                break;
                            default:
                                break;
                        }
                    }
                }
                    break;
                case TIM_GROUP_TIPS_TYPE_KICKED:
                {
                    NSString *users = [tips.userList componentsJoinedByString:@"、"];
                    str = [NSString stringWithFormat:@"\"%@\"将\"%@\"剔出群组", tips.opUser, users];
                }
                    break;
                case TIM_GROUP_TIPS_TYPE_INVITE:
                {
                    NSString *users = [tips.userList componentsJoinedByString:@"、"];
                    str = [NSString stringWithFormat:@"\"%@\"邀请\"%@\"加入群组", tips.opUser, users];
                }
                    break;
                default:
                    break;
            }
        }
        else{
            continue;
        }
    }
    return str;
}

-(NSString *)base64DecodeString:(NSString *)string{
    NSData *data=[[NSData alloc]initWithBase64EncodedString:string options:0];
    return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
}

- (NSString *)getDateDisplayString:(NSDate *)date {
    NSCalendar *calendar = [ NSCalendar currentCalendar ];
    int unit = NSCalendarUnitDay | NSCalendarUnitMonth |  NSCalendarUnitYear ;
    NSDateComponents *nowCmps = [calendar components:unit fromDate:[ NSDate date ]];
    NSDateComponents *myCmps = [calendar components:unit fromDate:date];
    NSDateFormatter *dateFmt = [[NSDateFormatter alloc ] init ];
    
    NSDateComponents *comp =  [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekday fromDate:date];
    
    if (nowCmps.year != myCmps.year) {
        dateFmt.dateFormat = @"yyyy/MM/dd";
    }
    else{
        if (nowCmps.day==myCmps.day) {
            dateFmt.AMSymbol = @"上午";
            dateFmt.PMSymbol = @"下午";
            dateFmt.dateFormat = @"aaa hh:mm";
        } else if((nowCmps.day-myCmps.day)==1) {
            dateFmt.AMSymbol = @"上午";
            dateFmt.PMSymbol = @"下午";
            dateFmt.dateFormat = @"昨天";
        } else {
            if ((nowCmps.day-myCmps.day) <=7) {
                switch (comp.weekday) {
                    case 1:
                        dateFmt.dateFormat = @"星期日";
                        break;
                    case 2:
                        dateFmt.dateFormat = @"星期一";
                        break;
                    case 3:
                        dateFmt.dateFormat = @"星期二";
                        break;
                    case 4:
                        dateFmt.dateFormat = @"星期三";
                        break;
                    case 5:
                        dateFmt.dateFormat = @"星期四";
                        break;
                    case 6:
                        dateFmt.dateFormat = @"星期五";
                        break;
                    case 7:
                        dateFmt.dateFormat = @"星期六";
                        break;
                    default:
                        break;
                }
            }else {
                dateFmt.dateFormat = @"yyyy/MM/dd";
            }
        }
    }
    return [dateFmt stringFromDate:date];
}

气泡自定义扩展字段消息格式如下:

{"TIM_CUSTOM_MESSAGE_CONTENT":{"degreeRequirement":"博士","enterpriseName":"深圳市xxx智能科技有限公司","expectJobCity":"101280600","experienceRequirement":"10年以上","financingStage":"天使轮","headPortrait":"http://xxx.oss-cn-hangzhou.aliyuncs.com/S8PeJn_%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20190320174739.jpg","launchCommunicativeTimeStamp":1553331133,"nickname":"苏海峰","positionName":"前端开发","salaryHighestRequirement":2000.00,"salaryMinimumRequirement":1000.00,"synopsis":"由你发起的沟通","workDetailedAddress":"深圳市路通网络技术有限公司"},"TIM_CUSTOM_MESSAGE_TYPE":"TIM_CUSTOM_MESSAGE_CHAT_POSITIONS_INFO"}

核心改动的文件就是上面这几个文件了,读懂就可以做一些自定义气泡的一些东东了, 具体效果如下:


WechatIMG55.png
WechatIMG57.png
WechatIMG58.png

相关文章

网友评论

    本文标题:iOS开发集成腾讯云IM即时通讯

    本文链接:https://www.haomeiwen.com/subject/ixisvqtx.html