我想问下 融云怎么清除服务器端的融云清除聊天记录录?

  融云SDK查看ServerAPI里面有个获取Token的方法,本以为只要传三个参数就可以。后来发现,在请求头有几个必须要传的参数,否则服务器返回401(未授权)。拿获取Token接口为例子
  如图所示,请求头中包含 : App-Key(应用appkey), Nonce(随机数,不限长度),Timestamp(时间戳from1970),Signature(签名)。签名生成的方法 就是 sha1(appsecret+Nonce+Timestamp) 只有这几个请求头的值都正确了,接口才能正确返回Token。(至于什么是sha1加密,又称安全哈希算法,大家自行谷歌。。。)代码如下:
#import &CommonCrypto/CommonCrypto.h&
@implementation MSTool
single_implementation(MSTool)
//获取随机数
-(NSString *)getRandomNonce
NSInteger randomValue = [self getRandomNumber:100000 to:999999];
[NSString stringWithFormat:@"%ld",randomValue];
//获取时间戳 从1970年
-(NSString *)getTimestamp
NSDate *date = [NSDate date];
NSTimeInterval times =
[date timeIntervalSince1970];
return [NSString stringWithFormat:@"%.0f",times];
//获取从 from 到
to 的随机数
-(NSInteger)getRandomNumber:(NSInteger)from to:(NSInteger)to
return (NSInteger)(from + (arc4random() % (to - from + 1)));
//sha1 加密
-(NSString *)sha1WithKey:(NSString *)key
const char *cstr = [key cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:key.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, data.length, digest);
NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i=0; i&CC_SHA1_DIGEST_LENGTH; i++) {
[output appendFormat:@"%02x", digest[i]];
//根据appSecret nonce timestamp 获取signature
-(NSString *)getSignatureWithAppSecret:(NSString *)appSecret nonce:(NSString *)nonce timestamp:(NSString *)timestamp
NSString *sha1String = [NSString stringWithFormat:@"%@%@%@",appKey,nonce,timestamp];
return [self sha1WithKey:sha1String];
那么这些参数都有了,服务请求我用的AFN,和其他请求的区别就是设置一下请求头而已,代码如下:
//获取Token的接口   url = @"./user/getToken.json";
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer
= [AFHTTPRequestSerializer serializer];
NSDictionary *dict = @{@"userId":@"1",@"name":@"panzi",@"portraiUri":@"http://qlogo3./qzone/?"};
NSString *appkey = kMSChatAppK
NSString *nonce = [[MSTool sharedMSTool] getRandomNonce];
NSString *timestamp = [[MSTool sharedMSTool] getTimestamp];
NSString *signature = [[MSTool
sharedMSTool]getSignatureWithAppSecret:kMSChatAppSecret nonce:nonce timestamp:timestamp];
NSLog(@"%@",appkey);
NSLog(@"%@",nonce);
NSLog(@"%@",timestamp);
NSLog(@"%@",signature);
 //设置请求头
[manager.requestSerializer setValue:appkey forHTTPHeaderField:@"App-Key"];
[manager.requestSerializer setValue:nonce forHTTPHeaderField:@"Nonce"];
[manager.requestSerializer setValue:timestamp forHTTPHeaderField:@"Timestamp"];
[manager.requestSerializer setValue:signature forHTTPHeaderField:@"Signature"];  //调用POST方法
[manager POST:url parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id
_Nullable responseObject) {
NSLog(@"%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
看看,其实也不是很难啦,根据这个DEMO在稍微封装一下,就可以支持这种需要Header参数验证的接口了。融云还有好多东西,继续看~~
阅读(...) 评论()记一次解决问题的心得-iOS, 简易Hack融云SDK - 简书
记一次解决问题的心得-iOS, 简易Hack融云SDK
记一次解决问题的心得-iOS, 简易Hack融云SDK
今天在看融云的群, 偶然发现有人有一种需求:
下午7.29.48.png
另一个问题,有没有办法让进入聊天页面的时候,在输入框里预先输好一段文字。光标定位在后面,可以继续输
为了帮这位用户解决问题,首先去看了一下融云提供的IMKit的聊天界面的父类RCChatViewController
我是继承了一下
下午7.30.39.png
看到头文件属性的位置
细心的看到了 @property (strong, nonatomic) RCChatSessionInputBarView *msgInputB 有这样一个属性, 认定这就是我们的目标, 因为输入框肯定是放在这里的。
但是看到融云的SDK也是封掉了这个类的开发, 只使用@class来引用,
下午7.32.48.png
所以不能直接的拿到属性以及方法。
所以想到了运行时, 首先导入运行时的头文件
#import &objc/runtime.h&
然后呢 先去获得这个目标对象的属性列表, 通过名称简单的判断一下我们的输入框是什么。
NSString *className = @"RCChatSessionInputBarView";
const char * cClassName = [className UTF8String];
id classM = objc_getClass(cClassName);
unsigned int outCount,
objc_property_t * properties = class_copyPropertyList(classM, &outCount);
for (i = 0; i & outC i++) {
objc_property_t property = properties[i];
NSString * attributeName = [NSString stringWithUTF8String:property_getName(property)];
NSLog(@"%@", attributeName);
这样 打印除了所有的属性列表。
19:15:14.633 SuperMan[] audioBtn
19:15:14.633 SuperMan[] emojiBtn
19:15:14.633 SuperMan[] additionalBtn
19:15:14.634 SuperMan[] msgColumnTextView
19:15:14.638 SuperMan[] pressTalkButton
19:15:14.638 SuperMan[] parent
19:15:14.638 SuperMan[] currentPosY
19:15:14.639 SuperMan[] hash
19:15:14.639 SuperMan[] superclass
19:15:14.640 SuperMan[] description
19:15:14.640 SuperMan[] debugDescription
我们可以看到结果中有 msgColumnTextView
明显就是这个了、 所以拿到这个对象 就OK了、
最终解决办法
// Hack Rong Cloud
NSString *className = @"RCChatSessionInputBarView";
const char * cClassName = [className UTF8String];
id classM = objc_getClass(cClassName);
unsigned int outCount,
objc_property_t * properties = class_copyPropertyList(classM, &outCount);
for (i = 0; i & outC i++) {
objc_property_t property = properties[i];
NSString * attributeName = [NSString stringWithUTF8String:property_getName(property)];
NSLog(@"%@", attributeName);
if ([attributeName isEqualToString:@"msgColumnTextView"]) {
id currentObject = self.msgInputB
[currentObject setValue:@"text" forKeyPath:@"msgColumnTextView.text"];
UITextView * textView = [currentObject valueForKey:@"msgColumnTextView"];
[textView becomeFirstResponder];
这样 就完成了我们的目的、、、哈哈、
Screen Shot
at 下午7.37.28.png
遇到问题不要逃避、换个角度去思考,首先我们认识到了思维的重要性,然后我们要学会怎么去合理的使用运行时来帮我们完成事情。 这只是一个最简单的例子。 运行时庞大到可以操作任何你想要的存在的对象, 加油吧。 欢迎一起讨论。 喜欢请Mark 哈哈、
相见不如怀念。
距离产生美。
钱花哪儿哪儿好。2016年4月 移动开发大版内专家分月排行榜第二
2017年8月 移动开发大版内专家分月排行榜第三2016年7月 移动开发大版内专家分月排行榜第三2015年12月 移动开发大版内专家分月排行榜第三
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。融云IMKit的简单使用 - 简书
融云IMKit的简单使用
写在前面融云是一个比较强大的第三方框架,为我们提供了即时通讯的基本组件,导入SDK,进行一些简单的配置就可以看到会话列表,会话界面,为我们省去了很多工作(IMKit)。IMKit对于要求不是很高,不需要很多自定义(也就是很多奇形怪状的东西)的产品来说已经够用了。下面是我使用到的IMKit的一些简单功能,做一下分享。
在使用之前,当然需要一个应用,这不需要多说了,去注册一个融云开发者账号,然后创建一个应用吧。
上午11.56.58.png
0.导入SDK有两种方式可以将 SDK 导入您的项目中:通过 CocoaPods 管理依赖;手动导入 SDK 并管理依赖;
是目前最流行的 Cocoa 项目库依赖管理工具之一,考虑到便捷与项目的可维护性,我们更推荐您使用 CocoaPods 导入并管理 SDK。使用 CocoaPods 导入 SDK1、 CocoaPods 安装如果您的机器上已经安装了 CocoaPods,直接进入下一步即可。如果您的网络已经翻墙,在终端中运行如下命令直接安装:sudo gem install cocoapods
如果您的网络不能翻墙,可以通过淘宝的
进行安装。在终端依次运行以下命令:gem sources --add
gem install cocoapods
2、 查询 CocoaPods 源中的融云 SDK在终端中运行以下命令:pod search RongCloudIM
命令截图您可以看到,融云在 CocoaPods 上提供了三种 SDK 下载,IMLib、不包含VoIP功能的 IMKit、包含 VoIP 功能的 IMKit,您按照您的需求安装选择其中一个即可。如果运行以上命令,没有搜到融云的 SDK 或者搜不到最新的 SDK 版本,您可以运行以下命令,更新一下您本地的 CocoaPods 源列表。pod repo update
3、 使用 CocoaPods 导入融云 SDK在您的工程根目录下新建一个 Podfile 文件,在文件中输入以下内容。(在此以 2.4.0 版本为例,其中 “MyApp” 为自己工程名)target 'MyApp' dopod 'RongCloudIMKit', '2.4.0'end
然后在终端中运行以下命令:pod install
完成后,CocoaPods 会在您的工程根目录下生成一个 .xcworkspace 文件。您需要通过此文件打开您的工程,而不是之前的 .xcodeproj。请不要在 Podfile 中同时引用 IMKit 和 IMLib,因为 CocoaPods 中的 IMKit 包中已经包含了 IMLib 的内容,重复引用会导致无法正常编译。CocoaPods 使用说明指定 SDK 版本CocoaPods 中,有几种设置 SDK 版本的方法。如:'&= 2.4.X' 会根据您本地的 CocoaPods 源列表,导入不低于 2.4.X 版本的 SDK。'~& 2.4.X' 会根据您本地的 CocoaPods 源列表,介于 2.4.X~2.5.0 之前版本的 SDK。
我们建议您锁定版本,便于团队开发。如,指定 2.4.X 版本。pod 'RongCloudIMKit', '2.4.X'
升级工程的 SDK 版本更新您工程目录中 Podfile 指定的 SDK 版本后,在终端中执行以下命令。pod update
清除 CocoaPods 本地缓存特殊情况下,由于网络或者别的原因,通过 CocoaPods 下载的文件可能会有问题。这时候您可以删除 CocoaPods 的缓存(~/Library/Caches/CocoaPods/Pods/Release 目录),再次导入即可。查看当前使用的 SDK 版本您可以在 Podfile.lock 文件中看到您工程中使用的 SDK 版本。
这是我直接贴的融云开发文档,很简单咯。
手动导入:
下午12.02.19.png
就是这个文件夹了,拖到你的工程里,就这么简单。还有一些简单的配置:---添加系统依赖库AssetsLibrary.frameworkAudioToolbox.frameworkAVFoundation.frameworkCFNetwork.frameworkCoreAudio.frameworkCoreGraphics.frameworkCoreLocation.frameworkCoreMedia.frameworkCoreTelephony.frameworkCoreVideo.frameworkImageIO.frameworklibc++.tbdlibc++abi.tbdlibsqlite3.tbdlibstdc++.tbdlibxml2.tbdlibz.tbdMapKit.frameworkOpenGLES.frameworkQuartzCore.frameworkSystemConfiguration.frameworkUIKit.frameworkPhotos.framework有点多,耐心点吧。
---在 Xcode 项目 Build Settings -& Other Linker Flags 中,增加"-ObjC"。
--- 设置 App 支持 httpiOS 9 中,Apple 引入了新特性 App Transport Security (ATS),默认要求 App 必须使用 https 协议。详情:融云 SDK 在 iOS9 上需要使用 http,您需要设置在 App 中使用 http。在 App 的 Info.plist 中添加 NSAppTransportSecurity
类型Dictionary。在 NSAppTransportSecurity下添加 NSAllowsArbitraryLoads 类型 Boolean,值设为 YES。
好了,导入成功,配置完成!
1.登录融云---初始化在你需要使用融云 SDK 功能的类中,import 相关头文件。
#import &RongIMKit/RongIMKit.h&
如果是 Swift 的话,需要在你工程的 Bridging-Header.h文件中加入 SDK 的引用。
#import &RongIMKit/RongIMKit.h&
之前从融云开发者控制台注册得到的 App Key,现在要用上了。Objective-C 代码
[[RCIM sharedRCIM] initWithAppKey:@"YourTestAppKey"];
Swift 代码
RCIM.sharedRCIM().initWithAppKey("YourTestAppKey")
--- 获取token必须在服务器端请求 Token,因为获取 Token 时需要提供 App Key 和 App Secret。如果在客户端请求 Token,假如 App 代码一旦被反编译,则会导致 App Key和App Secret 泄露。这一步就要向你自己的服务端请求token了,这个服务端的同学会做好,然后给你一个接口,你去请求就OK了。不多说。调试阶段,服务端的同学还没写好接口,所以就先弄个假的吧
下午2.03.40.png
这个API调试,获取token
下午2.12.17.png
这下面填上用户ID和昵称就提交就获取到了。
---连接融云服务器获取token成功后,就可以用这个token连接融云服务器了,So easy!Objective-C 代码
[[RCIM sharedRCIM] connectWithToken:@"YourTestUserToken" success:^(NSString *userId) {
NSLog(@"登陆成功。当前登录的用户ID:%@", userId);
} error:^(RCConnectErrorCode status) {
NSLog(@"登陆的错误码为:%d", status);
} tokenIncorrect:^{
//token过期或者不正确。
//如果设置了token有效期并且token过期,请重新请求您的服务器获取新的token
//如果没有设置token有效期却提示token错误,请检查您客户端和服务器的appkey是否匹配,还有检查您获取token的流程。
NSLog(@"token错误");
RCIM.sharedRCIM().connectWithToken("YourTestUserToken",success: { (userId) -& Void in
print("登陆成功。当前登录的用户ID:\(userId)")
}, error: { (status) -& Void in
print("登陆的错误码为:\(status.rawValue)")
}, tokenIncorrect: {
//token过期或者不正确。
//如果设置了token有效期并且token过期,请重新请求您的服务器获取新的token
//如果没有设置token有效期却提示token错误,请检查您客户端和服务器的appkey是否匹配,还有检查您获取token的流程。
print("token错误")
一般登录操作写在AppDelegate里面就可以了,在登陆成功后如果要跳转到某个控制器的话,记得回到主线程哦,不然会很卡很卡
// 在主线程更新UI
dispatch_sync(dispatch_get_main_queue(), ^(){
// 就是这里去跳转啊,刷新UI啊!
2.会话列表用IMKit,就是简单到不要不要的,直接用RCConversationListViewController 或者继承它创建一个控制器一个列表就出现了。我是继承RCConversationListViewController创建了一个控制器,再设置一些属性就OK了。Objective-C 代码:
//重写显示相关的接口,必须先调用super,否则会屏蔽SDK默认的处理
[super viewDidLoad];
//设置需要显示哪些类型的会话,会话类型有很多,选择你需要的就好啦
[self setDisplayConversationTypes:@[@(ConversationType_PRIVATE), @(ConversationType_DISCUSSION), @(ConversationType_CHATROOM), @(ConversationType_GROUP), @(ConversationType_APPSERVICE), @(ConversationType_SYSTEM)]]; //设置需要将哪些类型的会话在会话列表中聚合显示
[self setCollectionConversationType:@[@(ConversationType_DISCUSSION), @(ConversationType_GROUP)]];}
Swift 代码:
//重写显示相关的接口,必须先调用super,否则会屏蔽SDK默认的处理
super.viewDidLoad()
//设置需要显示哪些类型的会话
self.setDisplayConversationTypes([RCConversationType.ConversationType_PRIVATE.rawValue, RCConversationType.ConversationType_DISCUSSION.rawValue, RCConversationType.ConversationType_CHATROOM.rawValue, RCConversationType.ConversationType_GROUP.rawValue, RCConversationType.ConversationType_APPSERVICE.rawValue, RCConversationType.ConversationType_SYSTEM.rawValue])
//设置需要将哪些类型的会话在会话列表中聚合显示
self.setCollectionConversationType([RCConversationType.ConversationType_DISCUSSION.rawValue, RCConversationType.ConversationType_GROUP.rawValue])
就是这么简单, 一个会话列表就设置好了,当然是很原生态的了.会话列表嘛,肯定要显示用户名、昵称和头像的,userInfoDataSource 和 groupMemberDataSource两个代理会为我们完美的解决显示用户信息的问题。设置代理:
[RCIM sharedRCIM].userInfoDataSource = AppD
[RCIM sharedRCIM].groupMemberDataSource = AppD
实现代理方法:
- (void)getUserInfoWithUserId:(NSString *)userId completion:(void (^)(RCUserInfo *))completion {
NSLog(@"Rong cloud userID: %@", userId);
RCUserInfo *user = [[RCUserInfo alloc] initWithUserId:userId
name:userName
portrait:userPortrait];
return completion(user);
当需要显示用户信息的时候,IMKit自己会走这个方法去查询用户信息,然后显示在适当的位置。不要傻傻的像上面那么写,然后还问怎么没显示,当然不显示了,用户的信息融云的服务器不会帮你存的,在这里要去请求自己的服务器,根据userID查到用户的信息然后赋值 ,return completion(user);
去融云控制台调试一下吧,还是那个API调试,
下午2.04.38.png
在下面填上发送者的ID,接收者的ID,发几条试试,收到消息的感觉有没有很爽~
要做一些实质性的工作了!我们这个项目呢,需要在消息列表的页面顶端做一个通知的cell,它永远置顶,SDK原生的列表当然没有这个了,还好,是置顶的。列表嘛,当然还是个tableView,tableView的所有控件当然还在,所以这个置顶的cell简单了,做成headerView 就OK啦!
@interface ConversationListVC ()
@property (nonatomic, strong) ConversationListHeaderView *tableHeaderV
- (UIView *)tableHeaderView {
if (!_tableHeaderView) {
_tableHeaderView = [[ConversationListHeaderView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, SCALE6P(206))];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(headerViewTapped:)];
[_tableHeaderView addGestureRecognizer:tap];
return _tableHeaderV
ConversationListHeaderView 这是我自己写的一个view啦,不用在贴代码了哦!
self.conversationListTableView.tableHeaderView = self.tableHeaderV //设置tableView头部
self.conversationListTableView.tableFooterView = [UIView new];//这样就不会显示多余的分割线啦
self.conversationListTableView.backgroundColor = [UIColor clearColor];// 背景色嘛,clearColor尽量不要用哦,为什么?自行百度!
self.conversationListTableView.layoutMargins = UIEdgeInsetsZ
self.conversationListTableView.separatorInset = UIEdgeInsetsZ
self.topCellBackgroundColor = [UIColor blueColor]; // 置顶的消息背景颜色,不设置的话会有淡淡的蓝色
上面是对“conversationListTableView”的一些设置,这时候会话列表会看起来更舒服一些。刚刚提到了置顶,当然还会有标为已读,标为未读,删除这些需求了,怎么办?tableView嘛,直接去实现代理方法就好了
- (NSArray&UITableViewRowAction *& *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
RCConversationModel *model = self.conversationListDataSource[indexPath.row];
UITableViewRowAction *deleteRoWAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"删除" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
[[RCIMClient sharedRCIMClient] removeConversation:ConversationType_PRIVATE targetId:model.targetId];
[self refreshConversationTableViewIfNeeded];
UITableViewRowAction *readRoWA
if (model.unreadMessageCount & 0) {
readRoWAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"标为已读" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
[[RCIMClient sharedRCIMClient] clearMessagesUnreadStatus:ConversationType_PRIVATE targetId:model.targetId];
[self refreshConversationTableViewIfNeeded];
readRoWAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"标为未读" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
[[RCIMClient sharedRCIMClient] setMessageReceivedStatus:model.lastestMessageId receivedStatus:ReceivedStatus_UNREAD];
[self refreshConversationTableViewIfNeeded];// 刷新tableView
UITableViewRowAction *topRoWA
if (model.isTop) {
topRoWAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"取消置顶" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
[[RCIMClient sharedRCIMClient] setConversationToTop:1 targetId:model.targetId isTop:NO];
[self refreshConversationTableViewIfNeeded];
topRoWAction.backgroundColor = HighlightC// 设置成你喜欢的颜色
topRoWAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"置顶" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
[[RCIMClient sharedRCIMClient] setConversationToTop:1 targetId:model.targetId isTop:YES];
[self refreshConversationTableViewIfNeeded];
topRoWAction.backgroundColor = HighlightC
return @[deleteRoWAction, readRoWAction, topRoWAction];
我做的好像有点简单粗暴,哪位有好方法要告诉我哦!
--- 改变一下cell的样子,我们这个基本没改变什么,只是置顶的时候我们需要一个小标志,我就在这里直接改了
- (void)willDisplayConversationTableCell:(RCConversationBaseCell *)cell atIndexPath:(NSIndexPath *)indexPath {//cell将要显示的时候会走这里,在这里做一些微调当然是可以的了,一定要注意要写 super *******
[super willDisplayConversationTableCell:cell atIndexPath:indexPath];
RCConversationModel *model = self.conversationListDataSource[indexPath.row];
NSLog(@"title : %@", model.conversationTitle);
RCConversationCell *conversationCell = (RCConversationCell *)
cell.layoutMargins = UIEdgeInsetsZ
// 置顶设置
if (model.isTop) {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width - SCALE6P(39), 0, SCALE6P(39), SCALE6P(45))];
imageView.image = [UIImage imageNamed:@"Top_trangle_image"];
imageView.tag = TOP_CONVERSATION_IMAGE_VIEW_TAG;
[conversationCell.contentView addSubview:imageView];
RCUserInfo *userInfo = [[RCIM sharedRCIM] getUserInfoCache:model.targetId];
for (UIView *view in conversationCell.contentView.subviews) {
// 这里改了一下下字体哦~
if ([view isKindOfClass:UILabel.class]) {
UILabel *label = (UILabel *)
label.font = MainFontOfSize(label.font.pointSize);
if (label.x & conversationCell.contentView.width / 2) {
if (label.y & conversationCell.contentView.height / 3) {
label.textColor = LabelTextDarkGrayC
label.font = MainFontOfSize(SCALE6P(40));
label.textColor = LabelTextLightGrayC
label.font = MainFontOfSize(SCALE6P(34));
label.textColor = LabelTextLightGrayC
label.font = MainFontOfSize(SCALE6P(32));
// 非置顶设置
if (!model.isTop && [view isKindOfClass:UIImageView.class] && view.tag == TOP_CONVERSATION_IMAGE_VIEW_TAG) {
[view removeFromSuperview];
[cell layoutIfNeeded];
在会话列表中,收到新消息的回调
@param notification
收到新消息的notification
@discussion SDK在此方法中有针对消息接收有默认的处理(如刷新等),如果您重写此方法,请注意调用super。
notification的object为RCMessage消息对象,userInfo为NSDictionary对象,其中key值为@"left",value为还剩余未接收的消息数的NSNumber对象。
- (void)didReceiveMessageNotification:(NSNotification *)notification {
[super didReceiveMessageNotification:notification];
点击Cell头像的回调
@param model
会话Cell的数据模型
- (void)didTapCellPortrait:(RCConversationModel *)model {
长按Cell头像的回调
@param model
会话Cell的数据模型
- (void)didLongPressCellPortrait:(RCConversationModel *)model {
点击会话列表中Cell的回调
@param conversationModelType
当前点击的会话的Model类型
@param model
当前点击的会话的Model
@param indexPath
当前会话在列表数据源中的索引值
@discussion 您需要重写此点击事件,跳转到指定会话的聊天界面。
如果点击聚合Cell进入具体的子会话列表,在跳转时,需要将isEnteredToCollectionViewController设置为YES。
- (void)onSelectedTableRow:(RCConversationModelType)conversationModelType
conversationModel:(RCConversationModel *)model
atIndexPath:(NSIndexPath *)indexPath {
ConversationVC *conversationVC = [[ConversationVC alloc] init];
conversationVC.conversationType = model.conversationT
conversationVC.targetId = model.targetId;
conversationVC.navigationItem.title = model.conversationT
[self.navigationController pushViewController:conversationVC animated:YES]; // 进入聊天界面了
[self.conversationListTableView cellForRowAtIndexPath:indexPath].selected = NO;
还有一些小设置,更简单了
直接到头文件里看一看,都是中文,一目了然,这里就不多说了~
3.会话界面要发送消息了
就要去聊天界面了,这里更是So easy!上面点击会话列表cell的回调中进入的那个聊天界面,就是继承RCConversationViewController 的一个控制器——ConversationVC,甚至什么都不用做,就这么push进来了!就可以发消息了!就可以看到收到的消息了!(此时感叹融云SDK的开发者们真的都是神级的任务啊)
输入框中内容发生变化的回调
@param inputTextView 文本输入框
@param range
当前操作的范围
@param text
插入的文本
- (void)inputTextView:(UITextView *)inputTextView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
[super inputTextView:inputTextView shouldChangeTextInRange:range replacementText:text];
扩展功能板的点击回调
@param pluginBoardView 输入扩展功能板View
@param tag
输入扩展功能(Item)的唯一标示
- (void)pluginBoardView:(RCPluginBoardView*)pluginBoardView clickedItemWithTag:(NSInteger)tag {
[super pluginBoardView:pluginBoardView clickedItemWithTag:tag];
开始录制语音消息的回调
- (void)onBeginRecordEvent {
[super onBeginRecordEvent];
#pragma mark 点击头像
- (void)didTapCellPortrait:(NSString *)userId {
#pragma mark 点击头像
- (void)didLongPressCellPortrait:(NSString *)userId {
点击Cell中URL的回调
@param url
@param model 消息Cell的数据模型
- (void)didTapUrlInMessageCell:(NSString *)url
model:(RCMessageModel *)
点击Cell中电话号码的回调
@param phoneNumber 点击的电话号码
@param model
消息Cell的数据模型
- (void)didTapPhoneNumberInMessageCell:(NSString *)phoneNumber
model:(RCMessageModel *)
不贴代码了,进入头文件看一吧,基本功能都能实现了。
4.消息缓存刚刚用了IMKit不久,一直不知道缓存去哪了,怎么才能在断网的时候显示聊天记录呢?当然不用,自己去写缓存啦,SDK为我们做好了,怎么显示?还记得连接融云服务器的方法么?在我们服务端获取token成功之后我们会去连接融云的服务器,断网的时候当然我们不能获取到token了。我们需要在获取token成功之后缓存一下这个token,
[NSUserDefaults standardUserDefaults] setObject:token forKey:KRongCloudToken];
再次登录的时候,如果获取token失败了,那在登录失败的方法中用缓存的token连接融云服务器,
[[RCIM sharedRCIM] connectWithToken:KRongCloudToken success:^(NSString *userId) {
NSLog(@"登陆成功。当前登录的用户ID:%@", userId);
} error:^(RCConnectErrorCode status) {
NSLog(@"登陆的错误码为:%d", status);
} tokenIncorrect:^{
NSLog(@"token错误");
不要怀疑,写上这一段代码,然后呢
缓存消息没出现啊。。。。当然不会出现,要告诉SDK取哪个用户的缓存信息啊!
[[RCIM sharedRCIM] connectWithToken:KRongCloudToken success:^(NSString *userId) {
[RCIM sharedRCIM].userInfoDataSource = (id&RCIMUserInfoDataSource&)[UIApplication sharedApplication].
RCUserInfo *currentUserInfo = [[RCUserInfo alloc] initWithUserId:model.userID
name:[model acquireParentBabyName]
portrait:model.userHeadImage];
[RCIM sharedRCIM].currentUserInfo = currentUserI//告诉SDK当前是哪个用户登录就好了,用户信息是你之前缓存的哦~
} error:^(RCConnectErrorCode status) {
} tokenIncorrect:^{
此时,缓存的聊天消息在断网的情况下也出现了,但是看着很别扭,只有聊得记录,却不显示用户的头像和昵称,别担心,你看到这篇分享的时候下载的SDK版本已经做好了用户信息的缓存,在AppDelegate里面设置一下就看到完整的信息了
[RCIM sharedRCIM].enablePersistentUserInfoCache = YES;
缓存就这些吧,其实什么都不用做,设置一下就好了~
5.消息推送收到消息之后要通知用户啊,这就需要远程推送了。不知道你的项目之前有没有用到其他的推送,我们的项目在做聊天之前用了极光推送。极光推送和聊天消息推送是不冲突的,一起存在当然没问题。如果你的项目之前没有做远程推送,那么就需要先去开发者账号中申请推送证书了,怎么申请?这个。。。自行百度吧,融云的文档中也有,很详细。
下午3.18.43.png
上传好证书,在AppDelegate中设置一下就OK~码这么多字,,,不想码了直接去文档看吧,真的很详细!具体可以参考。
结尾~一些小设置~
[RCIM sharedRCIM].globalConversationAvatarStyle = RC_USER_AVATAR_CYCLE; // 列表页头像的形状,我设置成了圆形
[RCIM sharedRCIM].globalConversationPortraitSize// 列表页头像的大小,默认是46*46
[RCIM sharedRCIM].globalMessageAvatarStyle // 聊天界面头像的形状
[RCIM sharedRCIM].globalMessagePortraitSize // 聊天界面头像的大小默认是40*40
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"Arrow_back_white"] style:UIBarButtonItemStylePlain target:self action:@selector(returnBtnTapped:)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Clear_all_messages"] style:UIBarButtonItemStylePlain target:self action:@selector(clearAllMessage:)];
[self.navigationController.navigationBar setBackgroundImage:[CommonTool imageWithColor:ThemeColor] forBarMetrics:UIBarMetricsDefault];//这都是系统方法喽
还有发送位置和发送照片的时候navigation的颜色有点不太对,我是在AppDelegate里面统一设置的
[[UINavigationBar appearance] setBarTintColor:ThemeColor];
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
[[UINavigationBar appearance] setTitleTextAttributes:@{ NSForegroundColorAttributeName : [UIColor whiteColor], NSFontAttributeName : “YouFont”}];
码了半个下午,以后遇到什么了会继续补充~
一只稍微有点文艺情怀的代码喵

我要回帖

更多关于 svn服务器端下载 的文章

 

随机推荐