網(wǎng)易云信-新增自定義消息(iOS版)

前言

公司業(yè)務(wù)需要,PC端,移動(dòng)端都用到了第三方 網(wǎng)易云信 IM 來實(shí)現(xiàn)在線客服咨詢媒怯。
在這當(dāng)中難免遇到一些需求是網(wǎng)易云信沒有提供鸽嫂,需要自行編碼進(jìn)行擴(kuò)展的纵装。寫此篇文章的目的正是因業(yè)務(wù)需要,需要在網(wǎng)易云信的基礎(chǔ)上進(jìn)行消息類型的擴(kuò)展据某。

此篇文章里的代碼是基于 網(wǎng)易云信 NIM_iOS_Demo_v4.5.0 版 進(jìn)行修改的

如下圖所示的消息類型

帶圖片和文字橡娄,并且可點(diǎn)擊的消息類型,(注意收到的消息和發(fā)送的消息文本顏色不一樣)

標(biāo)題是iOS版癣籽,可想而知挽唉,肯定還有其他如 Android版,Web版等筷狼,不可能此類型的消息(我稱它為圖文消息)只支持iOS瓶籽,而在Android或Web端無法顯示問題。以下附上其他版本擴(kuò)展的鏈接


正文

  1. 下載demo后埂材,雙擊 NIMDemo/NIM.xcworkspace 打開項(xiàng)目塑顺,然后運(yùn)行,確保下載下來的demo能正確運(yùn)行起來俏险。

  2. 運(yùn)行沒有問題后严拒,修改以下幾個(gè)文件配置,將demo修改為自己所用竖独。

    • 修改 Classes/Util/NTESDemoConfig.m 中的_appKey裤唠,填入自己的appKey
- (instancetype)init
{
    if (self = [super init])
    {
        _appKey = @"填入自己的appKey";
        _apiURL = @"https://app.netease.im/api";
        _apnsCername = @"ENTERPRISE";
        _pkCername = @"DEMO_PUSH_KIT";
        
        _redPacketConfig = [[NTESRedPacketConfig alloc] init];        
    }
    return self;
}
  • 修改
- (NSString *)tokenByPassword
{
    //demo直接使用username作為account,md5(password)作為token
    //接入應(yīng)用開發(fā)需要根據(jù)自己的實(shí)際情況來獲取 account和token
    //return [[NIMSDK sharedSDK] isUsingDemoAppKey] ? [self MD5String] : self;
    return [self MD5String];
}

修改上述代碼后莹痢,重新運(yùn)行种蘸,即可使用自己的賬號(hào)密碼登錄了。

  1. 添加測(cè)試發(fā)送圖文鏈接的按鈕竞膳,點(diǎn)擊即發(fā)送圖文鏈接消息

編輯NTESCellLayoutConfig.m文件航瞭,在init函數(shù)中 _types 增加一條

- (instancetype)init
{
    if (self = [super init])
    {
        _types =  @[
                   @"NTESJanKenPonAttachment",
                   @"NTESSnapchatAttachment",
                   @"NTESChartletAttachment",
                   @"NTESWhiteboardAttachment",
                   @"NTESRedPacketAttachment",
                   @"NTESRedPacketTipAttachment",
                   // 添加圖文鏈接消息
                   @"NTESLinkAttachment"
                   ];
        _sessionCustomconfig = [[NTESSessionCustomContentConfig alloc] init];
        _chatroomTextConfig  = [[NTESChatroomTextContentConfig alloc] init];
        _chatroomRobotConfig = [[NTESChatroomRobotContentConfig alloc] init];
    }
    return self;
}

編輯 NTESCustomAttachmentDecoder.m文件,checkAttachment函數(shù)中添加如下代碼

//頭部導(dǎo)入
#import "NTESLinkAttachment.h"
//...

- (id<NIMCustomAttachment>)decodeAttachment:(NSString *)content
{
    id<NIMCustomAttachment> attachment = nil;

    NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
    if (data) {
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data
                                                             options:0
                                                               error:nil];
        if ([dict isKindOfClass:[NSDictionary class]])
        {
            NSInteger type     = [dict jsonInteger:CMType];
            NSDictionary *data = [dict jsonDict:CMData];
            switch (type) {
                //...
                // 添加圖文鏈接 case
                case CustomMessageTypeLink:
                {
                    attachment = [[NTESLinkAttachment alloc] init];
                    ((NTESLinkAttachment *)attachment).title        = [data jsonString:CMLinkPacketTitle];
                    ((NTESLinkAttachment *)attachment).linkUrl      = [data jsonString:CMLinkPacketLinkUrl];
                    ((NTESLinkAttachment *)attachment).imageUrl     = [data jsonString:CMLinkPacketImageUrl];
                    ((NTESLinkAttachment *)attachment).describe     = [data jsonString:CMLinkPacketDescribe];
                }
                    break;
                default:
                    break;
            }
            attachment = [self checkAttachment:attachment] ? attachment : nil;
        }
    }
    return attachment;
}

- (BOOL)checkAttachment:(id<NIMCustomAttachment>)attachment
{

    // ... 省略前面的 if  else if 塊
    
    // 添加如下代碼
    else if ([attachment isKindOfClass:[NTESLinkAttachment class]])
    {
        check = YES;
    }
    return check;
}

編輯NTESSessionConfig.m文件顶猜,在mediaItems函數(shù)中添加如下代碼

//...
// 添加圖文鏈接測(cè)試按鈕沧奴,此處的 onTapMediaItemLinkPacket 在
 NTESSessionViewController.m 中添加 
NIMMediaItem *linkPacket  = [NIMMediaItem item:@"onTapMediaItemLinkPacket:"
                                   normalImage:[UIImage imageNamed:@"icon_redpacket_normal"]
                                 selectedImage:[UIImage imageNamed:@"icon_redpacket_pressed"]
                                         title:@"圖文鏈接"];
//...
if (isMe)
{
    items = @[janKenPon,fileTrans,tip];
}
else if(_session.sessionType == NIMSessionTypeTeam)
{
    // 在群組消息里添加
    items = @[janKenPon,teamMeeting,fileTrans,tip,redPacket,linkPacket];
}
else
{
    // 添加圖文鏈接測(cè)試按鈕
    items = @[janKenPon,audioChat,videoChat,fileTrans,snapChat,whiteBoard,tip,redPacket,linkPacket];
}

Classes/Sections/Session/Object/Attach 目錄下創(chuàng)建 NTESLinkAttachment文件痘括,繼承 NSObject 類长窄,實(shí)現(xiàn) NIMCustomAttachment,NTESCustomAttachmentInfo 協(xié)議

創(chuàng)建Cocoa Touch Class文件 NTESLinkAttachment,命名規(guī)則盡量遵循云信命名規(guī)則

創(chuàng)建完成后纲菌,添加響應(yīng)的屬性值 標(biāo)題title挠日,跳轉(zhuǎn)的鏈接linkUrl,圖片imageUrl翰舌,描述describe嚣潜。

NTESLinkAttachment.h 文件內(nèi)容如下

#import <Foundation/Foundation.h>
#import "NTESCustomAttachmentDefines.h"

@interface NTESLinkAttachment : NSObject<NIMCustomAttachment,NTESCustomAttachmentInfo>

// 標(biāo)題
@property (nonatomic, copy) NSString *title;

// 點(diǎn)擊跳轉(zhuǎn)的鏈接地址
@property (nonatomic, copy) NSString *linkUrl;

// 圖片
@property (nonatomic, copy) NSString *imageUrl;

// 描述
@property (nonatomic, copy) NSString *describe;

@end

NTESLinkAttachment.m文件內(nèi)容如下

復(fù)制之后,會(huì)有報(bào)錯(cuò)如 NTESSessionLinkContentView.h 找不到椅贱,和 CMLinkPacket***未定義等相關(guān)錯(cuò)誤懂算,先別急只冻,后面會(huì)講到,如果看不順眼可以先注釋掉计技,回頭再過來放開注釋也行喜德。(ps:本人非iOS開發(fā),所以代碼部分不做詳細(xì)講解)

#import "NTESLinkAttachment.h"
#import "NTESSessionLinkContentView.h"

@implementation NTESLinkAttachment

- (NSString *)encodeAttachment
{
    NSDictionary *dict = @{
                           CMType : @(CustomMessageTypeRedPacket),
                           CMData : @{
                              CMLinkPacketTitle    : self.title,
                              CMLinkPacketLinkUrl  : self.linkUrl,
                              CMLinkPacketImageUrl : self.imageUrl,
                              CMLinkPacketDescribe : self.describe
                           }
                       };
    NSData *data = [NSJSONSerialization dataWithJSONObject:dict
                                                   options:0
                                                     error:nil];
    NSString *content = nil;
    if (data) {
        content = [[NSString alloc] initWithData:data
                                        encoding:NSUTF8StringEncoding];
    }
    return content;
}


- (NSString *)cellContent:(NIMMessage *)message{
    return @"NTESSessionLinkContentView";
}

- (CGSize)contentSize:(NIMMessage *)message cellWidth:(CGFloat)width{
    CGFloat w = 240.0f;
    CGFloat h = 40.0f;
    CGFloat padding = 3.0f * 3;
    if (self.imageUrl != nil) {
        h += 140.f;
    }
    if (self.describe != nil) {
        UIFont *font = [UIFont systemFontOfSize:12.0];
        CGFloat height = [NTESSessionLinkContentView getHeightByWidth:w - padding title:self.describe font:font];
        h += height + padding;
    }
    
    return CGSizeMake(w, h);
}

- (UIEdgeInsets)contentViewInsets:(NIMMessage *)message
{
    CGFloat bubblePaddingForImage    = 3.f;
    CGFloat bubbleArrowWidthForImage = 5.f;
    if (message.isOutgoingMsg) {
        return  UIEdgeInsetsMake(bubblePaddingForImage,bubblePaddingForImage,bubblePaddingForImage,bubblePaddingForImage + bubbleArrowWidthForImage);
    }else{
        return  UIEdgeInsetsMake(bubblePaddingForImage,bubblePaddingForImage + bubbleArrowWidthForImage, bubblePaddingForImage,bubblePaddingForImage);
    }
}

- (BOOL)canBeRevoked
{
    return YES;
}

- (BOOL)canBeForwarded
{
    return YES;
}

@end

現(xiàn)在再來補(bǔ)充上面缺失的部分垮媒。
NTESCustomAttachmentDefines.h 文件中定義如下四個(gè)字段舍悯。打開這個(gè)文件可以看到這個(gè)里面還定義了一些其他消息需要用到的字段,所以遵循人家的游戲規(guī)則睡雇,也在此處定義萌衬。

//...省略

typedef NS_ENUM(NSInteger,NTESCustomMessageType){
    CustomMessageTypeJanKenPon  = 1, //剪子石頭布
    CustomMessageTypeSnapchat   = 2, //閱后即焚
    CustomMessageTypeChartlet   = 3, //貼圖表情
    CustomMessageTypeWhiteboard = 4, //白板會(huì)話
    // (由于我其他平臺(tái)圖文消息type是5,剛好我們業(yè)務(wù)不需要發(fā)紅包功能它抱,這里我只好把5變成我的圖文消息秕豫,把紅包類型的消息去除)
    CustomMessageTypeRedPacket  = 5, //紅包消息
    CustomMessageTypeRedPacketTip = 6, //紅包提示消息
};

//...省略


//紅包
#define CMRedPacketTitle   @"title"        //紅包標(biāo)題
#define CMRedPacketContent @"content"      //紅包內(nèi)容
#define CMRedPacketId      @"redPacketId"  //紅包ID
//紅包詳情
#define CMRedPacketSendId     @"sendPacketId"
#define CMRedPacketOpenId     @"openPacketId"
#define CMRedPacketDone       @"isGetDone"
// 添加此處四個(gè)字段用于圖文鏈接消息使用
#define CMLinkPacketTitle       @"title"        //標(biāo)題
#define CMLinkPacketLinkUrl     @"link_url"      //跳轉(zhuǎn)鏈接
#define CMLinkPacketImageUrl    @"image_url"     //圖片鏈接
#define CMLinkPacketDescribe    @"describe"     //描述
//...省略

Classes/Sections/Session/View/SessionCell/SessionContentView目錄下創(chuàng)建Cocoach Touch Class文件 NIMSessionMessageContentView,此文件主要用來做圖文鏈接消息的顯示观蓄。

NIMSessionMessageContentView.h文件內(nèi)容如下

#import "NIMSessionMessageContentView.h"

static NSString *const NIMDemoEventNameLinkingPacket = @"NIMDemoEventNameLinkingPacket";

@interface NTESSessionLinkContentView : NIMSessionMessageContentView

// 根據(jù)寬度馁蒂,字體和文本內(nèi)容獲取高度
+ (CGFloat)getHeightByWidth:(CGFloat)width title:(NSString *)title font:(UIFont *)font;

@end

NIMSessionMessageContentView.m文件內(nèi)容如下

#import "NTESSessionLinkContentView.h"
#import "UIView+NTES.h"
#import "NTESLinkAttachment.h"
#import "NTESSessionUtil.h"
#import "UIImageView+WebCache.h"

CGFloat titleHeight = 40.f; // title高度
CGFloat imageHeight = 120.f;// 圖片高度

@interface NTESSessionLinkContentView()

// 圖文鏈接消息附件
@property (nonatomic,strong) NTESLinkAttachment *attachment;

@property (nonatomic,strong) UILabel *titleLabel;

@property (nonatomic,strong) UIImageView *imageView;

@property (nonatomic,strong) UILabel *describeLabel;

@end

@implementation NTESSessionLinkContentView

- (instancetype)initSessionMessageContentView{
    self = [super initSessionMessageContentView];
    if (self) {
        self.opaque = YES;
        
        _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        _imageView  = [[UIImageView alloc] initWithFrame:CGRectZero];
        _describeLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    }
    return self;
}

- (void)refresh:(NIMMessageModel *)data
{
    [super refresh:data];
    NIMCustomObject *customObject = (NIMCustomObject*)data.message.messageObject;
    id attach = customObject.attachment;
    
    if ([attach isKindOfClass:[NTESLinkAttachment class]]) {
        self.attachment = (NTESLinkAttachment *)attach;
        
        self.titleLabel.text = self.attachment.title;
        [self addSubview:_titleLabel];
        
        if (self.attachment.imageUrl != nil) {
            NSURL *url = [NSURL URLWithString:self.attachment.imageUrl];
            // 默認(rèn)圖片 default_image,記得在 Images.xcassets 中添加
            [self.imageView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"default_image"]];
            [self.imageView sizeToFit];
            [self addSubview:_imageView];
        }
        if (self.attachment.describe != nil) {
            self.describeLabel.text = self.attachment.describe;
            [self addSubview:_describeLabel];
        }
    }
}

- (void)layoutSubviews{
    [super layoutSubviews];
    BOOL outgoing = self.model.message.isOutgoingMsg;
    
    UIEdgeInsets contentInsets = self.model.contentViewInsets;
    CGSize contentSize = [self.model contentSize:self.superview.width];
    CGFloat padding = 15;
    
    self.titleLabel.frame = CGRectMake(padding, contentInsets.left, contentSize.width - padding, titleHeight);
    self.titleLabel.font = [UIFont systemFontOfSize:14.0];
    self.titleLabel.numberOfLines = 1;
    
    // 詳情描述距離
    CGFloat describeY = titleHeight;
    
    if (self.attachment != nil && self.attachment.imageUrl != nil) {
        self.imageView.frame = CGRectMake(
                                          contentInsets.left + contentInsets.right,
                                          titleHeight + contentInsets.top + 5,
                                          contentSize.width - (contentInsets.left + contentInsets.right), imageHeight);
        self.imageView.contentMode = UIViewContentModeScaleAspectFit;
        [self setBorderWithImageView:self.imageView top:TRUE left:FALSE bottom:TRUE right:FALSE borderColor:[UIColor lightGrayColor] borderWidth:0.3f];
        describeY += imageHeight + contentInsets.top * 3 + 5 ;
    }
    
    if (self.attachment != nil && self.attachment.describe != nil) {
        UIFont *font = [UIFont systemFontOfSize:12.0];
        self.describeLabel.font = font;
        self.describeLabel.numberOfLines = 3;
        CGFloat height = [NTESSessionLinkContentView getHeightByWidth:self.describeLabel.frame.size.width title:self.attachment.describe font:font];
        self.describeLabel.frame = CGRectMake(padding, describeY, contentSize.width - padding, height + padding);
    }
    
    // 發(fā)出去的消息
    if (outgoing)
    {
        self.titleLabel.textColor = [UIColor whiteColor];
        self.describeLabel.textColor = [UIColor whiteColor];
    }
    else
    {
        self.titleLabel.textColor = [UIColor blackColor];
        self.describeLabel.textColor = [UIColor grayColor];
    }
}

// 根據(jù)寬動(dòng)態(tài)獲取高度
+ (CGFloat)getHeightByWidth:(CGFloat)width title:(NSString *)title font:(UIFont *)font
{
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 0)];
    label.text = title;
    label.font = font;
    label.numberOfLines = 0;
    [label sizeToFit];
    CGFloat height = label.frame.size.height;
    return height;
}

// 設(shè)置元素邊框
-(void)setBorderWithImageView:(UIImageView *) imageView top:(BOOL)top left:(BOOL)left bottom:(BOOL)bottom right:(BOOL)right borderColor:(UIColor *)color borderWidth:(CGFloat)width
{
    // 垂直內(nèi)邊距
    CGFloat verticalPadding = 5.0f;
    if (top)
    {
        CALayer *layer = [CALayer layer];
        layer.frame = CGRectMake(0, -verticalPadding, imageView.frame.size.width, width);
        layer.backgroundColor = color.CGColor;
        [imageView.layer addSublayer:layer];
    }
    if (left)
    {
        CALayer *layer = [CALayer layer];
        layer.frame = CGRectMake(0, 0, width, imageView.frame.size.height);
        layer.backgroundColor = color.CGColor;
        [imageView.layer addSublayer:layer];
    }
    if (bottom)
    {
        CALayer *layer = [CALayer layer];
        layer.frame = CGRectMake(0, imageView.frame.size.height - width + verticalPadding, imageView.frame.size.width, width);
        layer.backgroundColor = color.CGColor;
        [imageView.layer addSublayer:layer];
    }
    if (right)
    {
        CALayer *layer = [CALayer layer];
        layer.frame = CGRectMake(imageView.frame.size.width - width, 0, width, imageView.frame.size.height);
        layer.backgroundColor = color.CGColor;
        [imageView.layer addSublayer:layer];
    }
}

- (void)onTouchUpInside:(id)sender
{
    if ([self.delegate respondsToSelector:@selector(onCatchEvent:)]) {
        NIMKitEvent *event = [[NIMKitEvent alloc] init];
        event.eventName = NIMDemoEventNameLinkingPacket;
        event.messageModel = self.model;
        event.data = self;
        [self.delegate onCatchEvent:event];
    }
}

@end

接下來我們添加圖文按鈕的點(diǎn)擊事件處理蜘腌。

下面代碼添加此處按鈕點(diǎn)擊處理事件

打開文件 NTESSessionViewController.m沫屡, 編輯函數(shù) onTapCell
在 if else if 代碼塊后面添加如下代碼

// 頭部需導(dǎo)入
#import "NTESLinkAttachment.h"
#import "NTESSessionLinkContentView.h"
#import "NTESWebViewController.h"

// ...

// 添加圖文鏈接消息點(diǎn)擊事件
else if ([eventName isEqualToString:NIMDemoEventNameLinkingPacket]) {
   NIMCustomObject *object = event.messageModel.message.messageObject;
   NTESLinkAttachment *attachment = (NTESLinkAttachment *)object.attachment;
   [self onOpenWebView:attachment];
   handled = YES;
}
// ....

// 添加上面調(diào)用的 onOpenWebView 函數(shù) 
- (void)onOpenWebView:(NTESLinkAttachment *)attachment {
    // NTESWebViewController 是點(diǎn)擊顯示的圖文消息后要跳轉(zhuǎn)的頁面,在構(gòu)造函數(shù)添加跳轉(zhuǎn)時(shí)傳入 linkUrl
    NTESWebViewController *vc = [[NTESWebViewController alloc] initWithUrl:attachment.linkUrl];
    // 設(shè)置title
    if (attachment && attachment.title != nil) {
        vc.title = attachment.title;
    }
    [self.navigationController pushViewController:vc animated:YES];
}

//...
#pragma mark - 圖文鏈接
- (void)onTapMediaItemLinkPacket:(NIMMediaItem *)item
{
    // 此處模擬測(cè)試數(shù)據(jù)
    NTESLinkAttachment *attachment = [[NTESLinkAttachment alloc] init];
    [attachment setTitle:@"暖冬季歡樂送"];
    [attachment setLinkUrl:@"http://www.reibang.com/u/bd57ade96e8a"];
    [attachment setImageUrl:@"https://www.baidu.com/img/bd_logo1.png"];
    [attachment setDescribe:@"家具滿1000元減100元再返100元現(xiàn)金券撮珠!點(diǎn)擊查看詳情沮脖!"];
    NIMMessage *message = [NTESSessionMsgConverter msgWithLink:attachment];
    [self sendMessage:message];
}
//...

在目錄 Classes/Sections/Session/ViewController 添加上面使用到的 NTESWebViewController,用來顯示點(diǎn)擊后的網(wǎng)頁
NTESWebViewController.h內(nèi)容如下

#import <UIKit/UIKit.h>

@interface NTESWebViewController : UIViewController<UIWebViewDelegate>
{
    UIWebView *webView;
}

- (instancetype)initWithUrl:(NSString *)url;

@end

NTESWebViewController.m內(nèi)容如下

#import "NTESWebViewController.h"

@interface NTESWebViewController ()<UINavigationControllerDelegate>

@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator;
@property (nonatomic, strong) NSString *url;

@end

@implementation NTESWebViewController

- (instancetype)initWithUrl:(NSString *)url
{
    self = [super init];
    if (self)
    {
        _url = url;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // app 尺寸芯急,去掉狀態(tài)欄
    CGRect mainScreen = [UIScreen mainScreen].applicationFrame;
    // 1.創(chuàng)建webview勺届,并設(shè)置大小
    webView = [[UIWebView alloc] initWithFrame:CGRectMake(mainScreen.origin.x, mainScreen.origin.y, mainScreen.size.width, mainScreen.size.height)];
    // 2.創(chuàng)建請(qǐng)求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];
    // 3.加載網(wǎng)頁
    [webView loadRequest:request];
    // 4.將webview添加到界面
    [self.view addSubview:webView];
    [webView setDelegate:self];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)webViewDidStartLoad:(UIWebView *)webView {
    // 創(chuàng)建UIActivityIndicatorView背底半透明View
    CGRect mainScreen = [UIScreen mainScreen].applicationFrame;
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(mainScreen.origin.x, mainScreen.origin.y, mainScreen.size.width, mainScreen.size.height)];
    [view setTag:108];
    [view setBackgroundColor:[UIColor whiteColor]];
    [self.view addSubview:view];
    
    self.activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 40.0f, 40.0f)];
    [self.activityIndicator setCenter:view.center];
    [self.activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
    [view addSubview:self.activityIndicator];
    
    [self.activityIndicator startAnimating];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [self.activityIndicator stopAnimating];
    UIView *view = (UIView *)[self.view viewWithTag:108];
    [view removeFromSuperview];
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    [self.activityIndicator stopAnimating];
    UIView *view = (UIView *)[self.view viewWithTag:108];
    [view removeFromSuperview];
}

@end
  1. 添加顯示自定義的圖文消息
    上面第3個(gè)步驟其實(shí)已經(jīng)做了大部分自定義的圖文鏈接消息的顯示工作了,此處添加圖文鏈接消息的轉(zhuǎn)換代碼娶耍,
    編輯NTESSessionMsgConverter.h 頭文件
// ...
@class NTESLinkAttachment

@interface NTESSessionMsgConverter : NSObject
// ...
// 添加鏈接消息
+ (NIMMessage *)msgWithLink:(NTESLinkAttachment *)attachment;
@end

在實(shí)現(xiàn)文件NTESSessionMsgConverter.m 添加以下代碼

//...
#import "NTESLinkAttachment.h"

@implementation NTESSessionMsgConverter
//...
+ (NIMMessage *)msgWithLink:(NTESLinkAttachment *)attachment
{
    NIMMessage *message               = [[NIMMessage alloc] init];
    NIMCustomObject *customObject     = [[NIMCustomObject alloc] init];
    customObject.attachment           = attachment;
    message.messageObject             = customObject;
    message.apnsContent = @"發(fā)來了鏈接信息";
    return message;
}

@end

5.修改消息列表中免姿,顯示的縮略文字

添加顯示[圖文鏈接]字樣,如果不添加榕酒,默認(rèn)顯示的是[未知消息]

編輯 NTESSessionListViewController.m胚膊, 在contentForRecentSession中添加一條邏輯判斷

// ...
#import "NTESLinkAttachment.h"

// ...
- (NSAttributedString *)contentForRecentSession:(NIMRecentSession *)recent{
    //...
    else if ([object.attachment isKindOfClass:[NTESLinkAttachment class]]) {
        text = @"[圖文鏈接]";
     } else {
        text = @"[未知消息]";
     }
    //...
}
// ...

尾篇

到此,云信iOS端的擴(kuò)展自定義消息已經(jīng)完成想鹰。當(dāng)然紊婉,這只是iOS的顯示正常了,其他如web辑舷,Android喻犁,pc等客戶端收到此類的消息,顯示有問題,也是需要擴(kuò)展調(diào)整的肢础。此篇文章其他端的文章我會(huì)陸續(xù)更新还栓,如果有需要的同學(xué)可以關(guān)注下。

以下附上其他版本擴(kuò)展的鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末传轰,一起剝皮案震驚了整個(gè)濱河市蝙云,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌路召,老刑警劉巖勃刨,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異股淡,居然都是意外死亡身隐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門唯灵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贾铝,“玉大人,你說我怎么就攤上這事埠帕」缚” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵敛瓷,是天一觀的道長叁巨。 經(jīng)常有香客問我,道長呐籽,這世上最難降的妖魔是什么锋勺? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮狡蝶,結(jié)果婚禮上庶橱,老公的妹妹穿的比我還像新娘。我一直安慰自己贪惹,他們只是感情好苏章,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奏瞬,像睡著了一般枫绅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丝格,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天撑瞧,我揣著相機(jī)與錄音棵譬,去河邊找鬼显蝌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的曼尊。 我是一名探鬼主播酬诀,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼骆撇!你這毒婦竟也來了瞒御?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤神郊,失蹤者是張志新(化名)和其女友劉穎肴裙,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涌乳,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蜻懦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了夕晓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宛乃。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蒸辆,靈堂內(nèi)的尸體忽然破棺而出征炼,到底是詐尸還是另有隱情,我是刑警寧澤躬贡,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布谆奥,位于F島的核電站,受9級(jí)特大地震影響拂玻,放射性物質(zhì)發(fā)生泄漏雄右。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一纺讲、第九天 我趴在偏房一處隱蔽的房頂上張望擂仍。 院中可真熱鬧,春花似錦熬甚、人聲如沸逢渔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肃廓。三九已至,卻和暖如春诲泌,著一層夾襖步出監(jiān)牢的瞬間盲赊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來泰國打工敷扫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哀蘑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像绘迁,于是被迫代替她去往敵國和親合溺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,842評(píng)論 25 707
  • 前言 公司業(yè)務(wù)需要缀台,PC端棠赛,移動(dòng)端都用到了第三方 網(wǎng)易云信 IM 來實(shí)現(xiàn)在線客服咨詢。在這當(dāng)中難免遇到一些需求是網(wǎng)...
    醉生夢(mèng)死閱讀 6,360評(píng)論 1 4
  • 前言 公司業(yè)務(wù)需要膛腐,PC端睛约,移動(dòng)端都用到了第三方 網(wǎng)易云信 IM 來實(shí)現(xiàn)在線客服咨詢。在這當(dāng)中難免遇到一些需求是網(wǎng)...
    醉生夢(mèng)死閱讀 3,932評(píng)論 20 1
  • 世界上沒有兩塊相同是石頭哲身,沒有兩片相同的樹葉痰腮,同時(shí),也沒有相同的兩個(gè)人律罢。即使長相相同的雙胞胎往往性格也會(huì)截然不同膀值,...
    望舒的雨巷暢想閱讀 349評(píng)論 0 4
  • 我寧愿把自己偽裝的讓別人覺得 我是整天就會(huì)哈哈哈哈 笑點(diǎn)低 很無腦的傻逼 我也不想讓別人看到我...
    南風(fēng)入弦閱讀 323評(píng)論 0 1