快速开始

网易作为国内最大最早的即时通信开发商之一,从最早的网易泡泡到后来的易信,已经有了超过十五年的通讯技术积累。现在我们整合了这些产品高稳定、高可靠即时通信能力,开发者能以很小的成本将即时通信功能集成到自己的 APP 中。

网易云信即时通讯iOS-SDK为iOS移动应用提供完善的即时通信功能开发框架,屏蔽其内部复杂细节,对外提供较为简洁的 API 接口,方便第三方应用快速集成即时通信功能。SDK 兼容 iOS 8.0+ ,Demo 兼容 iOS 8.0+ 。

SDK集成

云信即时通讯SDK支持两种集成方式:

此外,为了让开发者可以轻松快速地在 App 中集成 IM 功能,我们还提供了开源的UI组件: NIM_iOS_UIKit , 通过简单的配置就可以实现聊天功能。

CocoaPods集成

集成前,请先前往SDK下载页面查看当前最新版本,并查询本地仓库中对应的版本是否为最新版本。若不是最新版本,建议先更新本地仓库,以确保可以集成最新的SDK版本。

    pod search NIMSDK_LITE   //本地仓库中查询NIMSDK_LITE信息
    pod repo update          //更新本地仓库

CocoaPods集成资源关键词详解:

关键词 所含资源
NIMSDK_LITE IM即时通讯
NIMSDK NIMSDK_LITE+实时音视频+互动直播+互动白板
NIMKit/Core NIM_iOS_UIKit+特定版本的第三方依赖库
NIMKit NIMSDK_LITE+NIM_iOS_UIKit+特定版本的第三方依赖库
NIMKit/Full NIMSDK+NIM_iOS_UIKit+特定版本的第三方依赖库

如只需要即时通讯功能,且不需NIM_iOS_UIKit组件,可在Podfile中写入:

    //IM即时通讯SDK
    pod 'NIMSDK_LITE' 

然后执行安装命令:

    pod install

手动集成

【注】NIMSDK 在 5.1.0 版本之后已改为动态库,集成方式有所改变,若需要集成高于此版本的 SDK,只需要做以下步骤: 将下载的 SDK 拖动到 Targets -> General -> Embedded Binaries 里,如下图

弹框这样选择

即可完成集成。

若想集成静态库,可使用如下集成方式:

#!/bin/sh

# Strip invalid architectures

strip_invalid_archs() {
binary="$1"
echo "current binary ${binary}"
# Get architectures for current file
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
stripped=""
for arch in $archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
if [ -f "$binary" ]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
fi
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
}

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"

strip_invalid_archs "$FRAMEWORK_EXECUTABLE_PATH"
done

使用说明

API调用方式

所有业务均通过 NIMSDK 单例调用

@interface NIMSDK : NSObject
/**
 *  获取SDK实例
 *
 *  @return NIMSDK实例
 */
+ (instancetype)sharedSDK;
@end

以获取聊天管理类为例:

id<NIMChatManager> chatManager = [[NIMSDK sharedSDK] chatManager];

虽然所有的云信接口都是线程安全的,但我们强烈推荐您在且只在主线程调用相应接口。

通知方式

SDK 通过两种方式通知上层 API 调用结果:回调(callback)和委托 (delegate),两种方式都只在主线程触发。

一般回调接口直接反映在对应接口的 completion 参数上,调用时设置即可。而委托则需要开发者在合适时机在对应管理类上进行添加和移除:一般推荐在相应 ViewController 或管理类初始化进行委托注册,在其销毁时进行移除。

例如,开发者需要在在会话页上监听消息的发送结果

@implementation MySessionViewController

- (void)dealloc
{
  ...
    [[NIMSDK sharedSDK].chatManager removeDelegate:self];
  ...
}

- (void)viewDidLoad 
{
  ...
    [[NIMSDK sharedSDK].chatManager addDelegate:self];
  ...
}

#pragma mark - NIMChatManagerDelegate
- (void)sendMessage:(NIMMessage *)message didCompleteWithError:(NSError *)error
{
    //发送结果
}

所有调用错误都会以 NSError 的形式暴露。针对不同场景,我们将错误进行分类,主要分为以下两种错误域和对应错误码

错误域 错误码 说明
NIMLocalErrorDomain NIMLocalErrorCode 本地操作出错导致
NIMRemoteErrorDomain NIMRemoteErrorCode 与服务器交互出错导致

在开发过程中遇到错误情况,可以对照错误域和错误码进行排查,具体定义可以参考 NIMGlobalDefs.h。当然在开发过程中你也可以通过检视 NSError 中 userInfo 对应的错误描述信息定位问题。

初始化

将SDK集成到客户端后,使用SDK前需要先完成初始化工作。

NIMSDK 注册

NIM SDK 通过注册 App Key 来进行初始化。在使用 SDK 任何方法之前,都应该首先调用初始化方法。正常业务情况下,初始化方法有仅只应调用一次。

原型

@interface NIMSDK : NSObject
/**
 *  初始化SDK
 *
 *  @param option  注册选项
 */
- (void)registerWithOption:(NIMSDKOption *)option;
@end

NIMSDKOption 选项参数列表

参数 类型 说明
appKey NSString 云信分配的 App Key
apnsCername NSString 云信 APNs 推送证书名

appKey 作为应用的唯一逻辑标识,同一 appKey 不同 Bundle Id 的应用消息仍可以互通。

apnsCername 为APNs推送证书名。

调用示例

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...
    //推荐在程序启动的时候初始化 NIMSDK    
    NSString *appKey        = @"your app key";
    NIMSDKOption *option    = [NIMSDKOption optionWithAppKey:appKey];
    option.apnsCername      = @"your APNs cer name";
    option.pkCername        = @"your pushkit cer name";
    [[NIMSDK sharedSDK] registerWithOption:option];
    ...
}

其他配置参数初始化

NIM SDK 还提供了一些其他额外的初始化配置以供开发者做一些扩展。

NIMServerSetting

NIMServerSetting 是整体的云信服务器配置,需要开发者自己创建并注入。

示例

NIMServerSetting *setting    = [[NIMServerSetting alloc] init];
setting.enabledHttps = YES;
[[NIMSDK sharedSDK] setServerSetting:setting];

NIMSDKConfig

NIMSDKConfig 是一个单例,推荐在调用注册接口前配置。

原型

@interface NIMSDKConfig : NSObject

/**
 *  返回配置项实例
 *
 *  @return 配置项
 */
+ (instancetype)sharedConfig;

@end

示例:

[NIMSDKConfig sharedConfig].enabledHttpsForInfo = YES;

[NIMSDKConfig sharedConfig].enabledHttpsForMessage = YES;
- (void)setupSDKDir:(NSString *)sdkDir;

为了更好的应用体验,SDK 需要对应用数据做一些本地持久,比如消息,用户信息等等。在默认情况下,所有数据将放置于 $Document/NIMSDK 目录下。

设置该值后 SDK 产生的数据(包括聊天记录,但不包括临时文件)都将放置在这个目录下

示例

[[NIMSDKConfig sharedConfig] setupSDKDir:@"your data path"];
- (BOOL)shouldIgnoreNotification:(NIMNotificationObject *)notification

此方法在消息将要存储到本地时调用,配置对象判断是否忽略返回 YES 或 NO 。开发者只应该在这个回调里做简单逻辑判断,如果做耗时操作会严重影响存储性能。

配置名称 字段 说明
是否在收到消息后自动下载附件 fetchAttachmentAutomaticallyAfterReceiving 在收到图片或视频消息后,默认情况下 SDK 会去主动获取图片的缩略图和视频的第一帧封面,将这个字段设置为 NO,SDK 将不再主动获取,开发者需要在根据业务逻辑手动调用获取附件接口
是否在收到聊天室消息后自动下载附件 fetchAttachmentAutomaticallyAfterReceivingInChatroom 同普通消息下载附件开关说明,默认情况下 SDK 不会去主动获取聊天室消息的附件
是否使用 NSFileProtectionNone 作为云信文件的 NSProtectionKey fileProtectionNone 默认为 NO,只有在上层 APP 开启了 Data Protection 时才起效。设置成 YES 时,云信文件保护属性 为 NSFileProtectionNone ,设置成 NO 时,为 NSFileProtectionCompleteUntilFirstUserAuthentication
是否需要将被撤回的消息计入未读计算考虑 shouldConsiderRevokedMessageUnreadCount  默认为 NO。设置成 YES 的情况下,如果被撤回的消息本地还未读,那么当消息发生撤回时,对应会话的未读计数将减 1 以保持最近会话未读数的一致性。
是否需要多端同步未读数 shouldSyncUnreadCount 默认为 NO。设置成 YES 的情况下,同个账号多端(PC 和 移动端等)将同步未读计数。
是否将群通知计入未读 shouldCountTeamNotification 默认为 NO。设置成 YES 的情况下,收到的群通知也会计入未读数
针对用户信息开启 https 支持 enabledHttpsForInfo 默认为 YES。在默认情况下,我们认为用户头像,群头像,聊天室类用户头像等信息都是默认托管在云信上,所以 SDK 会针对他们自动开启 https 支持。但如果你需要将这些信息都托管在自己的服务器上,需要设置这个接口为 NO,避免 SDK 自动将你的 http url 自动转换为 https url。
针对消息内容开启 https 支持 enabledHttpsForMessage 默认为 YES。在默认情况下,我们认为消息,包括图片,视频,音频信息都是默认托管在云信上,所以 SDK 会针对他们自动开启 https 支持。但如果你需要将这些信息都托管在自己的服务器上,需要设置这个接口为 NO,避免 SDK 自动将你的 http url 自动转换为 https url。 (强烈不建议) 。需要注意的是即时设置了这个属性,通过 iOS SDK 发出去的消息 URL 仍是 https 的,设置这个值只影响接收到的消息 URL 格式转换
自动登录重试次数 maxAutoLoginRetryTimes 即默认情况下,自动登录将无限重试。设置成大于 0 的值后,在没有登录成功前,自动登录将重试最多 maxAutoLoginRetryTimes 次,如果失败,则抛出错误 (NIMLocalErrorCodeAutoLoginRetryLimit)。
本地 log 存活期 maximumLogDays 默认为 7 天。即超过 7 天的 log 将被清除。只能设置大于等于 2 的值
是否支持动图缩略 animatedImageThumbnailEnabled 默认为 NO。即默认情况下,从服务器获取原图缩略图时,如果原图为动图,我们将返回原图第一帧的缩略图。而开启这个选项后,我们将返回缩略图后的动图。这个选项只影响从服务器获取的缩略图,不影响本地生成的缩略图
是否禁止后台重连 reconnectInBackgroundStateDisabled 默认为 NO。即默认情况下,当程序退到后台断开连接后,如果 App 仍能运行,SDK 将继续执行自动重连机制。设置为 YES 后在后台将不自动重连,重连将被推迟到前台进行。只有特殊用户场景才需要此设置,无明确原因请勿设置。
是否开启群回执功能 teamReceiptEnabled 默认为 NO。
客户端自定义信息,用于多端登录时同步该信息 customTag 开发者自定义

NOS资源场景配置

sceneDict 预设场景和自定义场景规则。

原型

@interface NIMSDK : NSObject

/**
*  资源场景配置
*  @discussion nos 预设场景和自定义场景规则
*  可以覆盖设置,如果预设场景不设置,为系统默认设置
*  sceneDict key-value,系统默认预设场景为3种,自定义场景不超过10种
*  key 是场景,nsstring类型;value 是资源存活时间,nsnumber类型,精确到天,0为永久存活
*  例如:@{@"nim_icon":@0,@"nim_msg":@0,@"nim_system":@0,@"nim_custom":@30}
*/
@property (nonatomic,strong)      NSMutableDictionary *sceneDict;

@end

登录

在调用SDK登录接口之前,需要先完成IM账号的注册(注册一次即可),为应用下的每一位IM用户注册一个唯一的账号(account,又称accid)。推荐开发者首先阅读这里 来加深对云信账号体系流程的认知。 目前,云信提供两种注册方式:

手动登录

在新设备上初次登录,以及被踢、切换账号与注销登录后下一次登录,需要使用手动登录。对应用户手动输入登录账号密码的场景。

@protocol NIMLoginManager <NSObject>
/**
 *  登录
 *
 *  @param account    帐号
 *  @param token      令牌 (在后台绑定的登录token)
 *  @param completion 完成回调
 */
- (void)login:(NSString *)account
        token:(NSString *)token
   completion:(NIMLoginHandler)completion;
@end

示例

NSString *account = @"your account";
NSString *token   = @"your token";
[[[NIMSDK sharedSDK] loginManager] login:account
                                   token:token
                              completion:^(NSError *error) {}];

error 为登录错误信息,成功则为 nil。

自动登录

手动登录成功后,保存至本地的用户账号和密码,可用作自动登录时使用。主要针对应用被清理掉后,再次点击图标启动时,无需输入用户名密码即可完成登录的场景。此时 APP 可以在无网络,未登录成功的状态下直接访问用户本地SDK数据。自动登录需要调用如下接口:

原型

@protocol NIMLoginManager <NSObject>
/**
 *  自动登录
 *
 *  @param loginData 自动登录参数
 *  @discussion 启动APP如果已经保存了用户帐号和令牌,建议使用这个登录方式,使用这种方式可以在无网络时直接打开会话窗口
 */
- (void)autoLogin:(NIMAutoLoginData *)loginData;
@end

NIMAutoLoginData 参数列表

参数 类型 说明
account NSString 账号
token NSString 令牌(在后台绑定的登录token)
forcedMode BOOL 强制模式开关

NIMAutoLoginData 中的 forcedMode 为强制模式开关。非强制模式下的自动登录,服务器将检查当前登录设备是否为上一次登录设备,如果不是,服务器将拒绝这次自动登录(返回 error code 为 417 的错误);强制模式下的自动登录,服务器将不检查当前登录设备是否为上一次登录设备,安全性较低,但较为便捷。

示例

NIMAutoLoginData *loginData = [[NIMAutoLoginData alloc] init];
loginData.account = account;
loginData.token = token;

[[[NIMSDK sharedSDK] loginManager] autoLogin:loginData];

登录状态监听

App可以通过以下代理委托监听当前登录状态:

@protocol NIMLoginManagerDelegate <NSObject>
/**
 *  登录回调
 *
 *  @param step 登录步骤
 *  @discussion 这个回调主要用于客户端UI的刷新
 */
- (void)onLogin:(NIMLoginStep)step
@end

NIMLoginStep 枚举列表

说明
NIMLoginStepLinking 连接服务器
NIMLoginStepLinkOK 连接服务器成功
NIMLoginStepLinkFailed 连接服务器失败
NIMLoginStepLogining 登录
NIMLoginStepLoginOK 登录成功
NIMLoginStepLoginFailed 登录失败
NIMLoginStepSyncing 开始同步数据
NIMLoginStepSyncOK 同步数据完成
NIMLoginStepLoseConnection 连接断开
NIMLoginStepNetChanged 网络切换

一次完整的登录的基本步骤为

自动登录除了会触发上述相应步骤变化回调外,在碰到一些 SDK 无法自动解决的错误时,开发者需要在下面这个回调里做出相应的处理。

举例来说,当前网络状态较差时,容易导致自动登录发生网络超时错误,此时上层无需处理,SDK 会持续有策略地重连,而一旦发生用户名密码不匹配的错误时,则需要上层做出相应处理:登出并提示用户手动登录或是从自己的应用服务器刷新相应的用户名密码。一些特殊的登录错误将在下文列出,建议在集成时能尽可能考虑应对逻辑。

@protocol NIMLoginManagerDelegate <NSObject>
/**
 *  自动登录错误回调
 *
 *  @param error 错误信息
 *  @discussion 这个回调主要用于抛出SDK无法自动解决的错误
 */
- (void)onAutoLoginFailed:(NSError *)error
@end

数据同步

NIM SDK 在登录成功后,会自动同步群信息,离线消息,漫游消息,系统通知等数据。数据同步过程对应NIMLoginManagerDelegate代理协议的-(void)onLogin:(NIMLoginStep)step回调里的:

在数据同步完成后,整个登录过程才算真正完成。

断网重连

SDK 提供了自动重连机制(自动重新建立与网易云通信服务器的连接并重新登录),所有重连的登录状态都会在 - (void)onLogin:(NIMLoginStep)step 方法中回调。

SDK 在两种场景下会自动进行重连:

  1. 手动/自动登录成功后,网络不佳导致链接断开的情况。
  2. 网络不佳时,账号密码本身正常(未被封禁,且账号密码均正确),启动App时调用自动登录接口的情况。

满足上述中一个条件,当用户遇到普通网络问题如连接超时等,会自动进行重连登录,不需要上层开发者去做额外的重登逻辑

重试次数超过预定上限时, SDK 也不会继续重连。重试次数在 NIMSDKConfig 中定义,默认为 0 ,为无次数限制重试。

原型

@interface NIMSDKConfig : NSObject
/**
 *  自动登录重试次数
 *  @discusssion 默认为 0。即默认情况下,自动登录将无限重试。设置成大于 0 的值后,在没有登录成功前,自动登录将重试最多 maxAutoLoginRetryTimes 次,如果失败,则抛出错误 (NIMLocalErrorCodeAutoLoginRetryLimit)。
 */
@property (nonatomic,assign)    NSInteger   maxAutoLoginRetryTimes;
@end

多端登录与互踢

云信SDK支持多种多端登录策略:

多端登录监听

当用户在某个客户端登录时,其他没有被踢掉的端会触发回调:

@protocol NIMLoginManagerDelegate <NSObject>
/**
 * 多端登录发生变化
 */
- (void)onMultiLoginClientsChangedWithType:(NIMMultiLoginType)type
@end

同时,可以查询当前时间登录的设备列表:

@protocol NIMLoginManager <NSObject>
/**
* 返回当前登录的设备列表
*/
- (NSArray<NIMLoginClient *> *)currentLoginClients;
@end

互踢

当本端被踢出时,可以通过以下回调感知到:

@protocol NIMLoginManagerDelegate <NSObject>
/**
 * 被踢(服务器/其他端)回调
 */
-(void)onKick:(NIMKickReason)code 
   clientType:(NIMLoginClientType)clientType
@end

APP收到被踢回调后,建议进行注销并切换到登录界面。

注销登录

应用层登出/注销自己的账号时需要调用 SDK 的登出操作,该操作会同时通知云信服务器进行 APNs 推送的解绑操作,避免用户已登出但依然将消息推送到当前设备。

@protocol NIMLoginManager <NSObject>
- (void)logout:(nullable NIMLoginHandler)completion;
@end

考虑到用户体验,登出的超时时间会比其他请求短一些。上层应用不管登出请求是否成功,UI 表现上都应该做出登出行为。如果遇到登出失败,开发者仍然应该跳转到登录界面,登出失败只是云信服务器进行 APNs 推送信息的解绑失败,本地信息仍然是清理成功的。

示例:

[[[NIMSDK sharedSDK] loginManager] logout:^(NSError *error) {
    //jump to login page
}];