前言
公司業(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)行修改的
如下圖所示的消息類型
標(biāo)題是iOS版癣籽,可想而知挽唉,肯定還有其他如 Android版,Web版等筷狼,不可能此類型的消息(我稱它為圖文消息
)只支持iOS瓶籽,而在Android或Web端無法顯示問題。以下附上其他版本擴(kuò)展的鏈接
正文
下載demo后埂材,雙擊 NIMDemo/NIM.xcworkspace 打開項(xiàng)目塑顺,然后運(yùn)行,確保下載下來的demo能正確運(yùn)行起來俏险。
-
運(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)密碼登錄了。
- 添加測(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)建完成后纲菌,添加響應(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)擊事件處理蜘腌。
打開文件 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
- 添加顯示自定義的圖文消息
上面第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.修改消息列表中免姿,顯示的縮略文字
編輯 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ò)展的鏈接