使用融云和LeanCloud 创建一个IM应用

融云 是国内一家专门为APP开发者提供IM服务的公司,利用它提供的SDK可以快速使你的APP集成IM通讯能力。
详细的使用方法在它官网的开发文档中有提供,但是不得不吐槽的就是它的开发文档写的实在太乱了让人有种无从下手的感觉,下面简单记录一下使用过程。

导入SDK

推荐使用CocoaPods导入:

  1. 在Podfile中添加:

pod 'RongCloudIMKit'

  1. 然后执行命令:

pod install

获取Token

Token 也叫用户令牌,是 SDK 端用来连接融云服务器的凭证,每个用户连接服务器都需要一个 Token。每次初始化连接服务器时,都需要向服务器提交 Token。
获取Token需要注册一个融云的账号,然后新建一个应用,之后在API调试中填写userid(用户唯一标示符)、name(用户昵称)、portraitUri(头像url)就可以获得一个测试用的Token。

初始化和测试连接

获得测试用的Token之后就可以利用AppKey(创建应用时融云给你的应用标示符)和Token对应用进行初始化了:

//用AppKey初始化
RCIM.sharedRCIM().initWithAppKey("82hegw5uh4r8x")
//用Token测试连接
RCIM.sharedRCIM().connectWithToken(token, success: { (str:String!) -> Void in
print("连接成功!")
//连接成功后设置当前登陆用户信息
RCIMClient.sharedRCIMClient().currentUserInfo = RCUserInfo(userId: id, name: name, portrait: avatorURL)
//在UserDefaults中保存Token
NSUserDefaults.standardUserDefaults().setObject(token, forKey: "kDeviceToken")
//在主线程中调用更新UI
dispatch_async(dispatch_get_main_queue(), { () -> Void in
})},error: { (_) -> Void in
print("连接错误!")
}){ () -> Void in
print("Token不正确!")
}

连接成功后启动单聊会话

融云在它的SDK中已经集成聊天用户界面,所以我们只要创建一个RCConversationViewController的实例就能使用它提供的用户界面了,同时用户界面也支持自定义,这部分在官网的开发文档中有详细的介绍,这里就不做赘述。
需要注意的是:要使用RCConversationViewController,必须给它的几个属性赋值:

  • conversationType:聊天类型,有单聊、群聊等等

self.conversationType = RCConversationType.ConversationType_PRIVATE //这里的PRIVATE是单聊

  • targetId:聊天目标用户id

self.targerId = ""

  • userName:聊天目标用户的昵称

self.userName = ""

  • title:聊天界面显示的标题

self.title = self.userName
RCConversationViewController中还有其他很多的属性可以自定义,比如用户头像形状之类的,这些可以在它的头文件中找到。

测试单聊

设置好以上内容之后,单聊的工作就已经做好了,现在我们可以测试单聊的效果,这里由于还没有其他的用户,我们就先和自己聊天来测试一下单聊的效果;
把targerId设置成已经登录的id,然后就可以自己和自己聊天了,内部集成的界面还是挺简洁易用的,虽然是自己和自己聊天,但是他也不是在本地操作的,也要经过融云的服务器,所以你把网络断开的情况下是不能发出信息的。
到这里单聊已经实现了,但是你会发现聊天界面他是不会显示用户头像的,虽然你在初始化的时候给了一个头像的url,但是他是不会加载出来的,不得不说这一点确实很脑残,主要原因是融云为了安全起见,他的服务器是不会储存用户信息的,在融云那边只有一个Token和userid的对应关系,和你发送给他的好友关系,也就是说你的用户信息需要自己在用一个服务器存起来,然后向融云提供一个用户信息提供者;

设置用户信息提供者

要设置用户信息提供者首先要实现RCIMUserInfoDataSource协议,所以我们要在APP启动的时候让Appdelegate实现协议,然后:

func getUserInfoWithUserId(userId: String!, completion: ((RCUserInfo!) -> Void)!) {
let userInfo = RCUserInfo()
userInfo.userId = userId
switch userId{
case "xxx":
userInfo.name = "xxx"
userInfo.portraitUri = "http://7xl9qm.com1.z0.glb.clouddn.com/avatar.png"
case "x":
userInfo.name = "A"
userInfo.portraitUri = "http://www4.qqjay.com/u/files/2011/1216/d3302821f418fc5539398cb3ba72cd8c.jpg"
case "xxxxx":
userInfo.name = "B"
userInfo.portraitUri = "http://image.photophoto.cn/nm-6/018/030/0180300244.jpg"
case "xxxx":
userInfo.name = "C"
userInfo.portraitUri = "http://cdn.duitang.com/uploads/item/201407/26/20140726221707_i4ZnL.thumb.224_0.jpeg"
default:
print("no user")
}
completion(userInfo)
}