相信大家在项目中会用到即时通讯功能,自己去写的话会需要前后台合作,会大大加大开发的周期,所以考虑使用第三方的即时通讯平台,比如现在有融云,环信....等等等!楼主在项目开发过程中使用到过环信和融云,今天就为大家写下IOS端集成环信的方法和可能会遇到的问题。(融云提供聊天会话列表和聊天界面并且允许我们自定义,所以很方便的)。
一:准备工作
1.首先打开融云官网http://www.rongcloud.cn/,注册自己的账户,并登陆。
2.点击左边创建应用,在打开的小窗口填写你的项目的一些信息(如果正在开发阶段可以选择未运营商务用户,如果项目上线后是需要提交申请审核,后面再讲)。
3.创建好项目过后点击刚刚创建好的项目,并点击左边的"App Key",里面包含开发环境和生产环境,不同环境下的App Key是不一样的,融云基本是免费的,但是他会提供给你一些付费的服务(视自己项目而定)。记录好App Key,因为在后面工程中需要。融云开发环境允许100个测试用户,如果超过了100个测试用户,需要在后台手动添加用户,一次只能添加20个。
4.导入SDK到项目(需要什么功能就导入哪一个sdk模块,楼主只需要简单的聊天功能加聊天界面,所以导入融云 IM 通讯能力库 - RongCloudIM/IMLib
融云 IM 界面组件 - RongCloudIM/IMKit),融云支持下载到本地手动导入,还有一种方式就是使用cocoapods导入,个人觉得使用cocapods导入是最方便的。cocoapods的简介和使用方法转自:http://www.jianshu.com/p/b64b4fd08d3c。
5.添加依赖库,Xcode点击左侧项目名 - Build Phases - Link Binary With Libraies 点击下面的加号添加下图的依赖库(Xcode7.0以上版本,相信没人还会用Xcode7.0以下的版本做开发吧!)。
融云依赖库:
系统依赖库:
AssetsLibrary.framework
AudioToolbox.framework
AVFoundation.framework
CFNetwork.framework
CoreAudio.framework
CoreGraphics.framework
CoreLocation.framework
CoreMedia.framework
CoreTelephony.framework
CoreVideo.framework
ImageIO.framework
libc++.tbd
libc++abi.tbd
libsqlite3.tbd
libstdc++.tbd
libxml2.tbd
libz.tbd
MapKit.framework
OpenGLES.framework
QuartzCore.framework
SystemConfiguration.framework
UIKit.framework
Photos.framework
SafariServices.framework
添加完成依赖库后记得需要在 Xcode 项目 Build Settings - Other Linker Flags 中,点击下方加号,增加 "-ObjC"。
如果上面的步骤都已经做完了,可以试着编译以下自己项目,看会不会报错(如果有报错记得留言,我也会为尽我的努力为大家解答),准备工作就到这里了,下面我们开始集成。
二:开始集成回话列表
1.打开工程在Appdelegate里面连接融云服务器,使用融云开发者控制台注册得到的 App Key,通过 RCIM 的单例,传入 initWithAppKey:方法,初始化 SDK。在使用融云 SDK 所有功能(包括显示 SDK 中的 View 或者显示继承于 SDK 的 View )之前,您必须先调用此方法初始化 SDK。 在 App 的整个生命周期中,您只需要将 SDK 初始化一次。
[[RCIM sharedRCIM] initWithAppKey:@"后台应用的AppKey"];
2.连接融云服务器。
[[RCIM sharedRCIM] connectWithToken:@"YourTestUserToken" success:^(NSString *userId) {
NSLog(@"登陆成功。当前登录的用户ID:%@", userId);
} error:^(RCConnectErrorCode status) {
NSLog(@"登陆的错误码为:%ld", status);
} tokenIncorrect:^{
//token过期或者不正确。
//如果设置了token有效期并且token过期,请重新请求您的服务器获取新的token
//如果没有设置token有效期却提示token错误,请检查您客户端和服务器的appkey是否匹配,还有检查您获取token的流程。
NSLog(@"token错误");
}];
连接融云服务器的时候需要传给融云服务器一个token,相当于登录融云的一个"用户名",这个"用户名"是你们后台服务器集成的事情,所以你不用管,到时候后台会在你需要的地方返回给你这个token。在测试的时候需要我们在融云控制台获取一个测试的token,用来登录。方法如下
将token后面的复制下来。
贴上Appdelegate代码
#import "AppDelegate.h"
#import <RongIMLib/RongIMLib.h>
#import <RongIMKit/RongIMKit.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
//初始化融云SDK
[[RCIM sharedRCIM] initWithAppKey:@"6tnym1br65di7"];
//登录融云服务器
[[RCIM sharedRCIM] connectWithToken:@"0ABt7ILPEShS9stGR+AJgN3bHoP4ztV1ORxxRULm/FLmvyxeqth6/QrQGCuRGPBUkOFQ2cmYVi9C+B2yuDZfcA==" success:^(NSString *userId) {
NSLog(@"登陆成功。当前登录的用户ID:%@", userId);
} error:^(RCConnectErrorCode status) {
NSLog(@"登陆的错误码为:%ld", (long)status);
} tokenIncorrect:^{
//token过期或者不正确。
//如果设置了token有效期并且token过期,请重新请求您的服务器获取新的token
//如果没有设置token有效期却提示token错误,请检查您客户端和服务器的appkey是否匹配,还有检查您获取token的流程。
NSLog(@"token错误");
}];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end
当登录成功后,控制台会打印出
...
登陆成功。当前登录的用户ID:123
...
这是代表你的用户ID为123的账号已经登录到融云服务器成功,现在可以使用融云的服务了。
3.融云 IMKit 已经实现了一个默认的会话列表视图控制器,您直接使用或继承 RCConversationListViewController,即可快速启动和使用会话列表界面。意思是融云已经给你写好了一个回话列表的界面,我们如果对界面的要求不是很高的话,可以直接继承这个ViewController,并且这个ViewController是可以支持界面的一些修改,所以是不是很方便呢。
首先,新建一个类继承自RCConversationListViewController。
并在.m文件的- (void)viewDidLoad方法中设置需要显示哪些类型的会话以及哪些类型的会话可以在会话列表页面聚合显示。附上.m文件代码
#import "MyselfListViewController.h"
@interface MyselfListViewController ()
@end
@implementation MyselfListViewController
- (void)viewDidLoad {
[super viewDidLoad];
//设置需要显示哪些类型的会话,由于楼主只需要单聊功能,所以只设置ConversationType_PRIVATE
[self setDisplayConversationTypes:@[@(ConversationType_PRIVATE),
]];
//设置需要将哪些类型的会话在会话列表中聚合显示
[self setCollectionConversationType:@[@(ConversationType_PRIVATE),
]];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
这样一个回话列表界面就已经集成完成,我们可以在融云控制着后台发送一条测试消息,看一下回话列表能不能收到消息。
这样你的会话列表就会收到一条消息。
这时候你会好奇了,为什么只有消息内容,而没有用户名以及头像呢,这就是融云即时通讯的一个模式,他只负责做消息的转发者,而不会负责管理好友的信息,融云这样说:融云认为,每一个设计良好且功能健全的 App 都应该能够在本地获取、缓存并在合适的时机更新 App 中的用户信息。所以,融云不维护和管理用户基本信息(用户ID、昵称、头像)的获取、缓存、变更和同步。意思是用户的头像用户的名称,全都是保存在自己的服务器,融云只负责管理聊天内容有关的业务,所以现在就有一个问题,如何通过自己的服务器的用户名和头像对应到融云管理的相应的聊天信息呢,我们在后面用到时候在说。
三:开始集成聊天界面
下面我们开始集成聊天界面,融云为我们也准备了一个聊天界面RCConversationViewController,如果项目没有特殊要求,这个聊天界面也能满足我们很项目的需求,当然,融云也是给我们提供进行页面的修改的接口的。
首先新建一个类继承自RCConversationViewController。
创建好了之后我们需要在继承自RCConversationListViewController的控制器中重写一个方法:- (void)onSelectedTableRow:(RCConversationModelType)conversationModelType
conversationModel:(RCConversationModel *)model
atIndexPath:(NSIndexPath *)indexPath方法,来点击会话列表进入相应的聊天界面,再次贴上继承自RCConversationListViewController的会话列表界面.m实现代码
#import "MyselfListViewController.h"
#import "MyselfConversationController.h"
@interface MyselfListViewController ()
@end
@implementation MyselfListViewController
- (void)viewDidLoad {
[super viewDidLoad];
//设置需要显示哪些类型的会话,由于楼主只需要单聊功能,所以只设置ConversationType_PRIVATE
[self setDisplayConversationTypes:@[@(ConversationType_PRIVATE),
]];
}
//重写RCConversationListViewController的onSelectedTableRow事件
- (void)onSelectedTableRow:(RCConversationModelType)conversationModelType
conversationModel:(RCConversationModel *)model
atIndexPath:(NSIndexPath *)indexPath {
MyselfConversationController *conversationVC = [[MyselfConversationController alloc]init];
//聊天界面的聊天类型
conversationVC.conversationType = model.conversationType;
//需要打开和谁聊天的会话界面,和谁聊天其实是通过TargetId来联系的。
conversationVC.targetId = model.targetId;
conversationVC.title = @"想显示的会话标题";
[self presentViewController:conversationVC animated:YES completion:NULL];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
这样再次运行项目,点击屏幕的一个会话列表,查看聊天界面效果。
我一直用的[self presentViewController:conversationVC animated:YES completion:NULL];来打开新的页面,所以没有导航栏,也就没有标题栏。
到了这里大致的融云就已经完成。是不是很简单呢。