easeui第三方 ios
2018-03-26 18:30:34 asd63119 阅读数 379

背景

去年曾为了项目的一个即时通信功能集成过环信,因为考虑开发的低成本,就直接使用了环信的 EaseUI

环信的文档提供了很多好友管理、群聊操作的API,但当你看到下图后,这些api直接可以无视掉


所以环信当作工具来使用即可,千万别用他的后台系统(我的公司安卓那边莫名的相信环信后台,白白浪费了近两个多星期)


为什么需要优化?

因为环信的EaseUI,是根据环信自己后台开发的,所以需要让EaseUI更好地跟我们自己的后台关联起来


红色圈出来的就是我接下来所做的优化的内容

ps:一开始我以为,在拉取好友列表的时候判断好,就基本没有大碍!但是后面经测试,在聊天的过程中,如果对方把你删除,聊天依旧可以继续,所以就需要对 EaseUI 的源码开刀。


具体流程

EaseUI 使用起来十分便捷,只需要自己创建一个继承于 EaseMessageViewController 的控制器即可

接着实现 EaseMessageViewControllerDataSource 该协议的

- (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController
                           modelForMessage:(EMMessage *)message;

便可以对聊天内容的环信用户设置自定义头像和名字



接来下便开始修改他的源码:

第一步

打开 EaseUI 里面的 EaseMessageViewController.h 文件

在 EaseMessageViewControllerDelegate 下添加以下代码

/**
 * 是否需要发送这条消息  return false 将会阻止该消息的发送  - pfboy add
 *
 * @param viewController _
 * @param message 自己发送出去的消息
 * @param block 对发出去的数据的,进行校验,通过block的参数isDataRight返回数据的正确性
 *
 */
- (void) messageViewController:(EaseMessageViewController *)viewController willSendMessage:(EMMessage *)message  resultBlock:(void(^)(BOOL isDataRight)) block;

/**
 * 是否需要发送这条消息  return false 将会阻止该消息的发送  - pfboy add
 *
 * @param viewController _
 * @param message 接收到的数据
 * @param block 对接收到的数据,进行校验,通过block的参数isDataRight返回数据的正确性
 *
 */
- (void) messageViewController:(EaseMessageViewController *)viewController willReceiveMessage:(EMMessage *)message  resultBlock:(void(^)(BOOL isDataRight)) block;

这个是为了最后,我们可以在自己的 Controller 通过这两个方法,来判断发收信息的是否来自好友或者群聊

因为需要通过http请求来判断好友的真实性,所以使用block 进行控制

第二步

接着打开文件 EaseMessageViewController.m  并滑动到1721行

将原 _sendMessage 函数

- (void)_sendMessage:(EMMessage *)message
{
    if (self.conversation.type == EMConversationTypeGroupChat){
        message.chatType = EMChatTypeGroupChat;
    }
    else if (self.conversation.type == EMConversationTypeChatRoom){
        message.chatType = EMChatTypeChatRoom;
    }
    
    [self addMessageToDataSource:message
                        progress:nil];
    
    __weak typeof(self) weakself = self;
    [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {
        if (!aError) {
            [weakself _refreshAfterSentMessage:aMessage];
        }
        else {
            [weakself.tableView reloadData];
        }
    }];
}

改成以下代码

/判断该消息是否需要截断  pfboy add
- (void) _sendCorrectMessage:(EMMessage *)message{
    __weak typeof(self) weakself = self;
    [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {
        if (!aError) {
            [weakself _refreshAfterSentMessage:aMessage];
        }
        else {
            [weakself.tableView reloadData];
        }
    }];
}

// hook 这个地址
- (void) _sendMessage:(EMMessage *)message
{
    if (self.conversation.type == EMConversationTypeGroupChat){
        message.chatType = EMChatTypeGroupChat;
    }
    else if (self.conversation.type == EMConversationTypeChatRoom){
        message.chatType = EMChatTypeChatRoom;
    }
    
    [self addMessageToDataSource:message
                        progress:nil];
    
    //判断该消息是否需要截断  pfboy add
    if ([self.delegate respondsToSelector:@selector(messageViewController:willSendMessage:resultBlock:)]) {
        __weak typeof(self) weakself = self;
        [self.delegate messageViewController:self willSendMessage:message resultBlock:^(BOOL isDataRight) {
            if (isDataRight) {
                [weakself _sendCorrectMessage:message];
            }
        }];
    } else {
        // 如果没有实现该代理,则不会更改源码的流程
        [self _sendCorrectMessage:message];
    }
    
}
第三步

EaseMessageViewController.h 滑动到 1137 行将方法 statusButtonSelcted 替换成以下代码

- (void) _resendMessage:(id<IMessageModel>)model{
    __weak typeof(self) weakself = self;
    [[[EMClient sharedClient] chatManager] resendMessage:model.message progress:nil completion:^(EMMessage *message, EMError *error) {
        if (!error) {
            [weakself _refreshAfterSentMessage:message];
        }
        else {
            [weakself.tableView reloadData];
        }
    }];
    
    [self.tableView reloadData];
}

// hook 重发地址
- (void)statusButtonSelcted:(id<IMessageModel>)model withMessageCell:(EaseMessageCell*)messageCell
{
    if ((model.messageStatus != EMMessageStatusFailed) && (model.messageStatus != EMMessageStatusPending))
    {
        return;
    }
    //判断该消息是否需要截断  pfboy add
    if ([self.delegate respondsToSelector:@selector(messageViewController:willSendMessage:resultBlock:)]) {
        __weak typeof(self) weakself = self;
        [self.delegate messageViewController:self willSendMessage:model.message resultBlock:^(BOOL isDataRight) {
            if (isDataRight) {
                [weakself _resendMessage:model];
            }
        }];
    } else {
        // 如果没有实现该代理,则不会更改源码的流程
        [self _resendMessage:model];
    }
    
}

第四步

EaseMessageViewController.h 滑动到 1442 行,将 didReceiveMessages 替换成以下代码

- (void) _didReceiveMessages:(EMMessage *)message {
    [self addMessageToDataSource:message progress:nil];
    
    [self _sendHasReadResponseForMessages:@[message]
                                   isRead:NO];
    
    if ([self _shouldMarkMessageAsRead])
    {
        [self.conversation markMessageAsReadWithId:message.messageId error:nil];
    }
}
// hook 这里
- (void)didReceiveMessages:(NSArray *)aMessages
{
    for (EMMessage *message in aMessages) {
        if ([self.conversation.conversationId isEqualToString:message.conversationId]) {
            
            //判断该消息是否需要截断
            if ([self.delegate respondsToSelector:@selector(messageViewController:willReceiveMessage:resultBlock:)]) {
                __weak typeof(self) weakself = self;
                [self.delegate messageViewController:self willReceiveMessage:message resultBlock:^(BOOL isDataRight) {
                    //判断是否需要接受该数据
                    if (isDataRight) {
                        [weakself _didReceiveMessages:message];
                    }
                }];
            } else {
                // 如果没有实现该代理,则不会更改源码的流程
                [self _didReceiveMessages:message];
            }
        }
    }
}

通过以上四步,便可以在消息发送或接收前将消息截取下来,再通过protocol,返回到我们自己的控制器进行管理

最后在自己的 Controller 内,便可以将发送的消息与自己服务器的数据关联起来,实现对 EaseUI 的优化

// MARK: -EaseMessageViewControllerDelegate
func messageViewController(_ viewController: EaseMessageViewController!, willSend message: EMMessage!, resultBlock block: ((Bool) -> Void)!) {
     checkAccountCorrect(hx_account: message.conversationId) { (value) in
         block(value)
     }
}
    
func messageViewController(_ viewController: EaseMessageViewController!, willReceive message: EMMessage!, resultBlock block: ((Bool) -> Void)!) {
     checkAccountCorrect(hx_account: message.conversationId) { (value) in
         block(value)
     }
}

ps:方法 checkAccountCorrect 的内容主要与我们自己的服务器交互校验数据


本人能力有限,如果有什么更好的方法或者建议,欢迎指正

2016-09-26 17:54:00 weixin_33912246 阅读数 11
2324574-10a15c357f933d42.png

首先解释下为什么视频中同样的步骤集成不报错,视频中的集成是基于2015年10月30日的EaseUI,最新更新的2016年2月2日的版本中对3.0demo和EaseUI的代码稍作了修改,以解决之前版本中的一些小问题。但大家也不要着急,只要按视频中集成,再稍作修改即可。

先找到EaseUI-Prefix.pch,将其中的#define NSEaseLocalizedString(key, comment) [[NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"EaseUIResource" withExtension:@"bundle"]] localizedStringForKey:(key) value:@"" table:nil]这段代码拷贝到自己的pch文件下即可。

再在自己pch文件中所有代码的首尾加上#ifdef __OBJC__和#endif。

好了,问题就这样解决啦!

可以参考:

http://www.imgeek.org/question/5900

如果还报错,可能是重复库引起的,把重复的库删掉就行了。

2015-12-02 15:00:26 lct710992308 阅读数 1708

步骤1:导入sdk ,请看环信sdk集成api


步骤2:请看图


步骤3: 上面步骤会缺少表情,

表情请见3.0demo中的chatviewcontroller,

EaseEmotionManager *manager= [[EaseEmotionManager alloc] initWithType:EMEmotionDefault emotionRow:3

emotionCol:7 emotions:[EaseEmoji allEmoji]];

    [self.faceView setEmotionManagers:@[manager]];


环信集成完成

2015-11-03 16:35:25 u014084081 阅读数 392

iOS第三方开源项目分类

UI

提示

Label

Scroll View

Page Control

Controller

ImagePicker图片选择器

Webview

  • SVWebViewController:简单的内嵌浏览器。
  • TOWebViewController:在不离开当前app的情况下,快速的展示一个网页( to be able to quickly present a web page to the user, without needing to leave the current app)。

GIF动画

动画

刷新与加载

  • ODRefreshControl:类似于iOS6中的下拉刷新,有弹性的效果。
  • SVPullToRefresh:上拉加载更多(Give pull-to-refresh & infinite scrolling to any UIScrollView with 1 line of code)

AutoLayout

ReactiveCocoa

ReactiveCocoa(RAC) is a Cocoa framework inspired by Functional Reactive Programming. It provides APIs for composing and transforming streams of values over time.

2016-11-17 18:26:00 weixin_33966365 阅读数 17

1: 基于响应式编程思想ReactiveCocoa的oc
2:hud提示框
3:XML/HTML解析
4:有文字输入时,能根据键盘是否弹出来调整自身显示内容的位置
5:状态栏提示框
6:block工具包。将很多需要用delegate实现的方法整合成了block的形式
7:图片加载
8:正则表达式
9:Masonry代码布局
10: 弹出窗AlertView
11: Button的样式
12:验证网络连接状态
13:自动计算表格行高
14:动画效果的启动页
15:iOS快速简单集成国内三大平台分享
16:五项能力值展示五边形
17:自动识别网址号码邮箱和表情的label
18:IM对话功能的封装
19:字典转模型框架
20:下拉上拉刷数据
21:表格行左右划动菜单
22: 图文混搭
23: 可以简单展示在UINavigationBar下方,类似Music app的播放列表视图,弹出菜单视图
24:比如筛选、模糊、优化、蒙版、调整大小、旋转以及保存等等。同时还提供了一个UIImageView子类从URL异步加载图片,并在下载完毕时展示图片。
25:底部TabBar
26: 表情面版
27: 记录框架
28:IOS与javascript交互
29:图表统计展示
30: appStore评分
31:iOS-Categories 扩展类大全
32:扫描二维码,仿微信效果,带有扫描条
33: 动效弹出视图(弹出窗里面为文字,可以定义弹出的方向,及显示的时间)--AMPopTip
34: 基于Masonry自动计算行高扩展
35: 模仿新浪微博弹出菜单
36: 搜索历史标签
37:快速集成新手引导的类库
38:设置页面的封装
39:带箭头的弹出视图插件
40:下拉菜单插件
41:表格空白提示插件
42: 给任意UIView视图四条边框加上阴影,可以自定义阴影的颜色、粗细程度、透明程度以及位置(上下左右边框)
43: 不错的日期时间插件
44: 底部弹出选择
45: 比较不错的引导页面插件
46: 两个APP跳转的插件
47: 本地存取NSUserDefaults插件
48: NSArray 和 NSDictionary关于LINQ的操作方式,封装一些常用的操作
49: 可以监控网络请求的内容
50:时间帮助插件,可以快速获取时间,比较,增加等操作
51: 不错的链式动作
52: 弹出层视图,背景效果(可以自定义视图的内容)
53: 圆形进度条的显示,中间可显示值
54: 很帅的数据加载动画(可以用于数据列表加载的展现)
55: 一个开源的AFnetworking上层的封装(猿题库等运用)
56: CBStoreHouseRefreshControl:一个效果很酷炫的下拉刷新控件
57: AFNetworking-RACExtensions:针对ReactiveCocoa的AF封装
58: 模糊效果(毛玻璃)
59: 键盘管理器
60: 图片编辑

iOS 第三方

阅读数 7

ios 第三方 iOS SDK

阅读数 16

iOS之第三方小结

阅读数 327

iOS第三方框架推荐

阅读数 325

iOS第三方框架推荐

博文 来自: myzlhh
没有更多推荐了,返回首页