iOS

发送自定义消息

更新时间: 2026/05/19 16:55:23

网易云信 IM UIKit 内置了多种基本消息类型,包括文本、图片、语音、视频、文件等,可满足大部分即时通讯场景。当这些基础消息类型无法满足您的业务需求时,您可以使用自定义消息来扩展功能,例如实现电商订单卡片、红包、系统通知等。

发送自定义消息

自定义消息需要定义两个关键参数:

  • customMessageType:消息类型标识符,用于区分不同类型的自定义消息,用于后面的 UI 展示。
  • customHeight:自定义消息视图的高度。
Swift
swift@objc func sendCustomButton() {
    // type 自定义消息类型,该字段必须指定,且不可为 101、102(UIKit 内部已使用),否则解析为【未知消息体】
    // customHeight 自定义消息的高度
    let dataDic: [String: Any] = ["type": customMessageType, "customHeight": 1000]
    let dataJson = NECommonUtil.getJSONStringFromDictionary(dataDic)
    let customMessage = MessageUtils.customMessage(text: "this is a custom message, create time:\(Date.timeIntervalSinceReferenceDate)",
                                                   rawAttachment: dataJson)

    ChatRepo.shared.sendMessage(message: customMessage, conversationId: ChatRepo.conversationId) { result, error, pro in
      if let err = error {
        print("send custom message error : ", err.localizedDescription)
      }
    }
  }
Objective-C
Objective-C// type 字段必须指定,且不可为 101、102(UIKit 内部已使用),否则解析为 **未知消息体**
NSDictionary *data = @{@"type" : @(kCustomMessageType)};
NSString *rawAttachment = [NECommonUtil getJSONStringFromDictionary:data];
V2NIMMessage *customMessage = [MessageUtils customMessageWithText:@"this is a custom message" rawAttachment:rawAttachment];

[[ChatRepo shared] sendMessage:customMessage conversationId:@"conversationId" params:params completion:^(V2NIMSendMessageResult *result, NSError *error, NSUInteger pro) {
    if (error) {
    NSLog(@"send custom message error : %@", error.localizedDescription ?: @"");
  }
}];

自定义消息 UI 展示

若需要在会话界面将自定义消息按照您自定义的 UI 样式进行展示,请完成以下步骤。

实现自定义 CustomChatCell

添加消息展示的 Cell,并使其继承 NEChatBaseCell

Swift
swiftimport NEChatUIKit
import UIKit

class CustomChatCell: NEChatBaseCell {
  public var testLabel = UILabel()

  required init?(coder: NSCoder) {
    super.init(coder: coder)
  }

  override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    selectionStyle = .none
    backgroundColor = .lightGray
    testLabel.translatesAutoresizingMaskIntoConstraints = false
    contentView.addSubview(testLabel)
    NSLayoutConstraint.activate([
      testLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
      testLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
    ])
    testLabel.font = UIFont.systemFont(ofSize: 14)
    testLabel.textColor = UIColor.black
  }

  override func setModel(_ model: MessageContentModel, _ isSend: Bool) {
    if let model = model as? MessageCustomModel {
      print("this is custom message, customType: \(model.customType)")
      testLabel.text = model.message?.text
      
      let customContent = model.message?.attachment?.raw
    }
  }
}
Objective-C
Objective-C@interface CustomChatCell : NEChatBaseCell
@property (nonatomic, strong) UILabel *testLabel;
@end

@implementation CustomChatCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style
              reuseIdentifier:(NSString *)reuseIdentifier {
  self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
  if (self) {
    self.selectionStyle = UITableViewCellSelectionStyleNone;
    self.backgroundColor = UIColor.lightGrayColor;
    _testLabel = [[UILabel alloc] init];
    _testLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [self.contentView addSubview:_testLabel];
    [NSLayoutConstraint activateConstraints:@[
      [_testLabel.centerXAnchor constraintEqualToAnchor:self.contentView.centerXAnchor],
      [_testLabel.centerYAnchor constraintEqualToAnchor:self.contentView.centerYAnchor],
    ]];
    _testLabel.font = [UIFont systemFontOfSize:14];
    _testLabel.textColor = UIColor.blackColor;
  }
  return self;
}

- (void)setModel:(MessageContentModel *)model isSend:(BOOL)isSend {
  (void)isSend;
  if ([model isKindOfClass:[MessageCustomModel class]]) {
    self.testLabel.text = model.message.text;

    NSString *customContent = model.message.attachment.raw;
  }
}

@end

let customContent = model.message?.attachment?.raw 即为自定义消息内容。

注册自定义 NEChatBaseCell

CustomMessageCell 注册到 IM UIKit,使其在加载后能够处理您的自定义消息。

需要在重写的 ChatViewController 页面的 viewDidLoad 方法中的 super.viewDidLoad() 之前添加,此处的 customMessageType 即发送自定义消息时定义的 customMessageType

Swift
swiftNEChatUIKitClient.instance.regsiterCustomCell(["\(customMessageType)": CustomChatCell.self])
Objective-C
Objective-C[[NEChatUIKitClient instance] regsiterCustomCell:@{@"20" : [CustomChatCell class]}];

接收消息

IM UIKit 中已实现消息接收逻辑,您只需在 ChatViewController 重写父类的 onRecvMessages 方法即可。

Swift
Swift/// 收到消息
/// - Parameter messages: 消息列表
open func onRecvMessages(_ messages: [V2NIMMessage], _ indexs: [IndexPath]) {
    if let message = messages.first {
        // 解析自定义消息 attachment
        let attachment = NECustomUtils.attachmentOfCustomMessage(message.attachment)

        // 解析自定义消息 data 字段
        let data = NECustomUtils.dataOfCustomMessage(message.attachment)

        // 解析自定义消息 type 字段
        let type = NECustomUtils.typeOfCustomMessage(message.attachment)

        ...
    }
}
Objective-C
Objective-C/// 收到消息
/// - Parameter messages: 消息列表
- (void)onRecvMessages:(NSArray<V2NIMMessage *> *)messages indexs:(NSArray<NSIndexPath *> *)indexs {
    if (messages.firstObject) {
        // 解析自定义消息 attachment
        NSDictionary *attachment = [NECustomUtils attachmentOfCustomMessage:messages.firstObject.attachment];

        // 解析自定义消息 data 字段
        NSDictionary *data = [NECustomUtils dataOfCustomMessage:messages.firstObject.attachment];

        // 解析自定义消息 type 字段
        NSDictionary *type = [NECustomUtils typeOfCustomMessage:messages.firstObject.attachment];
        ...
    }
}
此文档是否对你有帮助?
有帮助
去反馈
  • 发送自定义消息
  • 自定义消息 UI 展示
  • 实现自定义 CustomChatCell
  • 注册自定义 NEChatBaseCell
  • 接收消息