iOS SDK Development Guide

Overview

JMessage provides developers with an easy-to-use and reliable IM development framework. Developers can integrate SDKs to quickly implement instant messaging capabilities. The JMessage iOS SDK supports systems after iOS 7. To learn more about JMessage, please refer to the document: Product Brief of JMessage

Function

The most important function of JMessage is the instant messaging.

  • Single chat, group chat

  • Message type: text, voice, picture, file, location, etc.

  • Save offline messages when users are offline;

  • Ensure timely delivery of messages

  • Based on JPush's original large-capacity and stable long-term connection, as well as concurrency capabilities for large-capacity message.

API interface

There are two ways to understand the complete SDK API:

  • Look directly at the Headers file in the JMessage.framework. These headers define the external interfaces provided by the SDK, with complete comments and descriptions, and even sample code.

  • Online version of documents generated by Appledoc: iOS SDK APIs

The following briefly lists the features provided by the SDK API and some simple examples.

SDK Initialization

The setupJMessage method defined in JMessage.h needs to be called when the application is initialized. It is recommended to call when the app loading is complete in AppDelegate.

Initialize the JMessage SDK

/*!
 * @abstract 初始化 JMessage SDK(此方法在JMessage 3.1.0 版本已过期)
 * 此方法被[setupJMessage:appKey:channel:apsForProduction:category:messageRoaming:]取代
 */
+ (void)setupJMessage:(NSDictionary *)launchOptions
               appKey:(NSString *)appKey
              channel:(NSString *)channel
     apsForProduction:(BOOL)isProduction
             category:(NSSet *)category;

SDK Initialization (Set Roaming)

Since v3.1.0

When the SDK is initializing, you can set whether to enable the message logging roaming. After the message roaming is enabled, when the user logs in between multiple devices, the SDK will automatically synchronize the history message to the local device. After the synchronization is completed, the SDK triggers the proxy method onSyncRoamingMessageConversation: in the unit of Conversation to inform the upper layer to refresh. For details, see Monitoring Agent of Message Synchronization.

/*!
 * @abstract 初始化 JMessage SDK
 *
 * @param launchOptions    AppDelegate启动函数的参数launchingOption(用于推送服务)
 * @param appKey           appKey(应用Key值,通过JPush官网可以获取)
 * @param channel          应用的渠道名称
 * @param isProduction     是否为生产模式
 * @param category         iOS8新增通知快捷按钮参数
 * @param isRoaming        是否启用消息漫游,默认关闭
 *
 * @discussion 此方法必须被调用, 以初始化 JMessage SDK
 *
 * 如果未调用此方法, 本 SDK 的所有功能将不可用.
 */
+ (void)setupJMessage:(NSDictionary *)launchOptions
               appKey:(NSString *)appKey
              channel:(NSString *)channel
     apsForProduction:(BOOL)isProduction
             category:(NSSet *)category
       messageRoaming:(BOOL)isRoaming;

Example
[JMessage setupJMessage:launchOptions
                 appKey:@"用户的AppKey"
                channel:@"应用的渠道名称"
       apsForProduction:NO
               category:nil
         messageRoaming:NO];

This call is a must, otherwise SDK will not work properly.

Register Remote Push

/*!
 * @abstract 注册远程推送
 * @param types 通知类型
 * @param categories 类别组
 * @discussion 此方法必须被调用,如果有集成JPush或其他远程推送注册方法,请不要再调用此方法
 *
 */
+ (void)registerForRemoteNotificationTypes:(NSUInteger)types
                                categories:(NSSet *)categories;

Register DeviceToken

/*!
 * @abstract 注册DeviceToken
 * @param deviceToken 从注册推送回调中拿到的DeviceToken
 * @discussion 此方法必须被调用
 *
 */
+ (void)registerDeviceToken:(NSData *)deviceToken;

Set Index (to the server)

/*!
 * @abstract 设置角标(到服务器)
 *
 * @param value 新的值. 会覆盖服务器上保存的值(这个用户)
 *
 * @discussion 本接口不会改变应用本地的角标值.
 * 本地仍须调用 UIApplication:setApplicationIconBadgeNumber 函数来设置角标.
 *
 * 该功能解决的问题是, 服务器端推送 APNs 时, 并不知道客户端原来已经存在的角标是多少, 指定一个固定的数字不太合理.
 *
 * APNS 服务器端角标功能提供:
 *
 * - 通过本 API 把当前客户端(当前这个用户的) 的实际 badge 设置到服务器端保存起来;
 * - 调用服务器端 API 发 APNs 时(通常这个调用是批量针对大量用户),
 *   使用 "+1" 的语义, 来表达需要基于目标用户实际的 badge 值(保存的) +1 来下发通知时带上新的 badge 值;
 */
+ (BOOL)setBadge:(NSInteger)value;

Reset Index (to the server)

/*!
 * @abstract 重置角标(为0)
 *
 * @discussion 相当于 [setBadge:0] 的效果.
 * 参考 [JMessage setBadge:] 说明来理解其作用.
 */
+ (void)resetBadge;

Registration and Login

User Registration

/*!
 * @abstract 新用户注册(支持携带用户信息字段)
 *
 * @param userInfo  用户名. 长度 4~128 位.
 *                  支持的字符: 字母,数字,下划线,英文减号,英文点,@邮件符号. 首字母只允许是字母或者数字.
 * @param password  用户密码. 长度 4~128 位.
 * @param userInfo  用户信息类,注册时携带用户信息字段,除用户头像字段
 * @param handler   结果回调. 返回正常时 resultObject 为 nil.
 *
 * @discussion 注意: 注册时不支持上传头像,其他信息全部支持
 */
+ (void)registerWithUsername:(NSString *)username
                    password:(NSString *)password
                    userInfo:(JMSGUserInfo *JMSG_NULLABLE)userInfo
           completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
JMSGUserInfo *info = [[JMSGUserInfo alloc]init];
info.nickname = @"昵称";
info.signature = @"签名";
//···
[JMSGUser registerWithUsername:@"用户名" password:@"密码" userInfo:info completionHandler:^(id resultObject, NSError *error) {
     if (!error) {
         //注册成功
     } else {
        //注册失败
     }
 }];

User Login

  • Return the login device information in the callback
/*!
 * @abstract 用户登录
 *
 * @param username 登录用户名. 规则与注册接口相同.
 * @param password 登录密码. 规则与注册接口相同.
 * @param handler 结果回调
 *
 * - devices 用户登录设备信息,NSArray<JMSGDeviceInfo>
 * - error   错误信息,为 nil 时表示成功
 *
 * @discussion 回调中 devices 返回的是设备信息,具体属性请查看 JMSGDeviceInfo 类
 */
+ (void)loginWithUsername:(NSString *)username
                 password:(NSString *)password
                  handler:(void(^)(NSArray <__kindof JMSGDeviceInfo *>*devices,NSError *error))handler;
/*!
 * @abstract 用户登录
 *
 * @param username 登录用户名. 规则与注册接口相同.
 * @param password 登录密码. 规则与注册接口相同.
 * @param handler 结果回调
 *
 * - resultObject 简单封装的user对象
 * - error 错误信息
 *
 * 注意:上层不要直接使用 resultObject 对象做操作, 因为 resultOjbect 只是一个简单封装的user对象.
 */

+ (void)loginWithUsername:(NSString *)username
                 password:(NSString *)password
        completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
[JMSGUser loginWithUsername:@"用户名" password:@"密码" completionHandler:^(id resultObject, NSError *error) {
      if (!error) {
         //登录成功
      } else {
         //登录失败
      } 
 }];

Sign out

/*!
 * @abstract 当前用户退出登录
 *
 * @param handler 结果回调。正常返回时 resultObject 也是 nil。
 *
 * @discussion 这个接口一般总是返回成功,即使背后与服务器端通讯失败,SDK 也总是会退出登录的。
 * 建议 App 也不必确认 SDK 返回, 就实际退出登录状态.
 */
+ (void)logout:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
//退出当前登录的用户
[JMSGUser logout:^(id resultObject, NSError *error) {
    if (!error) {
        //退出登录成功
    } else {
        //退出登录失败
    }
}];

Multi-end Simultaneously Online

SDK supports multi-end simultaneously online from the 3.3.0 release. For details, see Multi-end Online Description

User Management

Get user information in batches

/*!
 * @abstract 批量获取用户信息
 *
 * @param usernameArray 用户名列表。NSArray 里的数据类型为 NSString
 * @param handler 结果回调。正常返回时 resultObject 的类型为 NSArray,数组里的数据类型为 JMSGUser
 *
 * @discussion 这是一个批量接口。
 */
+ (void)userInfoArrayWithUsernameArray:(NSArray JMSG_GENERIC(__kindof NSString *)*)usernameArray
                     completionHandler:(JMSGCompletionHandler)handler;
Example
[JMSGUser userInfoArrayWithUsernameArray:@[@"username1", @"username2"] completionHandler:^(id resultObject, NSError *error) {
        if (!error) {
            //成功获取用户信息,resultObject为JMSGUser类型的数组
        } else {
            //获取用户信息失败
        }
    }];

Get user's personal information

/*!
 * @abstract 获取用户本身个人信息
 *
 * @return 当前登陆账号个人信息
 */
+ (JMSGUser *)myInfo;
Example
JMSGUser *user = [JMSGUser myInfo];

Update user information

/*!
 * @abstract 更新用户信息接口
 *
 * @param parameter     新的属性值
 *        Birthday&&Gender 是NSNumber类型, Avatar NSData类型 其他 NSString
 * @param type          更新属性类型
 * @param handler       更新用户信息回调接口函数
 */
+ (void)updateMyInfoWithParameter:(id)parameter
                    userFieldType:(JMSGUserField)type
                completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
/*
    userFieldType:
    kJMSGUserFieldsNickname: 用户名
    kJMSGUserFieldsBirthday: 生日
    kJMSGUserFieldsSignature: 签名
    kJMSGUserFieldsGender: 性别
    kJMSGUserFieldsRegion: 区域
    kJMSGUserFieldsAvatar: 头像
 */
[JMSGUser updateMyInfoWithParameter:parameter userFieldType:kJMSGUserFieldsGender completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        //updateMyInfoWithPareter success
    } else {
        //updateMyInfoWithPareter fail
    }
}];

Unified upload of user information updates

/*!
 * @abstract 更新用户信息(支持将字段统一上传)
 *
 * @param userInfo  用户信息对象,类型是 JMSGUserInfo
 * @param handler   更新用户信息回调接口函数
 *
 * @discussion 参数 userInfo 是 JMSGUserInfo 类,JMSGUserInfo 仅可用于修改用户信息
 */
+ (void)updateMyInfoWithUserInfo:(JMSGUserInfo *)userInfo
               completionHandler:(JMSGCompletionHandler)handler;
Example
JMSGUserInfo *userInfo = [[JMSGUserInfo alloc] init];
userInfo.nickname = @"new nick name";
userInfo.address = @"new address";
[JMSGUser updateMyInfoWithUserInfo:userInfo completionHandler:^(id resultObject, NSError *error) {
    //
}];

Update password

/*!
 * @abstract 更新密码接口
 *
 * @param newPassword   用户新的密码
 * @param oldPassword   用户旧的密码
 * @param handler       更新密码回调接口函数
 */
+ (void)updateMyPasswordWithNewPassword:(NSString *)newPassword
                            oldPassword:(NSString *)oldPassword
                      completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
[JMSGUser updateMyPasswordWithNewPassword:self.passwordField.text
                                      oldPassword:self.oldpassword.text
                                completionHandler:^(id resultObject, NSError *error) {
                                    if (!error) {
                                        //更新密码成功
                                    } else {
                                        //更新密码失败
                                    }
                                }];

Get avatar thumbnail

/*!
 * @abstract 获取头像缩略图文件数据
 *
 * @param handler 结果回调。回调参数:
 *
 * - data 头像数据;
 * - objectId 用户username;
 * - error 不为nil表示出错;
 *
 * 如果 error 为 ni, data 也为 nil, 表示没有头像数据.
 *
 * @discussion 需要展示缩略图时使用。
 * 如果本地已经有文件,则会返回本地,否则会从服务器上下载。
 */
- (void)thumbAvatarData:(JMSGAsyncDataHandler)handler;
Example
JMSGUser *user = [JMSGUser myInfo];
[user thumbAvatarData:^(NSData *data, NSString *objectId, NSError *error) {
    if (!error) {
        //下载成功
    } else {
        //下载失败
    }
}];

Get big picture of avatar

/*!
 * @abstract 获取头像大图文件数据
 *
 * @param handler 结果回调。回调参数:
 *
 * - data 头像数据;
 * - objectId 用户username;
 * - error 不为nil表示出错;
 *
 * 如果 error 为 ni, data 也为 nil, 表示没有头像数据.
 *
 * @discussion 需要展示大图图时使用
 * 如果本地已经有文件,则会返回本地,否则会从服务器上下载。
 */
- (void)largeAvatarData:(JMSGAsyncDataHandler)handler;
Example
JMSGUser *user = [JMSGUser myInfo];
[user largeAvatarData:^(NSData *data, NSString *objectId, NSError *error) {
                            if (!error) {
                                 //下载成功
                             } else {
                                //下载失败
                             }
                        }];

Get user display name

/*!
 * @abstract 用户展示名
 *
 * @discussion 如果 nickname 存在则返回 nickname,否则返回 username
 */
- (NSString *)displayName;
Example
JMSGUser *user = [JMSGUser myInfo];
NSString myName = [user displayName];

Modify friend's note name and note information

/*!
 * @abstract 修改好友备注名
 *
 * @param noteName 备注名
 *
 * @discussion 注意:这是建立在是好友关系的前提下,修改好友的备注名
 */
- (void)updateNoteName:(NSString *)noteName completionHandler:(JMSGCompletionHandler)handler;

/*!
 * @abstract 修改好友备注信息
 *
 * @param noteText 备注信息
 *
 * @discussion 注意:这是建立在是好友关系的前提下,修改好友的备注信息
 */
- (void)updateNoteText:(NSString *)noteText completionHandler:(JMSGCompletionHandler)handler;
Example
// 修改备注名
[friendUser updateNoteName:@"备注名" completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        [MBProgressHUD showMessage:@"修改备注成功" view:self.view];
    }else{
        [MBProgressHUD showMessage:@"修改备注失败" view:self.view];
    }
 }];

Change in Receiving Messages Starting from Version 3.1.0

From version 3.1.0, SDK distributes the message delivery into online delivery and offline delivery. Offline delivery includes offline messages and roaming messages. Please figure out these concepts first:

  • Online messages: During an IM user's online time, all incoming messages are called online messages.

  • Offline messages: Messages received by IM users during off-line (including logout or network disconnection) will be temporarily stored on the Jiguang Server. When the user goes online again, the SDK will pull these messages off. This part of the message is called offline messages.

  • Roaming messagess: When an IM user logs in multiple devices, the SDK treats the messages received on other devices as roaming messages.

SDK version Online messages Offline messages Roaming messages
Version \< 3.1.0 Issued one by one, trigger onReceiveMessage: each time Issued one by one, trigger onReceiveMessage: each time: none
Version >= 3.1.0 Issued one by one, trigger onReceiveMessage: each time In session units, issue onSyncOfflineMessageConversation: after a trigger In session units, issue onSyncRoamingMessageConversation: after a trigger

With the distinction between these concepts, SDK has handled the two kinds of messages differently:

Summary

For message synchronization with the session as the unit, SDK only triggers proxy method of message synchronization once, regardless of the number of offline messages in the session. This return value of proxy method contains specific related information such as a session and offline message. The upper layer could listen to each session by this method to complete the message synchronization and refresh the UI, which will greatly reduce the pressure on the upper to process events.

After SDK is upgraded to version 3.1.0 (or later), the upper layer only needs to make the following changes:

  • Set message roaming. Call new SDK initialization to set message roaming.

  • Add a proxy method for roaming messages onSyncRoamingMessageConversation: This method allows you to listen for roaming message synchronization and refresh the UI (developers who do not need roaming messages can ignore this action).

  • Add a proxy method for off-line messages  onSyncOfflineMessageConversation: This method allows you to listen to offline message synchronization and refresh the UI.

Note:

Starting with SDK 3.2.1 (including 3.2.1), offline events also take the message synchronization policy. Offline events are divided into:

  • Group events: If there is an offline group event, a proxy method for offline message is also triggered

  • Non-group events: Other events remain unchanged, taking the previous proxy method.

Message Management

Create a single chat message

/*!
 * @abstract 创建单聊消息
 *
 * @param content 消息内容对象
 * @param username 单聊用户 username
 *
 * @discussion 不关心会话时的直接创建聊天消息的接口。一般建议使用 JMSGConversation -> createMessageWithContent:
 */
+ (JMSGMessage *)createSingleMessageWithContent:(JMSGAbstractContent *)content
                                       username:(NSString *)username;
Example
JMSGTextContent *textContent = [[JMSGTextContent alloc] initWithText:@"textContent"];
JMSGMessage *message = [JMSGMessage createSingleMessageWithContent:textContent username:@"username"];

Create a group chat message

/*!
 * @abstract 创建群聊消息
 *
 * @param content 消息内容对象
 * @param groupId 群聊ID
 *
 * @discussion 不关心会话时的直接创建聊天消息的接口。一般建议使用 JMSGConversation -> createMessageWithContent:
 */
+ (JMSGMessage *)createGroupMessageWithContent:(JMSGAbstractContent *)content
                                       groupId:(NSString *)groupId;
Example
JMSGTextContent *textContent = [[JMSGTextContent alloc] initWithText:@"textContent"];
JMSGMessage *message = [JMSGMessage createGroupMessageWithContent:textContent groupId:@"groupId"];

Send a message

/*!
 * @abstract 发送消息(已经创建好的)
 *
 * @param message 消息对象。
 *
 * @discussion 此接口与 createMessage:: 相关接口配合使用,创建好后使用此接口发送。
 */
+ (void)sendMessage:(JMSGMessage *)message;

Send text message of single chat

/*!
 * @abstract 发送单聊文本消息
 *
 * @param text 文本内容
 * @param username 单聊对象 username
 *
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendSingleTextMessage:(NSString *)text
                       toUser:(NSString *)username;

Send picture message of single chat

/*!
 * @abstract 发送单聊图片消息
 *
 * @param imageData 图片数据
 * @param username 单聊对象 username
 *
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendSingleImageMessage:(NSData *)imageData
                        toUser:(NSString *)username;

Send voice message of a single chat

/*!
 * @abstract 发送单聊语音消息
 *
 * @param voiceData 语音数据
 * @param duration 语音时长
 * @param username 单聊对象 username
 *
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendSingleVoiceMessage:(NSData *)voiceData
                 voiceDuration:(NSNumber *)duration
                        toUser:(NSString *)username;

Send file message of single chat

/*!
 * @abstract 发送单聊文件消息
 *
 * @param fileData 文件数据数据
 * @param fileName 文件名
 * @param username 单聊对象 username
 *
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendSingleFileMessage:(NSData *)fileData
                     fileName:(NSString *)fileName
                       toUser:(NSString *)username;

Send location message of single chat

/*!
 * @abstract 发送单聊地理位置消息
 * @param latitude 纬度
 * @param longitude 经度
 * @param scale 缩放比例
 * @param address 详细地址
 * @param username 单聊对象
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendSingleLocationMessage:(NSNumber *)latitude
                        longitude:(NSNumber *)longitude
                            scale:(NSNumber *)scale
                          address:(NSString *)address
                           toUser:(NSString *)username;

Send text message of group chat

/*!
 * @abstract 发送群聊文本消息
 *
 * @param text 文本内容
 * @param groupId 群聊目标群组ID
 *
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendGroupTextMessage:(NSString *)text
                     toGroup:(NSString *)groupId;

Send picture message of group chat

/*!
 * @abstract 发送群聊图片消息
 *
 * @param imageData 图片数据
 * @param groupId 群聊目标群组ID
 *
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendGroupImageMessage:(NSData *)imageData
                      toGroup:(NSString *)groupId;

Send voice message of group chat

/*!
 * @abstract 发送群聊语音消息
 *
 * @param voiceData 语音数据
 * @param duration 语音时长
 * @param groupId 群聊目标群组ID
 *
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendGroupVoiceMessage:(NSData *)voiceData
                voiceDuration:(NSNumber *)duration
                      toGroup:(NSString *)groupId;

Send file message of group chat

/*!
 * @abstract 发送群聊文件消息
 *
 * @param fileData 文件数据
 * @param fileName 文件名
 * @param groupId 群聊目标群组ID
 *
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendGroupFileMessage:(NSData *)fileData
                    fileName:(NSString *)fileName
                     toGroup:(NSString *)groupId;

Send location message of group chat

/*!
 * @abstract 发送群聊地理位置消息
 * @param latitude 纬度
 * @param longitude 经度
 * @param scale 缩放比例
 * @param address 详细地址
 * @param groupId 群聊目标群组ID
 */
+ (void)sendGroupLocationMessage:(NSNumber *)latitude
                       longitude:(NSNumber *)longitude
                           scale:(NSNumber *)scale
                         address:(NSString *)address
                         toGroup:(NSString *)groupId;

Message forwarding

/*!
 * @abstract 消息转发
 *
 * @param message         需要转发的消息
 * @param target          目标 target,只能为 JMSGUser 或 JMSGGroup
 * @param optionalContent 可选功能,具体请查看 JMSGOptionalContent 类
 *
 * @discussion 注意:只能转发消息状态为 SendSucceed 和 ReceiveSucceed 的消息。
 */
+ (void)forwardMessage:(JMSGMessage *)message
                target:(id)target
       optionalContent:(JMSGOptionalContent *JMSG_NULLABLE)optionalContent;

Set the message's FromName

/*!
 * @abstract 设置消息的 fromName(即:通知栏的展示名称)
 *
 * @param fromName 本条消息在接收方通知栏的展示名称
 *
 * @discussion fromName填充在发出的消息体里,对方收到该消息通知时,在通知栏显示的消息发送人名称就是该字段的值.
 *
 */
- (void)setFromName:(NSString * JMSG_NULLABLE)fromName;

Update extra in message

/*!
 * @abstract 更新 message 中的 extra
 *
 * @param value   待更新的value,不能为null,类型只能为 NSNumber 和 NSString
 * @param key     待更新value对应的key,不能为null
 *
 */
- (BOOL)updateMessageExtraValue:(id)value forKey:(NSString *)key;

Session Management

Session related operations:

Get a single chat session

/*!
 * @abstract 获取单聊会话
 *
 * @param username 单聊对象 username
 *
 * @discussion 如果会话还不存在,则返回 nil
 */
+ (JMSGConversation * JMSG_NULLABLE)singleConversationWithUsername:(NSString *)username;

Get a group chat conversation

/*!
 * @abstract 获取群聊会话
 *
 * @param groupId 群聊群组ID。此 ID 由创建群组时返回的。
 *
 * @discussion 如果会话还不存在,则返回 nil
 */
+ (JMSGConversation * JMSG_NULLABLE)groupConversationWithGroupId:(NSString *)groupId;

Get a chat room session

/*!
 * @abstract 获取聊天室会话
 *
 * @param roomId 聊天室 ID
 *
 * @discussion 如果会话还不存在,则返回 nil
 */
+ (JMSGConversation * JMSG_NULLABLE)chatRoomConversationWithRoomId:(NSString *)roomId;

Create a single chat session

/*!
 * @abstract 创建单聊会话
 *
 * @param username 单聊对象 username
 * @param handler 结果回调。正常返回时 resultObject 类型为 JMSGConversation。
 *
 * @discussion 如果会话已经存在,则直接返回。如果不存在则创建。
 * 创建会话时如果发现该 username 的信息本地还没有,则需要从服务器上拉取。
 * 服务器端如果找不到该 username,或者某种原因查找失败,则创建会话失败。
 */
+ (void)createSingleConversationWithUsername:(NSString *)username
                           completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
[JMSGConversation createSingleConversationWithUsername:@"username" completionHandler:^(id resultObject, NSError *error) {
                    if (!error) {
                       //创建单聊会话成功, resultObject为创建的会话
                    } else {
                        //创建单聊会话失败
                    }
                }];

Create a group chat session

/*!
 * @abstract 创建群聊会话
 *
 * @param groupId 群聊群组ID。由创建群组时返回。
 * @param handler 结果回调。正常返回时 resultObject 类型为 JMSGConversation。
 *
 * @discussion 如果会话已经存在,则直接返回。如果不存在则创建。
 * 创建会话时如果发现该 groupId 的信息本地还没有,则需要从服务器端上拉取。
 * 如果从服务器上获取 groupId 的信息不存在或者失败,则创建会话失败。
 */
+ (void)createGroupConversationWithGroupId:(NSString *)groupId
                         completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
[JMSGConversation createGroupConversationWithGroupId:@"groupId" completionHandler:^(id resultObject, NSError *error) {
                        if (!error) {
                           //创建群聊用会话成功, resultObject为创建的会话
                        } else {
                            //创建群聊会话失败
                        }
                    }];

Create a chat room session

/*!
 * @abstract 创建聊天室会话
 *
 * @param roomId  聊天室 ID。
 * @param handler 结果回调。正常返回时 resultObject 类型为 JMSGConversation。
 *
 * @discussion 如果会话已经存在,则直接返回。如果不存在则创建。
 * 创建会话时如果发现该 roomId 的信息本地还没有,则需要从服务器端上拉取。
 * 如果从服务器上获取 roomId 的信息不存在或者失败,则创建会话失败。
 */
+ (void)createChatRoomConversationWithRoomId:(NSString *)roomId
                           completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

Delete a single chat session

/*!
 * @abstract 删除单聊会话
 *
 * @param username 单聊用户名
 *
 * @discussion 除了删除会话本身,还会删除该会话下所有的聊天消息。
 */
+ (BOOL)deleteSingleConversationWithUsername:(NSString *)username;

Delete a group chat session

/*!
 * @abstract 删除群聊会话
 *
 * @param groupId 群聊群组ID
 *
 * @discussion 除了删除会话本身,还会删除该会话下所有的聊天消息。
 */
+ (BOOL)deleteGroupConversationWithGroupId:(NSString *)groupId;

Delete a chat room conversation

/*!
 * @abstract 删除聊天室会话
 *
 * @param roomId  聊天室 ID
 *
 * @discussion 除了删除会话本身,还会删除该会话下所有的聊天消息。
 */
+ (BOOL)deleteChatRoomConversationWithRoomId:(NSString *)roomId;

List of session list

/*!
 * @abstract 返回 conversation 列表(异步,已经排序)
 *
 * @param handler 结果回调。正常返回时 resultObject 的类型为 NSArray,数组里成员的类型为 JMSGConversation
 *
 * @discussion 当前是返回所有的 conversation 列表,不包括聊天室会话,默认是已经排序。
 *
 */
 + (void)allConversations:(JMSGCompletionHandler)handler;
Example
[JMSGConversation allConversations:^(id resultObject, NSError *error) {
        if (!error) {
           //获取成功,resultObject为会话对的数组
        } else {
            //获取失败
        }
    }];

List of chat room conversation

/*!
 * @abstract 返回聊天室 conversation 列表(异步,已排序)
 *
 * @param handler 结果回调。正常返回时 resultObject 的类型为 NSArray,数组里成员的类型为 JMSGConversation
 *
 * @discussion 当前是返回所有的chatroom conversation 列表,不包括单聊和群聊会话,默认是已经排序。
 */
+ (void)allChatRoomConversation:(JMSGCompletionHandler)handler;

Message related operations:

Get a message

/*!
 * @abstract 获取某条消息
 *
 * @param msgId 本地消息ID
 *
 * @discussion 这个接口在正常场景下不需要单独使用到. 获取消息一般应使用 [JSMGConversation messageArrayFromNewestWithOffset::]
 *
 * 注意: 这里的 msgId 概念同 [JMSGMessage msgId], 是本地生成的消息ID, 而非 [JMSGMessage serverMessageId]
 */
- (JMSGMessage * JMSG_NULLABLE)messageWithMessageId:(NSString *)msgId;

Paginate to get messages

/*!
 * @abstract 同步分页获取最新的消息
 *
 * @param offset 开始的位置。nil 表示从最初开始。
 * @param limit 获取的数量。nil 表示不限。
 *
 * @return 返回消息列表(数组)。数组成员的类型是 JMSGMessage*
 *
 * @discussion 排序规则是:最新
 *
 * 参数举例:
 *
 * - offset = nil, limit = nil,表示获取全部。相当于 allMessages。
 * - offset = nil, limit = 100,表示从最新开始取 100 条记录。
 * - offset = 100, limit = nil,表示从最新第 100 条开始,获取余下所有记录。
 */
- (NSArray JMSG_GENERIC(__kindof JMSGMessage *) *)messageArrayFromNewestWithOffset:(NSNumber *JMSG_NULLABLE)offset
                                                                             limit:(NSNumber *JMSG_NULLABLE)limit;

Get all message records

/*!
 * @abstract 异步获取所有消息记录
 *
 * @param handler 结果回调。正常返回时 resultObject 类型为 NSArray,数据成员类型为 JMSGMessage。
 *
 * @discussion 排序规则:最新
 */
- (void)allMessages:(JMSGCompletionHandler)handler;
Example
//_conversation 为Conversation的实例对象
[conversation allMessages:^(id resultObject, NSError *error) {
        NSArray *array = (NSArray *)resultObject;
        LogInfo(@"消息数:%ld", (long)array.count);
    }];

Delete messages

/*!
 * @abstract 删除一条消息
 *
 * @param msgId 本地消息ID
 */
- (BOOL)deleteMessageWithMessageId:(NSString *)msgId;

Delete all messages

/*!
 * @abstract 删除全部消息
 *
 * @discussion 清空当前会话的所有消息。
 */
- (BOOL)deleteAllMessages;

Create a message object

/*!
 * @abstract 创建消息对象
 *
 * @param content 消息的内容对象。当前直接的内容对象有:
 * JMSGTextContent, JMSGImageContent, JMSGVoiceContent, JMSGCustomContent
 *
 * @return JMSGMessage对象。该对象里包含了 content。
 *
 * @discussion 这是推荐的创建新的消息拿到 JMSGMessage 对象接口。
 *
 * 此接口创建消息后, SDK 会进行落地, 包括: 消息保存数据库, 媒体文件保存到文件系统.
 * 这意味着, 这个创建后的消息对象, App 可以用来放到 UI 上展示.
 *
 * 新创建的消息对象, 其消息状态 status 为: kJMSGMessageStatusSendDraft
 *
 * 调用此接口前需要先创建消息内容,以作为 content 参数传入。举例:
 *
 *    ```
 *    NSData *imageData = … // 可能来自拍照或者相册
 *    JMSGImageContent *imageContent = [[JMSGImageContent alloc] initWithImageData:imageData];
 *    ```
 *
 * 另外更快捷的作法是,不通过此接口创建 JMSGMessage 而是直接调用具体的发送接口,如 sendSingleTextMessage.
 *
 * 通过此接口先创建 JMSGMessage 的好处是,可以对 JMSGMessage 做更多的定制控制,比如加附加字段。举例:
 *
 *    ```
 *    [imageContent addExtraValue:@"extra_value" forKey:@"extra_key"]
 *    ```
 *
 * 注意:如果创建消息的内容是图片,并且图片可能比较大,则建议不要使用这个同步接口,
 * 改用 createMessageAsyncWithImageContent:completionHandler: 方法。
 */
- (JMSGMessage * JMSG_NULLABLE)createMessageWithContent:(JMSGAbstractContent *)content;

Create a picture message object

/! * @abstract 创建消息对象(图片,异步) * @param content 准备好的图片内容 * @param handler 结果回调. 正常返回时 resultObject 类型为 JMSGMessage. * @discussion 对于图片消息,因为 SDK 要做缩图有一定的性能损耗,图片文件很大时存储落地也会较慢。 * 所以创建图片消息,建议使用这个异步接口。 / - (void)createMessageAsyncWithImageContent:(JMSGImageContent *)content completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

Example
//_conversation 为Conversation的实例对象
[_conversation createMessageAsyncWithImageContent:imageContent completionHandler:^(id resultObject, NSError *error) {
            if (!error) {
                //创建成功
                //resultObject 为Message内容
            }
        }];

Send a message

/*!
 * @abstract 发送消息(已经创建好对象的)
 *
 * @param message 通过消息创建类接口,创建好的消息对象
 *
 * @discussion 发送消息的多个接口,都未在方法上直接提供回调。你应通过 xxx 方法来注册消息发送结果。
 */
- (void)sendMessage:(JMSGMessage *)message;

Send a text message

/*!
 * @abstract 发送文本消息
 * @param text 文本消息内容
 * @discussion 快捷发消息接口。如果发送文本消息不需要附加 extra,则使用此接口更方便。
 */
- (void)sendTextMessage:(NSString *)text;

Send a picture message

/*!
 * @abstract 发送图片消息
 * @param imageData 图片消息数据
 * @discussion 快捷发送消息接口。如果发送图片消息不需要附加 extra,则使用此接口更方便。
 */
- (void)sendImageMessage:(NSData *)imageData;

Send a voice message

/*!
 * @abstract 发送语音消息
 * @param voiceData 语音消息数据
 * @param duration 语音消息时长(秒). 长度必须大于 0.
 * @discussion 快捷发送消息接口。如果发送语音消息不需要附加 extra,则使用此接口更方便。
 */
- (void)sendVoiceMessage:(NSData *)voiceData
                duration:(NSNumber *)duration;

Send a file message

/*!
 * @abstract 发送文件消息
 * @param voiceData 文件消息数据
 * @param fileName 文件名
 * @discussion 快捷发送消息接口。如果发送文件消息不需要附加 extra,则使用此接口更方便。
 */
- (void)sendFileMessage:(NSData *)fileData
               fileName:(NSString *)fileName;

Send a location message

/*!
 * @abstract 发送地理位置消息
 * @param latitude 纬度
 * @param longitude 经度
 * @param scale 缩放比例
 * @param address 详细地址
 * @discussion 快捷发送消息接口。如果发送文件消息不需要附加 extra,则使用此接口更方便。
 */
- (void)sendLocationMessage:(NSNumber *)latitude
                  longitude:(NSNumber *)longitude
                      scale:(NSNumber *)scale
                    address:(NSString *)address;

Get a session avatar

/*!
 * @abstract 异步获取会话头像
 *
 * @param handler 结果回调。回调参数:
 *
 * - data 头像数据;
 * - objectId 为 targetId_conversationType 的组合, 用下划线隔开.
 *   其中 targetId 单聊时为 username_targetAppKey,
 *                 群聊时为 groupId
 * - error 不为nil表示出错;
 *
 * 如果 error 为 ni, data 也为 nil, 表示没有数据.
 *
 * @discussion 会话的头像来自于聊天对象, 单聊就是用户的头像, 群聊是群组头像.
 * 建议在会话列表时, 使用此接口来显示会话的头像, 而不要使用 target 属性里的用户头像.
 */
- (void)avatarData:(JMSGAsyncDataHandler)handler;
Example
//_conversation 为Conversation的实例对象
[_conversation avatarData:^(NSData *data, NSString *objectId, NSError *error) {
        if (!error) {
            //获取成功
        } else {
            //获取失败
        }];

Get the total number of unread messages in all sessions

/*!
 * @abstract 获取当前所有会话的未读消息的总数
 *
 * @discussion 获取所有会话未读消息总数
 */
+ (NSNumber *)getAllUnreadCount;

Clear numbers of unread sessions

/*!
 * @abstract 清除会话未读数
 *
 * @discussion 把未读数设置为 0
 */
- (void)clearUnreadCount;

The total number of unread messages in all sessions

/*!
 * @abstract 获取当前所有会话的未读消息的总数
 *
 * @discussion 获取所有会话未读消息总数
 */
+ (NSNumber *)getAllUnreadCount;

Get content text of the last message

/*!
 * @abstract 获取最后一条消息的内容文本
 *
 * @discussion 通常用来展示在会话列表的第 2 行. 如果是图片消息,通常是文本 [图片] 之类. CustomContent 可以定制这个文本.
 */
- (NSString *)latestMessageContentText;
Example
//_conversation 为Conversation的实例对象
NSString *latestMessageText = [_conversation latestMessageContentText];

Determine if the message belongs to this Conversation

/*!
 * @abstract 判断消息是否属于这个 Conversation
 *
 * @param message 待判断的消息对象
 *
 * @discussion 当前在聊天界面时,接收到消息通知,需要通过这个接口判断该消息是否属于当前这个会话,从而做不同的动作
 *
 * 如果注册消息接收事件时,只注册接收当前会话的消息,则不需要用此接口判断.
 */
- (BOOL)isMessageForThisConversation:(JMSGMessage *)message;

Refresh session information from the server

/*!
 * @abstract 从服务器端刷新会话信息
 *
 * @param handler 结果回调。返回正常时 resultObject 为当前 conversation 对象.
 *
 * @discussion 会话信息的 title/avatar 信息, 单聊来自于 UserInfo,对于群聊来自于 GroupInfo。
 * 建议在进入聊天界面时,调用此接口,来更新会话属性。
 * 典型的情况是, 此接口返回时, 刷新单聊界面顶部的会话标题. (有可能聊天对方昵称改变了, 或者群组名称改变了, 聊天标题需要刷新)
 *
 * 此接口供暂时使用。JMessage 整体的 Sync 机制生效后,将不需要客户端主动去刷新信息。
 */
- (void)refreshTargetInfoFromServer:(JMSGCompletionHandler)handler;
Example
//_conversation 为Conversation的实例对象
[_conversation refreshTargetInfoFromServer:^(id resultObject, NSError *error) {
    if (!error) {
      //success
    } else {
      //刷新失败
    }
  }];

  /*!

Group Management

The group is divided into private group and public group. Type of the group cannot be modified after the group is created successfully. Application is needed if you want to enter a public group. After the administrator approves the application, you can enter the group.

Create a group (can only create private groups)

/*!
 * @abstract 创建群组(只能创建私有群)
 *
 * @param groupName 群组名称
 * @param groupDesc 群组描述信息
 * @param usernameArray 初始成员列表。NSArray 里的类型是 NSString
 * @param handler 结果回调。正常返回 resultObject 的类型是 JMSGGroup。
 *
 * @discussion 向服务器端提交创建群组请求,返回生成后的群组对象.
 * 返回群组对象, 群组ID是App 需要关注的, 是后续各种群组维护的基础.
 */
+ (void)createGroupWithName:(NSString * JMSG_NULLABLE )groupName
                       desc:(NSString *JMSG_NULLABLE)groupDesc
                memberArray:(NSArray JMSG_GENERIC(__kindof NSString *) *JMSG_NULLABLE)usernameArray
          completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
//  创建群组
[JMSGGroup createGroupWithName:@"群名" desc:@"群描述" memberArray:[NSArray arrayWithObjects:@"username1",@"username2", nil] completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        NSLog(@"创建群组成功!");
        JMSGGroup *group = (JMSGGroup *)resultObject;
    }
}];

Create groups (you can create private groups, public groups)

/*!
 * @abstract 创建群组(可创建私有群、公开群)
 *
 * @param groupInfo     群信息类,如:群名、群类型等,详细请查看 JMSGGroupInfo 类
 * @param usernameArray 初始成员列表。NSArray 里的类型是 NSString
 * @param handler       结果回调。正常返回 resultObject 的类型是 JMSGGroup。
 *
 * @discussion 向服务器端提交创建群组请求,返回生成后的群组对象.
 * 返回群组对象, 群组ID是App 需要关注的, 是后续各种群组维护的基础.
 */
+ (void)createGroupWithGroupInfo:(JMSGGroupInfo *)groupInfo
                     memberArray:(NSArray JMSG_GENERIC(__kindof NSString *) *JMSG_NULLABLE)usernameArray
               completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
JMSGGroupInfo *info = [[JMSGGroupInfo alloc] init];
info.name =@"公开群001";
info.groupType = kJMSGGroupTypePublic;
info.desc = @"这个群组是公开群";
[JMSGGroup createGroupWithGroupInfo:info memberArray:nil completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        myGroup = resultObject;
    }
}];

Dissolve groups

  • Group type: Both general and restricted groups have this feature

  • Permissions: Only the owner can disband. Normal group members and administrators do not have this permission

/*!
 * @abstract 解散群组
 *
 * @patam gid     需要解散的群组 id
 * @param handler 结果回调,error = nil 表示操作成功
 *
 * @discussion 只有群主才有权限解散群。
 */
+ (void)dissolveGroupWithGid:(NSString *)gid handler:(JMSGCompletionHandler)handler;

Get list of public group

Support paging to obtain public group information under AppKey. Note that the array element returned by the interface is JMSGGroupInfo instead of JMSGGroup. If you need to obtain the group's property value and call the group interface, you need to obtain the JMSGGroup object through the gid in JMSGGroupInfo, and then operate:

/*!
 * @abstract 分页获取 appkey 下所有公开群信息
 *
 * @param appkey    群组所在的 AppKey,不填则默认为当前应用 AppKey
 * @param start     分页获取的下标,第一页从  index = 0 开始
 * @param count     每一页的数量,最大值为500
 * @param handler   结果回调,NSArray<JMSGGroupInfo>
 *
 * #### 注意:返回数据中不是 JMSGGroup 类型,而是 JMSGGroupInfo 类型,只能用于展示信息,如果想要调用相关群组 API 接口则需要通过 gid 获取到 JMSGGroup 对象才可以调用
 */
+ (void)getPublicGroupInfoWithAppKey:(NSString *JMSG_NULLABLE)appkey
                               start:(NSInteger)start
                               count:(NSInteger)count
                   completionHandler:(JMSGCompletionHandler)handler;

Update group information

/*!
 * @abstract 更新群组信息
 *
 * @param groupId 待更新的群组ID
 * @param groupName 新名称
 * @param groupDesc 新描述
 * @param handler 结果回调. 正常返回时, resultObject 为 nil.
 *
 * @discussion 注意:name 和 desc 不允许传空字符串
 */
+ (void)updateGroupInfoWithGroupId:(NSString *)groupId
                              name:(NSString *JMSG_NULLABLE)groupName
                              desc:(NSString *JMSG_NULLABLE)groupDesc
                 completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
// 更新群组信息
[JMSGGroup updateGroupInfoWithGroupId:@"group.gid" name:@"新群名" desc:@"新群描述" completionHandler:^(id resultObject, NSError *error) {
            if (!error) {
                NSLog(@"更新群组信息成功!");
            }
}];

Update group information (Upload uniform field)

/*!
 * @abstract 更新群信息(统一字段上传)
 *
 * @param gid         群组 id
 * @param groupInfo   群信息类,详细请查看 JMSGGroupInfo 类
 * @param handler     结果回调. 正常返回时, resultObject 为 nil.
 *
 * @discussion 注意:修改群名称和群描述时参数不允许传空字符串
 */
+ (void)updateGroupInfoWithGid:(NSString *)gid
                     groupInfo:(JMSGGroupInfo *)groupInfo
             completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

Update avatar

/*!
 * @abstract 更新群头像(支持传图片格式)
 *
 * @param groupId         待更新的群组ID
 * @param avatarData      头像数据
 * @param avatarFormat    头像格式,可以为空,不包括"."
 * @param handler         回调
 *
 * @discussion 头像格式参数直接填格式名称,不要带点。正确:@"png",错误:@".png"
 */
+ (void)updateGroupAvatarWithGroupId:(NSString *JMSG_NONNULL)groupId
                          avatarData:(NSData *JMSG_NONNULL)avatarData
                        avatarFormat:(NSString *JMSG_NULLABLE)avatarFormat
                   completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

Get group information

/*!
 * @abstract 获取群组信息
 *
 * @param groupId 待获取详情的群组ID
 * @param handler 结果回调. 正常返回时 resultObject 类型是 JMSGGroup.
 *
 * @discussion 该接口总是向服务器端发起请求, 即使本地已经存在.
 * 如果考虑性能损耗, 在群聊时获取群组信息, 可以获取 JMSGConversation -> target 属性.
 */
+ (void)groupInfoWithGroupId:(NSString *)groupId
           completionHandler:(JMSGCompletionHandler)handler;
Example
// 获取群组信息
[JMSGGroup groupInfoWithGroupId:@"群组ID" completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        JMSGGroup *group = (JMSGGroup *)resultObject;
        NSLog(@"获取群组信息成功");
    }
}];

Set up a group administrator

  • Scope: Admin roles are increased in both private and public groups.

  • Description: Only the owner can manage the group administrator and specify any member in the group as an administrator or cancel the identity of administrator.

  • Administrator privilege: Administrator has all the basic functions and permissions of the common group members. In addition to this, he also has higher privilege: setting bans and approving application.

/*!
 * @abstract 添加管理员
 *
 * @param username 用户名
 * @param appkey   用户 AppKey,不填则默认为本应用 AppKey
 * @param handler 结果回调。error 为 nil 表示成功.
 *
 * @discussion 注意:非 VIP 应用最多设置 15 个管理员,不包括群主本身
 */
- (void)addGroupAdminWithUsername:(NSString *JMSG_NONNULL)username
                           appKey:(NSString *JMSG_NULLABLE)appkey
                completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

/*!
 * @abstract 删除管理员
 *
 * @param username 用户名
 * @param appkey   用户 AppKey,不填则默认为本应用 AppKey
 * @param handler 结果回调。error 为 nil 表示成功.
 */
- (void)deleteGroupAdminWithUsername:(NSString *)username
                              appKey:(NSString *JMSG_NULLABLE)appkey
                   completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
/*!
 * @abstract 判断用户是否是管理员
 *
 * @param username  待判断用户的用户名
 * @param appKey    待判断用户的appKey,若传入空则默认使用本应用appKey
 */
- (BOOL)isAdminMemberWithUsername:(NSString *JMSG_NONNULL)username
                           appKey:(NSString *JMSG_NULLABLE)appKey;

/*!
 * @abstract 管理员列表
 *
 * @return 管理员列表. NSArray 里成员类型是 JMSGUser
 *
 * @discussion 注意:返回列表中包含群主;仅在获取群成员成功后此接口才有效
 */
- (NSArray JMSG_GENERIC(__kindof JMSGUser *)*)groupAdminMembers;

Transfer owner

  • The owner can select any member of the group to transfer the authority of owner to him. The group owner becomes an ordinary group member after the transition.

  • Applicable group type: Both private and public groups have this feature

  • Only owners have this permission

/*!
 * @abstract 移交群主
 *
 * @param username 新群主用户名
 * @param appkey   新群主用户 AppKey,不填则默认为本应用 AppKey
 * @param handler 结果回调。error 为 nil 表示成功.
 */
- (void)transferGroupOwnerWithUsername:(NSString *JMSG_NONNULL)username
                                appKey:(NSString *JMSG_NULLABLE)appkey
                     completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

Apply to the group

For the public group, you need to apply for or be invited by other group members, and approved by the administrator before entering the group.

/*!
 * @abstract 申请加入群组
 *
 * @param gid     群组 gid
 * @param reason   申请原因
 * @param handler 结果回调
 *
 * @discussion 只有公开群需要申请才能加入,私有群不需要申请。
 */
+ (void)applyJoinGroupWithGid:(NSString *JMSG_NONNULL)gid
                       reason:(NSString *JMSG_NULLABLE)reason
            completionHandler:(JMSGCompletionHandler)handler;

Administrator approves applications for admission

When a user requests to join the group, the administrator will receive a  JMSGApplyJoinGroupEvent event and he needs to approve the application. If the administrator rejects the application, both the applicant and the respondent will receive a  JMSGGroupAdminRejectApplicationEvent event.

/*!
 * @abstract 管理员审批入群申请
 *
 * @patam eventId     入取申请事件的 id,详情请查看 JMSGApplyJoinGroupEvent 类
 * @param gid         群组 gid
 * @param joinUser    入群的用户
 * @param applyUser   发起申请的的用户,如果是主动申请入群则和 member 是相同的
 * @param isAgree     是否同意申请,YES : 同意, NO: 不同意
 * @param reason      拒绝申请的理由,选填
 * @param handler     结果回调
 *
 * @discussion 只有管理员才有权限审批入群申请,SDK 不会保存申请入群事件(JMSGApplyJoinGroupEvent),上层可以自己封装再保存,或则归档直接保存,以便此接口取值调用。
 */
+ (void)processApplyJoinGroupEventID:(NSString *JMSG_NONNULL)eventId
                                 gid:(NSString *JMSG_NONNULL)gid
                            joinUser:(JMSGUser *JMSG_NONNULL)joinUser
                           applyUser:(JMSGUser *JMSG_NONNULL)applyUser
                             isAgree:(BOOL)isAgree
                              reason:(NSString *JMSG_NULLABLE)reason
                             handler:(JMSGCompletionHandler)handler;

Set group members to ban

/*!
 * @abstract 群成员禁言设置
 *
 * @param isSilence 是否禁言, YES:是 NO: 否
 * @param username  带设置的用户的 username
 * @param username  带设置的用户的 appKey,若传入空则默认使用本应用appKey
 * @param handler   结果回调
 *
 * @discussion 注意: 目前 SDK 只支持群主设置群里某个用户禁言
 */
- (void)setGroupMemberSilence:(BOOL)isSilence
                     username:(NSString *JMSG_NONNULL)username
                       appKey:(NSString *JMSG_NULLABLE)appKey
                      handler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

Determine whether the user is banned

/*!
 * @abstract 判断用户在该群内是否被禁言
 *
 * @param username  待判断用户的用户名
 * @param appKey    待判断用户的appKey,若传入空则默认使用本应用appKey
 */
- (BOOL)isSilenceMemberWithUsername:(NSString *JMSG_NONNULL)username
                             appKey:(NSString *JMSG_NULLABLE)appKey;

Get group banned list

/*!
 * @abstract 禁言列表
 *
 * @return 禁言的成员列表. NSArray 里成员类型是 JMSGUser
 */
- (NSArray JMSG_GENERIC(__kindof JMSGUser *)*)groupSilenceMembers;

Get my group list

/*!
 * @abstract 获取我的群组列表
 *
 * @param handler 结果回调。正常返回时 resultObject 的类型是 NSArray,数组里的成员类型是JMSGGroup的gid
 *
 * @discussion 该接口总是向服务器端发起请求。
 */
+ (void)myGroupArray:(JMSGCompletionHandler)handler;
Example
// 获取我的群组列表(实际返回的群组的gid列表)
[JMSGGroup myGroupArray:^(id resultObject, NSError *error) {
    if (!error) {
        NSArray *groupGidArray = (NSArray *)resultObject;
        NSLog(@"获取我的群组成功!");
        NSLog(@"返回值是gid数组,开发者需要获取每个群完整信息的话,需要通过返回的gid再调用获取群信息接口");
    }
}];

Get a list of group members

/*!
 * @abstract 获取群组成员列表
 *
 * @return 成员列表. NSArray 里成员类型是 JMSGUser.
 *
 * @discussion 一般在群组详情界面调用此接口,展示群组的所有成员列表。
 * 本接口只是在本地请求成员列表,不会发起服务器端请求。
 */
- (NSArray JMSG_GENERIC(__kindof JMSGUser *)*)memberArray;

Add group members

/*!
 * @abstract 添加群组成员
 *
 * @param usernameArray 用户名数组。数组里的成员类型是 NSString
 * @param handler 结果回调。正常返回时 resultObject 为 nil.
 */
- (void)addMembersWithUsernameArray:(NSArray JMSG_GENERIC(__kindof NSString *) *)usernameArray
                  completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
// 添加群组成员
[group addMembersWithUsernameArray:[NSArray arrayWithObjects:@"username1",@"username2", nil] completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        NSLog(@"添加群成员成功!");
    }
}];

Delete group members

/*!
 * @abstract 删除群组成员
 *
 * @param usernameArray 用户名数据. 数组里的成员类型是 NSString
 * @param handler 结果回调。正常返回时 resultObject 为 nil.
 */
- (void)removeMembersWithUsernameArray:(NSArray JMSG_GENERIC(__kindof NSString *) *)usernameArray
                     completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
// 删除群组成员
[group removeMembersWithUsernameArray:[NSArray arrayWithObjects:@"username1",@"username2", nil] completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        NSLog(@"删除群成员成功!");
    }
}];

Exit the current group

/*!
 * @abstract 退出当前群组(当前用户)
 *
 * @param handler 结果回调。正常返回时 resultObject 为 nil。
 */
- (void)exit:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
// 退出当前群组(当前用户)
[deletedGroup exit:^(id resultObject, NSError *error) {
    if (error == nil) {
        NSLog(@"退出群组成功!");
    }
}];

Get the group’s display name

/*!
 * @abstract 获取群组的展示名
 *
 * @discussion 如果 group.name 为空, 则此接口会拼接群组前 5 个成员的展示名返回.
 */
- (NSString *)displayName;

Chatroom Management

Since 3.4.0

  • Main features: Messages in chat rooms have no push notifications and offline strorage, and there is no concept of permanent members. You can receive messages, start chatting after entering the chat room, and once you exit the chat room, you will no longer receive any messages, notifications, and reminders.

  • Send messages: The sending interface of chat room message is universal as single chat and group chat.

  • Receive messages: The reception of chat room messages is distinguished from the single chat and group chat. The reception of chat room messages will be notified to the upper layer via the onReceiveChatRoomConversation:messages:  method in the JMSGConversationDelegate class.

  • You will automatically get the last 50 messages after entering the chat room.

Pagination to get chat room

/*!
 * @abstract 获取当前用户已加入的聊天室列表
 *
 * @param handler 结果回调. 正常返回时 resultObject 类型是 NSArray<JMSGChatRoom>
 *
 * @discussion 该接口总是向服务器端发起请求.
 */
+ (void)getMyChatRoomListCompletionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

Get chat room already joined

/*!
 * @abstract 获取聊天室详情
 *
 * @param roomIds   待获取详情的聊天室 ID 数组
 * @param handler   结果回调. 正常返回时 resultObject 类型是 NSArray<JMSGChatRoom>
 *
 * @discussion 该接口总是向服务器端发起请求.
 */
+ (void)getChatRoomInfosWithRoomIds:(NSArray *JMSG_NONNULL)roomIds
                  completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

Get chat room details

/*!
 * @abstract 获取聊天室详情
 *
 * @param roomIds   待获取详情的聊天室 ID 数组
 * @param handler   结果回调. 正常返回时 resultObject 类型是 NSArray<JMSGChatRoom>
 *
 * @discussion 该接口总是向服务器端发起请求.
 */
+ (void)getChatRoomInfosWithRoomIds:(NSArray *JMSG_NONNULL)roomIds
                  completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

Join chat room

/*!
 * @abstract 加入聊天室
 *
 * @param roomId    聊天室 id
 * @param handler   结果回调. error = nil 表示加入成功,resultObject 为 JMSGConversation 类型
 *
 * @discussion 成功进入聊天室之后,会将聊天室中最近若干条聊天记录同步下来并以 onReceiveChatRoomConversation: 事件的形式通知到上层,进入聊天室会自动获取最近50条消息。
 */
+ (void)enterChatRoomWithRoomId:(NSString *JMSG_NONNULL)roomId
              completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

Leave chat room

/*!
 * @abstract 退出聊天室
 *
 * @param roomId    聊天室 id
 * @param handler   结果回调. error = nil 表示加入成功.
 *
 * @discussion 退出聊天室后获取不到任何消息和通知.
 */
+ (void)leaveChatRoomWithRoomId:(NSString *JMSG_NONNULL)roomId
              completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

Receive chat room messages

  • Send messages: The interface for sending messages is the same as single chats and group chats.

  • Receive messages: The proxy method of receiving chat room messages distinguishes from single chats and group chats, and defines new interfaces to Receiving Chat Room Messages.

Withdrawal of Message

Since 3.2.0

The call is initiated by the message withdrawing party and within a certain length of time, the SDK can withdraw a message in the session.

  • The sender can retrieve the post-withdrawal message in the callback with successful recall and update the withdrawn message in the UI.

  • If the message has already been received by the receiver, and then be withdrawn by the other party, the message receiver will receive a message revocation event. The upper layer can use this event to get the session and message after withdrawal, and then refresh the UI interface.

JMSGMessage

/*!
 * @abstract 消息撤回
 *
 * @param message 需要撤回的消息
 * @param handler 结果回调
 *
 * - resultObject 撤回后的消息
 * - error        错误信息
 *
 * @discussion 注意:SDK可撤回3分钟内的消息
 */
+ (void)retractMessage:(JMSGMessage *)message completionHandler:(JMSGCompletionHandler)handler;
Example
[JMSGMessage retractMessage:message completionHandler:^(id resultObject, NSError *error) {
    if(!error){
        // 撤回之后显示的消息,例如:xx撤回了一条消息
        JMSGMessage *resultMessage = (JMSGMessage *) resultObject;
    }
}];

JMSGConversation

/*!
 * @abstract 消息撤回
 *
 * @param message 需要撤回的消息
 * @param handler 结果回调
 *
 * - resultObject 撤回后的消息
 * - error        错误信息
 *
 * @discussion 注意:SDK可撤回3分钟内的消息
 */
- (void)retractMessage:(JMSGMessage *)message completionHandler:(JMSGCompletionHandler)handler;
Example
[conversation retractMessage:message completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        // 撤回之后显示的消息,例如:xx撤回了一条消息
        JMSGMessage *resultMessage = (JMSGMessage *)resultObject;
    }
}]

Message Read Receipt

Since 3.3.0

Set read receipt

The message sender can set whether to require the receiver to send a read receipt for a single message. The default behavior is NO.

Set whether the read receipt is required by setting the needReadReceipt property in the JMSGOptionalContent class.

/*!
 * @abstract 发送消息(附带可选功能,如:控制离线消息存储、自定义通知栏内容、消息已读回执等)
 *
 * @param message           通过消息创建类接口,创建好的消息对象
 * @param optionalContent   可选功能,具体请查看 JMSGOptionalContent 类
 *
 * @discussion 可选功能里可以设置离线消息存储、自定义通知栏内容、消息已读回执等,具体请查看 JMSGOptionalContent 类。
 *
 */
- (void)sendMessage:(JMSGMessage *)message optionalContent:(JMSGOptionalContent *)optionalContent;

Get the number of people who did not send read receipt

When a message that requires read receipt is successfully issued, the message sender can view the number of people who have not yet sent the read receipt.

/*!
 * @abstract 消息未读人数
 *
 * @discussion 只针对消息发送方有效
 *
 * 注意:只有发送方调用 [+sendMessage:optionalContent:] 方法设置 message 需要已读回执,此方法才有意义。
 */
- (NSInteger)getMessageUnreadCount;

Get details of read receipt

The sender can view the details of the current read receipt of this message. The details include information such as the list of users who have sent read receipts and who have not sent read receipts.

/*!
 * @abstract 已读未读用户列表
 *
 * @param handler 结果回调。回调参数:
 *
 * - unreadUsers  未读用户列表
 * - readsUsers   读用户列表
 * - error        不为nil表示出错
 *
 * @discussion 只针对消息发送方有效
 *
 * 注意:只有发送方调用 [+sendMessage:optionalContent:] 方法设置 message 需要已读回执,此方法才有意义。
 */
- (void)messageReadDetailHandler:(void(^)(NSArray *JMSG_NULLABLE readUsers, NSArray *JMSG_NULLABLE unreadUsers, NSError *JMSG_NULLABLE error))handler;

The message receiver marks the message as read

Message receivers could mark a message as read. After marking, the read status of this message is recorded locally. When this message requires a read receipt, the SDK will also send a notification event JMSGMessageReceiptStatusChangeEvent: to the message sender, notifying the other party that the number of read receipts for this message has changed.

Note: This read state will only be saved locally, and the read state will be reset to NO when the local data is cleared or the user changes the device to log in.

The upper layer listens for this event via methods.

/*!
 * @abstract 是否已读(只针对接收的消息)
 *
 * @discussion 该属性与实例方法 [-(void)setMessageHaveRead:] 是对应的。
 *
 * 注意:只有发送方调用 [+sendMessage:optionalContent:] 方法设置 message 需要已读回执,此属性才有意义。
 */
@property(nonatomic, assign, readonly) BOOL isHaveRead;

Get whether the message is read

For the message receiver, this interface can be used to obtain whether the message is read. By default, read status of all received messages is NO. After successfully calling the -(void)setMessageHaveRead: interface, read status of this message becomes YES.

Note: This read state will only be saved locally. When the local data is cleared, or the user replaces the device, the read state will be reset to NO.

/*!

* @abstract 是否已读(只针对接收的消息)

*

* @discussion 该属性与实例方法 [-(void)setMessageHaveRead:] 是对应的。

*

* 注意:只有发送方调用 [+sendMessage:optionalContent:] 方法设置 message 需要已读回执,此属性才有意义。

*/

@property(nonatomic, assign, readonly) BOOL isHaveRead;

Message Receipt Status Change Event

For the message which requires read receipt by message sender, after the receiver successfully sends the read receipt via the setMessageHaveRead: interface, the SDK will throw this event notification sender. By monitoring this event, the sender can know which message in which session the unreceived number of the message has changed.

Sender adds listener:

/*!
 * @abstract 消息回执状态变更事件
 *
 * @param receiptEvent 下发的通知事件,事件类型请查看 JMSGMessageReceiptStatusChangeEvent 类
 *
 * @discussion 上层可以通过 receiptEvent 获取相应信息
 *
 * @since 3.3.0
 */
@optional
- (void)onReceiveMessageReceiptStatusChangeEvent:(JMSGMessageReceiptStatusChangeEvent *)receiptEvent;
//发送方
1、设置消息需要回执功能
JMSGTextContent *textContent = [[JMSGTextContent alloc] initWithText:text];
JMSGOptionalContent *optionalCon = [[JMSGOptionalContent alloc] init];
optionalCon.needReadReceipt = YES;    
[conversation sendMessage:message optionalContent:optionalCon];

2、获取未回执人数
NSInteger count =  [self.message getMessageUnreadCount];
NSLog(@"消息未读人数:%ld",count);

3、获取消息回执详情
[self.message messageReadDetailHandler:^(NSArray * _Nullable readUsers, NSArray * _Nullable unreadUsers, NSError * _Nullable error) {
  NSLog(@"\n 已读列表:%@,\n 未读列表:%@",readUsers,unreadUsers);
 }];

 4、监听已读回执变更事件
 - (void)onReceiveMessageReceiptStatusChangeEvent:(JMSGMessageReceiptStatusChangeEvent *)receiptEvent{
    NSArray *messages =receiptEvent.messages;
    JMSGConversation *conversation = receiptEvent.conversation;
}

//接收方
1、设置消息已读
[self.message setMessageHaveRead:^(id resultObject, NSError *error) {
    NSLog(@"发送已读回执:%@",error?@"失败":@"成功");
 }];

2、查看消息已读状态
BOOL status = self.message.isHaveRead;
NSLog(@"消息是否已读:%@", status?@"是":@"否");

Message Transparent Transmission Command

Messages sent through transparent transmission will not be saved offline by the background and only be pushed to the other party on the premise that the other user is online. After the SDK receives the command, it will not be saved locally, neither send a notification bar notification. Overall response will be very quick.

Developers can use message transparent transmission to expand the auxiliary functions in some online scenarios, such as: input status prompts.

Command classification of transparent transmission

/*!
 * 发送消息透传的的类型
 */
typedef NS_ENUM(NSInteger,JMSGTransMessageType) {
  /// 单聊透传消息
  kJMSGTransMessageTypeSingle        = 1,
  /// 群里透传消息
  kJMSGTransMessageTypeGroup        = 2,
  /// 设备间透传消息
  kJMSGTransMessageTypeCrossDevice  = 3,
};

Transparent transmission of messages between devices

Supports transparent transmission of messages between different devices under the same user

/*!
 * @abstract 发送透传消息给自己在线的其他设备
 *
 * @param message   发送的内容
 * @param platform  设备类型
 * @param handler   回调
 *
 * @discussion 注意:
 *
 *  1. 消息透传功能,消息不会进入到后台的离线存储中去,仅当对方用户当前在线时才会成功送达,SDK 不会将此类消息内容存储;
 *
 *  2. 透传命令到达是,接收方通过 [JMSGEventDelegate onReceiveMessageTransparentEvent:] 方法监听。
 *
 * @since 3.5.0
 */
+ (void)sendCrossDeviceTransMessage:(NSString *)message
                           platform:(JMSGPlatformType)platform
                            handler:(JMSGCompletionHandler)handler;

Transparent transmission of messages between sessions

/*!
 * @abstract 消息透传
 *
 * @param transparentText 用户自定义透传内容,仅限 NSString 类型
 * @param handler 回调,error=nil 表示成功
 *
 * @discussion 注意:
 *
 *  1. 消息透传功能,消息不会进入到后台的离线存储中去,仅当对方用户当前在线时才会成功送达,可以快速响应,方便开发者拓展自定义行为;
 *
 *  2. 可用来快速实现一些在线场景下的辅助功能 :输入状态提示、位置信息提示、开发者自定义等。
 *
 */
- (void)sendTransparentMessage:(NSString *JMSG_NONNULL)transparentText
             completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;

Listen to transparent messages

/*!
 * @abstract 消息透传事件
 *
 * @param transparentEvent 下发的通知事件,事件类型请查看 JMSGMessageTransparentEvent 类
 *
 * @discussion 上层可以通过 transparentEvent 获取相应信息,如自定义的透传信息、会话
 *
 * @since 3.3.0
 */
@optional
- (void)onReceiveMessageTransparentEvent:(JMSGMessageTransparentEvent *)transparentEvent;

Group @ Function

The sender can send a message with @list. After the receiver receives the message with @list, if @list contains yourself, there will be a corresponding prompt in the notification bar prompt popuped by sdk, such as "xxx in the group @ you".

JMSGMessage

Create @group member message

/*!
 * @abstract 创建@人的群聊消息
 *
 * @param content 消息内容对象
 * @param groupId 群聊ID
 * @param at_list @对象的数组
 *
 * @discussion 不关心会话时的直接创建聊天消息的接口。一般建议使用 JMSGConversation -> createMessageWithContent:
 */
+ (JMSGMessage *)createGroupMessageWithContent:(JMSGAbstractContent *)content
                                       groupId:(NSString *)groupId
                                       at_list:(NSArray<__kindof JMSGUser *> *)at_list;

Determine if the message has @ yourself

/*!
 * @abstract 是否是@自己的消息(只针对群消息,单聊消息无@功能)
 */
- (BOOL)isAtMe;

Get the list of @group members

/*!
 * @abstract 获取消息体中所有@对象(只针对群消息,单聊消息无@功能)
 *
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 类型为 NSArray,数组里成员的类型为 JMSGUser
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 从服务器获取,返回消息的所有@对象。
 */
- (void)getAt_List:(JMSGCompletionHandler)handler;

JMSGConversation

Send @person's message

/*!
 * @abstract 发送@人消息(已经创建好对象的)
 *
 * @param message 通过消息创建类接口,创建好的消息对象
 * @param at_list @对象的数组
 *
 * @discussion 发送消息的多个接口,都未在方法上直接提供回调。你应通过 JMSGMessageDelegate中的onReceiveMessage: error:方法来注册消息发送结果。
 */
- (void)sendMessage:(JMSGMessage *)message at_list:(NSArray<__kindof JMSGUser *> *)userList;
Example
// 创建@群成员的消息
JMSGTextContent *textContent1 = [[JMSGTextContent alloc] initWithText:@"at他人的消息"];
JMSGMessage *atMessage = [JMSGMessage createGroupMessageWithContent:textContent1 groupId:@"gid" at_list:[NSArray arrayWithObjects:user1,user2, nil]];

// 消息中@的群成员列表
[atMessage getAt_List:^(id resultObject, NSError *error) {
     NSArray *atList = (NSArray *)resultObject;
 }];

// 发送@人的消息
JMSGTextContent *textContent2 = [[JMSGTextContent alloc] initWithText:@"创建好的消息"];
JMSGMessage *message = [JMSGMessage createGroupMessageWithContent:textContent2 groupId:@"gid"];
[conversation sendMessage: message atMessage at_list:[NSArray arrayWithObjects:user1,user2, nil]]

Send @ everyone's message

/*!
 * @abstract 发送@所有人消息(已经创建好对象的)
 *
 * @param message 通过消息创建类接口,创建好的消息对象
 *
 * @discussion 发送消息的多个接口,都未在方法上直接提供回调。你应通过 JMSGMessageDelegate中的onReceiveMessage: error:方法来注册消息发送结果
 */
- (void)sendAtAllMessage:(JMSGMessage *)message;

Group Message Block

After the group is set to be blocked, the group's message will not be received, but the change of group member can still be received normally.

JMSGGroup

Determine if the group is blocked

/*!
 * @abstract 该群是否已被设置为消息屏蔽
 *
 * @discussion YES:是 , NO: 否
 */
@property(nonatomic, assign, readonly) BOOL isShieldMessage

Set a group message block

/*!
 * @abstract 设置群组消息屏蔽
 *
 * @param isShield 是否群消息屏蔽 YES:是 NO: 否
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 相应对象
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 针对单个群组设置群消息屏蔽
 */
- (void)setIsShield:(BOOL)isShield handler:(JMSGCompletionHandler)handler;

Get the current user's group block list

/*!
 * @abstract 获取所有设置群消息屏蔽的群组
 *
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 类型为 NSArray,数组里成员的类型为 JMSGGroup
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 从服务器获取,返回所有设置群消息屏蔽的群组。
 */
+ (void)shieldList:(JMSGCompletionHandler)handler;

Notification Bar Management

JMSGConversation

When sending a message, SDK can control the storage of offline messages, the contents of custom notification bars, etc. Specific functions can be found in the instructions of JMSGOptionalContent class.

/*!
 * @abstract 发送消息(附带可选功能,如:控制离线消息存储、自定义通知栏内容等)
 *
 * @param message           通过消息创建类接口,创建好的消息对象
 * @param optionalContent   可选功能,具体请查看 JMSGOptionalContent 类
 *
 * @discussion 可选功能里可以设置离线消息存储、自定义通知栏内容等,具体请查看 JMSGOptionalContent 类。
 *
 */
- (void)sendMessage:(JMSGMessage *)message optionalContent:(JMSGOptionalContent *)optionalContent;
/*!
 * @abstract 发送消息(附带可选功能,如:控制离线消息存储、自定义通知栏内容等)
 *
 * @param message           通过消息创建类接口,创建好的消息对象
 * @param optionalContent   可选功能,具体请查看 JMSGOptionalContent 类
 *
 * @discussion 可选功能里可以设置离线消息存储、自定义通知栏内容等,具体请查看 JMSGOptionalContent 类。
 *
 */
+ (void)sendMessage:(JMSGMessage *)message optionalContent:(JMSGOptionalContent *)optionalContent;

Buddy Management

Adding, deleting, accepting and rejecting friends, etc. will be issued by SDK as a notification event. The upper layer listens for such events through the methods in the  onReceiveNotificationEvent: class. Use the example and make corresponding processing.

JMSGFriendManager

Get friend list

/*!
 * @abstract 获取好友列表
 *
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 类型为 NSArray,数组里成员的类型为 JMSGUser
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 从服务器获取,异步返回结果,返回用户的好友列表。
 * 建议开发者在 SDK 完全启动之后,再调用此接口获取数据
 */
+ (void)getFriendList:(JMSGCompletionHandler)handler;
Example
// get friend list
[JMSGFriendManager getFriendList:^(id resultObject, NSError *error) {
    if(!error){
        NSArray *friendList = (NSArray *)resultObject;
        NSLog(@"获取好友列表:%@",friendList)
    }
}];

Send a friend request

/*!
 * @abstract 发送添加好友请求
 *
 * @param username 对方用户名
 * @param userAppKey 对方所在应用appkey,不传则默认是本应用
 * @param reason 添加好友时的备注,可不填
 *
 * @param handler 结果回调。回调参数
 *
 * - resultObject 相应的返回对象
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 在对方未做回应的前提下,允许重复发送添加好友的请求。
 */
+ (void)sendInvitationRequestWithUsername:(NSString *)username
                                   appKey:(NSString *)userAppKey
                                   reason:(NSString *)reason
                        completionHandler:(JMSGCompletionHandler)handler;
Example
[JMSGFriendManager sendInvitationRequestWithUsername:username appKey:appkey reason:nil completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        NSLog(@"发送邀请成功");
    } else {
        NSLog(@"发送邀请失败");
    }
}];

Accept friend invitations

/*!
 * @abstract 接受好友邀请
 *
 * @param username 对方用户名
 * @param userAppKey 对方所在应用appkey,不传则默认是本应用
 *
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 相应的返回对象
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 */
+ (void)acceptInvitationResponseWithUsername:(NSString *)username
                                      appKey:(NSString *)userAppKey
                           completionHandler:(JMSGCompletionHandler)handler;
Example
// 接受好友邀请
[JMSGFriendManager acceptInvitationWithUsername:username appKey:appKey completionHandler:^(id resultObject, NSError *error) {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (!error) {
            NSLog(@"接受成功");
        }
        else{
            NSLog(@"接受失败");
        }
    });
}];

Reject friend invitation

/*!
 * @abstract 拒绝好友邀请
 *
 * @param username 对方用户名
 * @param userAppKey 对方所在应用appkey,不传则默认是本应用
 * @param reason 拒绝理由,可不传
 *
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 相应的返回对象
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 */
+ (void)rejectInvitationWithUsername:(NSString *)username
                              appKey:(NSString *)userAppKey
                              reason:(NSString *)reason
                   completionHandler:(JMSGCompletionHandler)handler;
Example
// 拒绝好友邀请
[JMSGFriendManager rejectInvitationWithUsername:username appKey:appKey reason:nil completionHandler:^(id resultObject, NSError *error) {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (!error) {
            NSLog(@"拒绝成功");
        }
        else{
            NSLog(@"拒绝失败");
        }
    });
}];

Delete friend

/*!
 * @abstract 删除好友
 *
 * @param username 好友username
 * @param userAppKey 好友所在应用appkey,不传则默认是本应用
 *
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 相应对象
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion
 */
+ (void)removeFriendWithUsername:(NSString *)username
                          appKey:(NSString *)userAppKey
               completionHandler:(JMSGCompletionHandler)handler;
Example
// 比如将你好友列表里的 user 移除
[JMSGFriendManager removeFriendWithUsername:user.username appKey:user.appkey completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
       NSLog(@"删除好友成功");
    }
    else{
       NSLog(@"删除好友失败");
    }
}];

Blacklist

After adding users to the blacklist, they will not receive any messages from the other party. For example: A user adds the B user to the blacklist, then the message sent by the B user cannot be received by the A user. The message sent by A user can still be seen by the B user.

Get blacklist

/*!
 * @abstract 黑名单列表
 *
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 类型为 NSArray,数组里成员的类型为 JMSGUser
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 从服务器获取,返回用户的黑名单列表。
 */
+ (void)blackList:(JMSGCompletionHandler)handler;

Example
//获取黑名单列表
[JMessage blackList:^(id resultObject, NSError *error) {
    if (!error) {
        NSLog(@"\n 黑名单列表: %@ \n",resultObject);
    }
}];

Add blacklist

/*!
 * @abstract 添加黑名单
 * @param usernameArray 作用对象的username数组
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 相应对象
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 可以一次添加多个用户
 */
+ (void)addUsersToBlacklist:(NSArray JMSG_GENERIC(__kindof NSString *)*)usernameArray
          completionHandler:(JMSGCompletionHandler)handler;

Example
//添加黑名单
[JMSGUser addUsersToBlacklist:[NSArray arrayWithObjects:@"username1",@"username2", nil] completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        NSLog(@"\n 添加黑名单成功:%@ \n ",resultObject);
    }
}];

Remove blacklist

/*!
 * @abstract 删除黑名单
 * @param usernameArray 作用对象的username数组
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 相应对象
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 可以一次删除多个黑名单用户
 */
+ (void)delUsersFromBlacklist:(NSArray JMSG_GENERIC(__kindof NSString *)*)usernameArray
            completionHandler:(JMSGCompletionHandler)handler;

Example
//删除黑名单
[JMSGUser delUsersFromBlacklist:[NSArray arrayWithObjects:@"username1",@"username2", nil] completionHandler:^(id resultObject, NSError *error) {
        if (!error) {
            NSLog(@"\n 添加黑名单成功:%@ \n ",resultObject);
        }
    }];

Do-Not-Disturb

Users/groups can be added to the Do-Not-Disturb (DND) list. When notifications are received from Do-Not-Disturb Users/Groups, there will be no notification bar notifications, but message events will be delivered as usual. After setting global Do-Not-Disturb, all messages received will have no notification bar notification and the effect is similar.

Do-Not-Disturb List

/*!
 * @abstract 用户免打扰列表
 *
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 类型为 NSArray,数组里成员的类型为 JMSGUser、JMSGGroup
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 从服务器获取,返回用户的免打扰列表。
 */
+ (void)noDisturbList:(JMSGCompletionHandler)handler;
Example
//获取当前用户免打扰列
[JMessage noDisturbList:^(id resultObject, NSError *error) {
     if (!error) {
         NSLog(@"\n 免打扰列表: \n %@",resultObject);
     }
 }];

Global Do-Not-Disturb Settings

/*!
 * @abstract 判断是否设置全局免打扰
 *
 * @return YES/NO
 */
+ (BOOL)isSetGlobalNoDisturb;

/*!
 * @abstract 设置是否全局免打扰
 *
 * @param isNoDisturb 是否全局免打扰 YES:是 NO: 否
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 相应返回对象
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 此函数为设置全局的消息免打扰
 */
+ (void)setIsGlobalNoDisturb:(BOOL)isNoDisturb handler:(JMSGCompletionHandler)handler;

Example
 //获取是否设置全局免打扰
 BOOL isNoDisturb = [JMessage isSetGlobalNoDisturb];
 //设置全局免打扰(开启:YES,关闭:NO)
 [JMessage setIsGlobalNoDisturb:!isNoDisturb handler:^(id resultObject, NSError *error) {
     if (!error) {
         NSLog(@"\n 全局免打扰设置成功:\n%@",resultObject);
     }
 }];

User Do-Not-Disturb Settings

/*!
 * @abstract 该用户是否已被设置为免打扰
 *
 * @discussion YES:是 , NO: 否
 */
@property(nonatomic, assign, readonly) BOOL isNoDisturb;

/*!
 * @abstract 设置用户免打扰(支持跨应用设置)
 *
 * @param isNoDisturb 是否全局免打扰 YES:是 NO: 否
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 相应对象
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 针对单个用户设置免打扰
 * 这个接口支持跨应用设置免打扰
 */
- (void)setIsNoDisturb:(BOOL)isNoDisturb handler:(JMSGCompletionHandler)handler;

Example
//获取 user 对象是否设置了免打扰
BOOL isAlreadSet = user.isNoDisturb;

//开启或关闭 user 免打扰设置
[user setIsNoDisturb:!isAlreadSet handler:^(id resultObject, NSError *error) {
    if (!error) {
        NSLog(@"\n消息免打扰设置成功:\n%@\n",resultObject);
    }
}];
注:如果user对象已经开启(关闭)免打扰,再对user设置开启(关闭)免打扰,会返回失败,所以在设置设置免打扰时,先获取user对象的isNoDisturb值,再进行设置

Group Do-Not-Disturb Settings

/*!
 * @abstract 该群是否已被设置为免打扰
 *
 * @discussion YES:是 , NO: 否
 */
@property(nonatomic, assign, readonly) BOOL isNoDisturb;

/*!
 * @abstract 设置群组消息免打扰(支持跨应用设置)
 *
 * @param isNoDisturb 是否免打扰 YES:是 NO: 否
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 相应对象
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 针对单个群组设置免打扰
 * 这个接口支持跨应用设置免打扰
 */
- (void)setIsNoDisturb:(BOOL)isNoDisturb handler:(JMSGCompletionHandler)handler;

Example
使用方法参考“用户免打扰”例子

Event Handling

Notification event type

typedef NS_ENUM(NSInteger, JMSGEventNotificationType) {

    /// 用户登录状态变更事件
    /// 事件类型: 登录被踢
    kJMSGEventNotificationLoginKicked = 1,
    /// 事件类型: 非客户端修改密码强制登出事件
    kJMSGEventNotificationServerAlterPassword = 2,
    /// 事件类型:用户登录状态异常事件(需要重新登录)
    kJMSGEventNotificationUserLoginStatusUnexpected = 70,
    /// 事件类型:当前登录用户信息变更通知事件(非客户端修改)
     kJMSGEventNotificationCurrentUserInfoChange = 40,

    /// 好友相关事件
    /// 事件类型: 收到好友邀请
    kJMSGEventNotificationReceiveFriendInvitation   = 51,
    /// 事件类型: 对方接受了你的好友邀请
    kJMSGEventNotificationAcceptedFriendInvitation  = 52,
    /// 事件类型: 对方拒绝了你的好友邀请
    kJMSGEventNotificationDeclinedFriendInvitation  = 53,
    /// 事件类型: 对方将你从好友中删除
    kJMSGEventNotificationDeletedFriend             = 6,
     /// 事件类型:非客户端修改好友关系收到好友更新事件
     kJMSGEventNotificationReceiveServerFriendUpdate = 7,

     /// 事件类型: 消息撤回
     kJMSGEventNotificationMessageRetract = 55,
     /// 事件类型: 消息透传
     kJMSGEventNotificationMessageTransparent = 58,
     /// 事件类型: 消息回执变更
     kJMSGEventNotificationMessageReceiptStatusChange = 68,

    /// 消息事件
    /// 事件类型: 群组被创建
    kJMSGEventNotificationCreateGroup = 8,
    /// 事件类型: 退出群组
    kJMSGEventNotificationExitGroup = 9,
    /// 事件类型: 群组添加新成员
    kJMSGEventNotificationAddGroupMembers = 10,
    /// 事件类型: 群组成员被踢出
    kJMSGEventNotificationRemoveGroupMembers = 11,
    /// 事件类型: 群信息更新
    kJMSGEventNotificationUpdateGroupInfo = 12,
};

JMSGNotificationEvent

/*!
 * @abstract 事件类型
 * @discussion 参考事件类型的定义 JMSGEventNotificationType
 */
@property(nonatomic, assign, readonly) JMSGEventNotificationType eventType;

/*!
 * @abstract 事件的描述信息
 * @discussion 下发事件的文字描述,可能为空
 */
@property(nonatomic, strong, readonly) NSString *eventDescription;
Example

Example of listening for this event

JMSGFriendNotificationEvent

/*!
 * @abstract 获取事件发生的理由
 *
 * @discussion 该字段由对方发起请求时所填,对方如果未填则将返回默认字符串
 */
- (NSString *JMSG_NULLABLE)getReason;
 /*!
  * @abstract 事件发送者的username
  *
  * @discussion 该字段由对方发起请求时所填,对方如果未填则将返回默认字符串
  * 如果设置了noteName、nickname,返回优先级为noteName、nickname;否则返回username
  */
- (NSString *JMSG_NULLABLE)getFromUsername;

/*!
 * @abstract 获取事件发送者user
 */
- (JMSGUser *JMSG_NULLABLE)getFromUser;
Example

Example of listening for this event

JMSGNotificationEvent

/*!
 * @abstract 消息撤回事件
 *
 * @discussion 上层通过 JMSGEventDelegate 类中的 -(void)onReceiveNotificationEvent: 代理方法监听此事件,详见官方文档.
 */
@interface JMSGMessageRetractEvent : JMSGNotificationEvent

/**
 * @abstract 消息撤回所属会话
 */
@property(nonatomic, strong, readonly) JMSGConversation *conversation;

/**
 * @abstract 撤回之后的消息
 */
@property(nonatomic, strong, readonly) JMSGMessage *retractMessage;

JMSGMessageTransparentEvent

/*!
 * @abstract 消息透传事件
 */
@interface JMSGMessageTransparentEvent : JMSGNotificationEvent
/*!
 * @abstract 消息所属会话
 */
@property(nonatomic, strong, readonly) JMSGConversation *conversation;
/*!
 * @abstract 用户自定义透传内容
 */
@property(nonatomic, strong, readonly) NSString *transparentText;
@end
Example

The message transparent transmission event listens for this event via the onReceiveMessageTransparentEvent: method.

JMSGMessageReceiptStatusChangeEvent

/*!
 * @abstract 消息已读回执状态变更事件
 */
@interface JMSGMessageReceiptStatusChangeEvent : JMSGNotificationEvent
/**
 * @abstract 消息所属会话
 */
@property(nonatomic, strong, readonly) JMSGConversation *conversation;
/**
 * @abstract 已读回执变更的消息列表
 */
@property(nonatomic, strong, readonly) NSArray <__kindof JMSGMessage *>*messages;
@end
Example

Message receipt change event. The upper layer listens for this event via the onReceiveMessageReceiptStatusChangeEvent: method.

JMSGApplyJoinGroupEvent

@interface JMSGApplyJoinGroupEvent : JMSGNotificationEvent
/// 事件的 id
@property(nonatomic, strong, readonly) NSString *eventID;
/// 群 gid
@property(nonatomic, strong, readonly) NSString *groupID;
/// 是否是用户主动申请入群,YES:主动申请加入,NO:被邀请加入
@property(nonatomic, assign, readonly) BOOL isInitiativeApply;
/// 发起申请的 user,如果 isInitiativeApply = YES,则与 sendApplyUser 和 joinGroupUser 是相同的
@property(nonatomic, strong, readonly) JMSGUser *sendApplyUser;
/// 被邀请入群的 user,如果 isInitiativeApply = YES,则与 sendApplyUser 和 joinGroupUser 是相同的
@property(nonatomic, strong, readonly) JMSGUser *joinGroupUser;
/// 原因
@property(nonatomic, strong, readonly) NSString *reason;
@end
Example

Group application event. The upper layer listens for this event via the onReceiveApplyJoinGroupApprovalEvent: method.

JMSGGroupAdminRejectApplicationEvent

@interface JMSGGroupAdminRejectApplicationEvent : JMSGNotificationEvent
/// 群 gid
@property(nonatomic, strong, readonly) NSString *groupID;
/// 拒绝原因
@property(nonatomic, strong, readonly) NSString *rejectReason;
/// 操作的管理员
@property(nonatomic, strong, readonly) JMSGUser *groupManager;
@end
Example

Administrator rejecting the applcation event . The upper layer listens for this event via the onReceiveGroupAdminRejectApplicationEvent: method.

JMSGEventContent

/*!
 @abstract 展示此事件的文本描述

 @discussion SDK 根据事件类型,拼接成完整的事件描述信息。
 */
- (NSString * JMSG_NONNULL)showEventNotification;
/*!
 * @abstract 获取事件发起者的用户名
 * @return 正常返回事件发起者的用户名,如果是系统事件则返回“系统消息”
 *
 * @discussion 如果设置了nickname,则返回nickname,否则返回username
 * 可以用于定制 event message,拼接成完整的事件描述信息。
 */
- (NSString *JMSG_NULLABLE)getEventFromUsername;

/*!
 * @abstract 获取事件作用对象用户名列表
 * @return 返回类型为 NSArray,数组成员为事件作用对象的用户名
 *
 * @discussion 如果设置了nickname,则返回nickname,否则返回username
 * 可以用于定制 event message,拼接成完整的事件描述信息。
 */
- (NSArray *JMSG_NULLABLE)getEventToUsernameList;
Example
// 事件的文本描述
if (message.contentType == kJMSGContentTypeEventNotification) {
    NSString *showText = [((JMSGEventContent *)message.content) showEventNotification];
    //比如,在群group中,用户A邀请用户B加入了群,showText 如下:
    //showText = "A邀请B加入了群组"
}

//根据事件类型,定制相应描述(以事件类型: 添加新成员为例子)
JMSGEventContent *eventContent = (JMSGEventContent*)message.content;
NSString *fromUsername = [eventContent getEventFromUsername];
NSArray *toUsernameList = [eventContent getEventToUsernameList];
if(eventContent.eventType == kJMSGEventNotificationAddGroupMembers) {
    NSString *showText = [NSString stringWithFormat:@"%@邀请了%@加入了群聊",fromUsername,[toUsernameList componentsJoinedByString:@","]];
}

Notification Listener

JMessage SDK uses the mechanism of Delegate to send notifications to the App, rather than using the common notifications method of iOS platform. Approach of Delegate is more direct and easy to use.

You can call the following methods to listen for event notifications in any of the App's classes.

[JMessage addDelegate:self withConversation:nil]

To make the above line valid, you need to declare the implementation of JMessageDelegate protocol in the header file of the current class. The following example is listened in AppDelegate.

@interface AppDelegate : UIResponder <UIApplicationDelegate,JMessageDelegate>

In addition to listening the above two actions, the other action is the method that implements the event you want to listen to. For example, listening database upgrades:

- (void)onDBMigrateStart {
  NSLog(@"onDBmigrateStart in appdelegate");
  _isDBMigrating = YES;
}

Since the JMessage SDK detects database upgrades during setup, it sends notifications when needed. It is therefore recommended to add listeners before calling setupJMessage in AppDelegate.

Another notification suggested to be listened in AppDelegate is that the current user is kicked out.

- (void)onLoginUserKicked;(此方法已过期,建议使用下面的新方法)

// 通过event.eventType 判断事件类型,如:被踢事件、好友相关事件等
- (void)onReceiveNotificationEvent:(JMSGNotificationEvent *)event;

Example Code
// 通知事件监听
- (void)onReceiveNotificationEvent:(JMSGNotificationEvent *)event{
    switch (event.eventType) {
         case kJMSGEventNotificationCurrentUserInfoChange:
              NSLog(@"Current user info change Event ");
              break;
        case kJMSGEventNotificationReceiveFriendInvitation:
            NSLog(@"Receive Friend Invitation Event ");
            break;
        case kJMSGEventNotificationAcceptedFriendInvitation:
            NSLog(@"Accepted Friend Invitation Event ");
            break;
        case kJMSGEventNotificationDeclinedFriendInvitation:
            NSLog(@"Declined Friend Invitation Event ");
            break;
        case kJMSGEventNotificationDeletedFriend:
            NSLog(@"Deleted Friend Event ");
            break;
        case kJMSGEventNotificationReceiveServerFriendUpdate:
            NSLog(@"Receive Server Friend Update Event ");
            break;
        case kJMSGEventNotificationLoginKicked:
            NSLog(@"Login Kicked Event ");
            break;
        case kJMSGEventNotificationServerAlterPassword:
            NSLog(@"Server Alter Password Event ");
            break;
        case kJMSGEventNotificationUserLoginStatusUnexpected:
            NSLog(@"User login status unexpected Event ");
            break;
        default:
            NSLog(@"Other Notification Event ");
            break;
    }
}

Result Callback

Many interfaces provided by JMessage SDK are returned asynchronously. Callbacks of them are all blocks of type JMSGCompletionHandler and defined as

typedef void (^JMSGCompletionHandler)(id resultObject, NSError *error);

JMSGCompletionHandler has 2 parameters:

  • id resultObject - returned result object

  • NSError *error - returned error

If error is not nil, the call goes wrong. error -> code defines error codes, and error -> description has a detailed description of the error. You can also find further error description information from the documentation.

If error is nil, the call is successful and resultObject is the returned result object. The actual type of each interface resultObject is different and is specified in the definition document for each interface. In actual use, the resultObject should be transformed into the normal object of the interface.

Similar to JMSGCompletionHandler, there is another block called JMSGAsyncDataHandler that used to return media file data.

Proxy Method

JMSGConversationDelegate

Change notification of session information

/*!
 * @abstract 会话信息变更通知
 *
 * @param conversation 变更后的会话对象
 *
 * @discussion 当前有二个属性: 会话标题(title), 会话图标
 *
 * 收到此通知后, 建议处理: 如果 App 当前在会话列表页,刷新整个列表;如果在聊天界面,刷新聊天标题。
 */
@optional
- (void)onConversationChanged:(JMSGConversation *)conversation;

/*!
 * @abstract 当前剩余的全局未读数
 *
 * @param newCount 变更后的数量
 */
@optional
- (void)onUnreadChanged:(NSUInteger)newCount;

Proxy method of message synchronization

/*!
 * @abstract 同步离线消息、离线事件通知
 *
 * @param conversation    同步离线消息的会话
 * @param offlineMessages 离线消息、离线事件数组
 *
 * @discussion 注意:
 *
 * SDK 会将消息下发分为在线下发和离线下发两种情况,
 * 其中用户在离线状态(包括用户登出或者网络断开)期间所收到的消息我们称之为离线消息.
 *
 * 当用户上线收到这部分离线消息后,这里的处理与之前版本不同的是:
 *
 * 3.1.0 版本之前: SDK 会和在线时收到的消息一样,每收到一条消息都会上抛一个在线消息 JMSGMessage 来通知上层.
 *
 * 3.1.0 版本之后: SDK 会以会话为单位,不管该会话有多少离线消息,SDK同步完成后每个会话只上抛一次.
 *
 * 3.2.1 版本之后: SDK 会以会话为单位,不管该会话有多少离线事件,SDK同步完成后每个会话只上抛一次
 *
 * 注意:一个会话最多触发两次这个代理,即:离线消息和离线事件各一次,这样会大大减轻上层在收到消息刷新 UI 的压力.
 *
 * 上层通过此代理方法监听离线消息同步的会话,详见官方文档.
 *
 */
@optional
- (void)onSyncOfflineMessageConversation:(JMSGConversation *)conversation
                         offlineMessages:(NSArray JMSG_GENERIC(__kindof JMSGMessage *)*)offlineMessages;
/*!
 * @abstract 同步漫游消息通知
 *
 * @param conversation 同步漫游消息的会话
 *
 * @discussion 注意:
 *
 * 当 SDK 触发此函数时,说明该会话有同步下漫游消息,并且已经存储到本地数据库中,
 * 上层可通过 JMSGConversation 类中的获取message的方法刷新UI.
 *
 * @since 3.1.0
 */
@optional
- (void)onSyncRoamingMessageConversation:(JMSGConversation *)conversation;

Proxy method of chat room receiving messages

/*!
 * @abstract 接收聊天室消息
 *
 * @param conversation 聊天室会话
 * @param messages      接收到的消息数组,元素是 JMSGMessage
 *
 * @discussion 注意:
 *
 * 接收聊天室的消息与单聊、群聊消息不同,聊天室消息都是通过这个代理方法来接收的。
 *
 * @since 3.4.0
 */
- (void)onReceiveChatRoomConversation:(JMSGConversation *)conversation
                             messages:(NSArray JMSG_GENERIC(__kindof JMSGMessage *)*)messages;

JMSGMessageDelegate

/*!
 * @abstract 发送消息结果返回回调
 *
 * @param message 原发出的消息对象
 * @param error 不为nil表示发送消息出错
 *
 * @discussion 应检查 error 是否为空来判断是否出错. 如果未出错, 则成功.
 */
@optional
- (void)onSendMessageResponse:(JMSGMessage *)message
                        error:(NSError *)error;
/*!
 * @abstract 接收消息(服务器端下发的)回调
 *
 * @param message 接收到下发的消息
 * @param error 不为 nil 表示接收消息出错
 *
 * @discussion 应检查 error 是否为空来判断有没有出错. 如果未出错, 则成功.
 * 留意的是, 这里的 error 不包含媒体消息下载文件错误. 这类错误有单独的回调 onReceiveMessageDownloadFailed:
 *
 * 收到的消息里, 也包含服务器端下发的各类事件, 比如有人被加入了群聊. 这类事件处理为特殊的 JMSGMessage 类型.
 *
 * 事件类的消息, 基于 JMSGMessage 类里的 contentType 属性来做判断,
 * contentType = kJMSGContentTypeEventNotification.
 */
@optional
- (void)onReceiveMessage:(JMSGMessage *)message
                   error:(NSError *)error;
/*!
 * @abstract 接收消息媒体文件下载失败的回调
 *
 * @param message 下载出错的消息
 *
 * @discussion 因为对于接收消息, 最主要需要特别做处理的就是媒体文件下载, 所以单列出来. 一定要处理.
 *
 * 通过的作法是: 如果是图片, 则 App 展示一张特别的表明未下载成功的图, 用户点击再次发起下载. 如果是语音,
 * 则不必特别处理, 还是原来的图标展示. 用户点击时, SDK 发现语音文件在本地没有, 会再次发起下载.
 */
@optional
- (void)onReceiveMessageDownloadFailed:(JMSGMessage *)message;

JMSGGroupDelegate

/*!
 * @abstract 群组信息 (GroupInfo) 信息通知
 *
 * @param group 变更后的群组对象
 *
 * @discussion 如果想要获取通知, 需要先注册回调. 具体请参考 JMessageDelegate 里的说明.
 */
@optional
- (void)onGroupInfoChanged:(JMSGGroup *)group;

JMSGUserDelegate (Obsolete. Recommend to use JMSGEventDelegate)

/*!
 * @abstract 当前登录用户被踢下线通知(方法已过期,建议使用新方法)
 *
 * @discussion 一般可能是, 该用户在其他设备上登录, 把当前设备的登录踢出登录.
 *
 * SDK 收到服务器端下发事件后, 会内部退出登录.
 * App 也应该退出登录. 否则所有的 SDK API 调用将失败, 因为 SDK 已经退出登录了.
 *
 * 注意: 这是旧版本的监听方法,建议不要使用,已经过期,
 * 使用 JMSGEventDelegate 类中的 onReceiveNotificationEvent 新的监听方法.
 */
@optional
- (void)onLoginUserKicked;

JMSGEventDelegate

/*!
 * @abstract 监听通知事件
 *
 * @param event 下发的通知事件
 *
 * @discussion SDK 收到服务器端下发事件后,会以通知代理的方式给到上层,通过event.eventType判断事件类型.
 *
 * 注意:
 * 消息事件,如:群事件,SDK会作为一个特殊的消息类型下发,上层依旧通过 JMSGMessageDelegate 监听消息事件.
 *
 * 非消息事件,如:被踢下线、加好友,SDK会作为通知事件下发,上层通过本类 JMSGEventDelegate 的方法可监听此类事件.
 */
@optional
- (void)onReceiveNotificationEvent:(JMSGNotificationEvent *)event;
/*!
 * @abstract 消息撤回事件
 *
 * @param retractEvent 下发的通知事件,事件类型请查看 JMSGMessageRetractEvent 类
 *
 * @discussion 收到此事件时,可以通过 event.conversation 判断是否属于某个会话
 *
 * @since 3.2.0
 */
@optional
- (void)onReceiveMessageRetractEvent:(JMSGMessageRetractEvent *)retractEvent;
/*!
 * @abstract 消息回执状态变更事件
 *
 * @param receiptEvent 下发的通知事件,事件类型请查看 JMSGMessageReceiptStatusChangeEvent 类
 *
 * @discussion 上层可以通过 receiptEvent 获取相应信息
 *
 * @since 3.3.0
 */
@optional
- (void)onReceiveMessageReceiptStatusChangeEvent:(JMSGMessageReceiptStatusChangeEvent *)receiptEvent;
/*!
 * @abstract 消息透传事件
 *
 * @param transparentEvent 下发的通知事件,事件类型请查看 JMSGMessageTransparentEvent 类
 *
 * @discussion 上层可以通过 transparentEvent 获取相应信息,如果自定义的透传信息、会话
 *
 * @since 3.3.0
 */
@optional
- (void)onReceiveMessageTransparentEvent:(JMSGMessageTransparentEvent *)transparentEvent;

JMSGDBMigrateDelegate

/*!
 * @abstract 数据库升级开始
 */
@optional
- (void)onDBMigrateStart;

/*!
 * @abstract 数据库升级完成
 *
 * @param error 如果升级失败, 则 error 不为 nil. 反之 error 为 nil 时升级成功.
 *
 * @discussion SDK会有自动重试, 竭力避免失败. 如果实在返回失败, 建议提示用户重新安装 App.
 */
@optional
- (void)onDBMigrateFinishedWithError:(NSError *)error;

Cross-application API Interface

Cross-application communication means that different applications under the same developer account can communicate with each other to meet the developer's need for application communication under different appKeys.

Cross-application user management

Get cross-application user information in batches

/*!
 * @abstract 批量获取跨应用的用户信息
 *
 * @param usernameArray 用户名列表。NSArray 里的数据类型为 NSString
 * @param handler 结果回调。正常返回时 resultObject 的类型为 NSArray,数组里的数据类型为 JMSGUser
 *
 * @discussion 这是一个批量接口。
 */
+ (void)userInfoArrayWithUsernameArray:(NSArray JMSG_GENERIC(__kindof NSString *)*)usernameArray
                                appKey:( NSString *JMSG_NULLABLE)userAppKey
                     completionHandler:(JMSGCompletionHandler)handler;
Example
// 批量获取跨应用的用户信息
// 注:usernameArray 里的username都应该是在你所填userAppKey应用的user
[JMSGUser userInfoArrayWithUsernameArray:[NSArray arrayWithObjects:@"username1",@"username2", nil] appKey:@"appkey" completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        NSArray *userList =(NSArray *)resultObject;
        NSLog(@"userList:%@",userList);
    }
}];

Cross-application message management

1、Send cross-application text messages of single chat

/*!
 * @abstract 发送跨应用单聊文本消息
 *
 * @param text 文本内容
 * @param username 单聊对象 username
 *
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendSingleTextMessage:(NSString *)text
                       toUser:(NSString *)username
                       appKey:(NSString *)userAppKey;

2、Send cross-application picture messages of single chat

/*!
 * @abstract 发送跨应用单聊图片消息
 *
 * @param imageData 图片数据
 * @param username 单聊对象 username
 *
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendSingleImageMessage:(NSData *)imageData
                        toUser:(NSString *)username
                        appKey:(NSString *)userAppKey;

3、Send cross-application voice messages of single chat

/*!
 * @abstract 发送跨应用单聊语音消息
 *
 * @param voiceData 语音数据
 * @param duration 语音时长
 * @param username 单聊对象 username
 *
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendSingleVoiceMessage:(NSData *)voiceData
                 voiceDuration:(NSNumber *)duration
                        toUser:(NSString *)username
                        appKey:(NSString *)userAppKey;

4、Send cross-application file messages of single chat

/*!
 * @abstract 发送跨应用单聊文件消息
 *
 * @param fileData 文件数据数据
 * @param fileName 文件名
 * @param username 单聊对象 username
 *
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendSingleFileMessage:(NSData *)fileData
                     fileName:(NSString *)fileName
                       toUser:(NSString *)username
                       appKey:(NSString *)userAppKey;

5、Send cross-application location messages of single chat

/*!
 * @abstract 发送跨应用单聊地理位置消息
 * @param latitude 纬度
 * @param longitude 经度
 * @param scale 缩放比例
 * @param address 详细地址
 * @param username 单聊对象
 * @param userAppKey 单聊对象的appKey
 * @discussion 快捷方法,不需要先创建消息而直接发送。
 */
+ (void)sendSingleLocationMessage:(NSNumber *)latitude
                        longitude:(NSNumber *)longitude
                            scale:(NSNumber *)scale
                          address:(NSString *)address
                           toUser:(NSString *)username
                           appKey:(NSString *)userAppKey;

Cross-application session management

1、Get a cross-application single chat session

/*!
 * @abstract 会话目标用户所在的 appKey
 *
 * @discussion 这是为了跨应用聊天而新增的一个字段.
 * 如果此字段为空, 则表示为默认的主应用.
 *
 * 单聊会话时, 如果单聊对象用户不属于主应用, 则此字段会有值.
 */
@property(nonatomic, strong, readonly) NSString *targetAppKey;

/*!
 * @abstract 获取跨应用单聊会话
 *
 * @param username 单聊对象的username
 * @param userAppKey 单聊对象的appkey
 *
 * @discussion 如果会话还不存在,则返回 nil
 *
 */
+ (JMSGConversation * JMSG_NULLABLE)singleConversationWithUsername:(NSString *)username

                                                      appKey:(NSString *)userAppKey;

2、Create a cross-application single chat session

/*!
 * @abstract 创建跨应用单聊会话
 *
 * @param username 单聊对象的username
 * @param userAppKey 单聊对象的appkey
 * @param handler 结果回调。正常返回时 resultObject 类型为 JMSGConversation。
 *
 * @discussion 如果会话已经存在,则直接返回。如果不存在则创建。
 */
+ (void)createSingleConversationWithUsername:(NSString *)username
                                      appKey:(NSString *)userAppKey
                           completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
// 创建跨应用会话
[JMSGConversation createSingleConversationWithUsername:@"username" appKey:@"appkey"  completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        NSLog(@"创建跨应用会话成功");
    } else {
        NSLog(@"创建跨应用会话失败");
    }
}];

3、Delete cross-application single chat session

/*!
 * @abstract 删除跨应用单聊会话
 *
 * @param username 单聊用户名
 * @param userAppKey 单聊用户的appkey
 *
 * @discussion 除了删除会话本身,还会删除该会话下所有的聊天消息。
 */
+ (BOOL)deleteSingleConversationWithUsername:(NSString *)username
                                      appKey:(NSString *)userAppKey;

Cross-application group management

1、Add group cross-application members

/*!
 * @abstract 添加群组跨应用成员
 *
 * @param usernameArray 用户名数组。数组里的成员类型是 NSString
 * @param handler 结果回调。正常返回时 resultObject 为 nil.
 */
- (void)addMembersWithUsernameArray:(NSArray JMSG_GENERIC(__kindof NSString *) *)usernameArray
                             appKey:userAppKey
                  completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
[group addMembersWithUsernameArray:[NSArray arrayWithObjects:@"username1",@"username2", nil] appKey:@"被添加用户所在应用的appkey" completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        NSLog(@"\n 添加群组跨应用成员 成功");
    }
}];

2、Delete group cross-application members

/*!
 * @abstract 删除群组跨应用成员
 *
 * @param usernameArray 用户名数据. 数组里的成员类型是 NSString
 * @param handler 结果回调。正常返回时 resultObject 为 nil.
 */
- (void)removeMembersWithUsernameArray:(NSArray JMSG_GENERIC(__kindof NSString *) *)usernameArray
                                appKey:userAppKey
                     completionHandler:(JMSGCompletionHandler JMSG_NULLABLE)handler;
Example
[group removeMembersWithUsernameArray:[NSArray arrayWithObjects:@"username1",@"username2", nil] appKey:@"被删除用户所在应用的appkey" completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        NSLog(@"\n 添删除组跨应用成员 成功");
    }
}];

Cross-application blacklist management

1、Add blacklist across applications

/*!
 * @abstract 跨应用添加黑名单
 * @param usernameArray 作用对象的username数组
 * @param appKey 应用的appKey
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 相应对象
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 可以一次添加多个用户
 */
+ (void)addUsersToBlacklist:(NSArray JMSG_GENERIC(__kindof NSString *)*)usernameArray
                     appKey:(NSString *)userAppKey
          completionHandler:(JMSGCompletionHandler)handler;

Example
//添加黑名单
[JMSGUser addUsersToBlacklist:[NSArray arrayWithObjects:@"username1",@"username2", nil] appKey:@"被添加用户所在应用的appkey" completionHandler:^(id resultObject, NSError *error) {
       if (!error) {
           NSLog(@"\n 跨应用添加黑名单成功:%@ \n ",resultObject);
       }
   }];

2、Delete blacklist across applications

/*!
 * @abstract 跨应用删除黑名单
 * @param usernameArray 作用对象的username数组
 * @param appKey 应用的appKey
 * @param handler 结果回调。回调参数:
 *
 * - resultObject 相应对象
 * - error 错误信息
 *
 * 如果 error 为 nil, 表示设置成功
 * 如果 error 不为 nil,表示设置失败
 *
 * @discussion 可以一次删除多个黑名单用户
 */
+ (void)delUsersFromBlacklist:(NSArray JMSG_GENERIC(__kindof NSString *)*)usernameArray
                       appKey:(NSString *)userAppKey
            completionHandler:(JMSGCompletionHandler)handler;

Example
//删除黑名单
[JMSGUser delUsersFromBlacklist:[NSArray arrayWithObjects:@"username1",@"username2", nil] appKey:@"被删除用户所在应用的appkey" completionHandler:^(id resultObject, NSError *error) {
    if (!error) {
        NSLog(@"\n 跨应用删除黑名单成功:%@ \n ",resultObject);
    }
}];

Cross-application do-not-disturb management

Cross-application do-not-disturb setting

Cross-application functions are supported in DND settings of the application. For details, please see "User Do-Not-Disturb Settings".

Cross-app Friend Management

Friend management interface of this application supports cross-applications. See "Friend Management" for details.

Definition of Error Code

Reference Document: Error Code List of IM iOS SDK


Copyright 2011-2018, jiguang.cn, All Rights Reserved.
粤ICP备12056275号-13 深圳市和讯华谷信息技术有限公司

Documentation built with MkDocs.