Skip to content
forked from jwfing/FreeChat

Leancloud instance message v2 sdk demo

Notifications You must be signed in to change notification settings

KieSun/FreeChat

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FreeChat

image

FreeChat 是基于 LeanCloud 实时消息服务的一个聊天 app。

感谢

首先非常感谢你下载该 Demo,如果你觉得这个项目写的不够好,非常欢迎帮助我们来不断完善(通过github pull request即可);如果你觉得有新的需求或者发现了 bug,欢迎给我们提 Issue

如何运行

下载工程之后,直接在 Xcode 中打开 FreeChat.xcodeproj 即可。换成你自己的 appId/appKey 也可以直接运行(此时因为开放聊天室没有预先建立,所以开放聊天室页面下列表为空。要预先建立开放聊天室,可以参考 LeanCloud 文档)。

注意: FreeChat 使用了 LeanCloud 最新的 CrashReporting Framework,所以编译前需要先安装 LeanCloud 用于上传符号表的客户端工具,具体方法如下: gem install --no-wrappers leancloud

功能

FreeChat 的主要功能与微信类似。主要的模块分为三块:最新消息、联系人和设置,主界面如下图所示:

image

用户选择了一个联系人之后,就可以开始对话,对话界面如下图所示:

image

在这里用户可以发送文本、图片或者语音消息。而点击右上角的图标,则可以看到对话的详情,界面如下图所示:

image

在这里用户可以邀请其他人加入群聊,也可以踢出恶意发言的人,还可以修改群聊名称和设置是否接收离线通知,以及推出当前对话。

除此之外,FreeChat 也是需要用户注册、登录的。这部分功能的实现,则是基于 LeanCloud 的数据存储服务完成的。

实现

消息响应

因为实时通信的消息是被动接收的,应用在不同的界面上都有可能收到新的消息。譬如:

  • 在「最新消息」这个页面,如果来了新的消息,那么对应的「对话」后面可能要出现提示图标;
  • 正好在对话页面的话,要是来了新的消息,就需要实时显示在消息列表中。

所以整体上我们采用了如下机制来响应新消息:

类结构设计

  • MainViewController 应用主窗口,登录之后就一直存在,实现了AVIMClientDelegate协议。它会把收到的新消息全部存入ConversationStore实例。
  • IMEventObserver 接口,应用内用来通知新消息到达或者消息被对方接收等事件。主要接口有:
- (void)newMessageArrived:(Message*)message conversation:(AVIMConversation*)conversation;
- (void)messageDelivered:(Message*)message conversation:(AVIMConversation*)conversation;
  • ConversationStore 全局单例,用来做消息缓存,并且也持有AVIMClient的实例。支持消息 Observer 的注册和取消,方法如下:
- (void)addEventObserver:(id<IMEventObserver>)observer forConversation:(NSString*)conversationId;
- (void)removeEventObserver:(id<IMEventObserver>)observer forConversation:(NSString*)conversationId;

设想使用方式如下(参照观察者模式):

  • 对于每一个希望响应新消息的 ViewController 来说,可以在viewDidAppear方法中把自己作为新消息观察者加入到ConversationStore 全局单例中;
  • viewWillDisappear方法中从ConversationStore 全局单例中删除自己这个观察者。

新消息响应时序图

总体上看,LeanCloud 实时通信云端到来的新消息,会经过如下时序反应到界面上来

LeanCloud云端    MainViewController  ConversationStore   ChatViewController(IMEventObserver)
          -- Msg -->  |                    |                       |
                      |-newMessageArrived->|                       |
                      |                    | -newMessageArrived->  |

目前主要有 ChatViewController 这一个观察者,RecentConversationViewController(最新消息)也应该作为观察者来实时响应,我现在还没有实现。

消息本地缓存

ConversationStore中会将消息缓存到本地,然后获取历史消息的时候,内部会结合本地缓存数据和 LeanCloud 云端一起来查询(本地有则从本地获取,否则走网络)。

本地消息缓存的方式如下:

  • MessagePersister协议类,支持消息 push 和 pull 两种操作;
  • SQLiteMessagePersister 采用 SQLite 方式实现的本地数据库持久化类,实现了MessagePersister协议。
  • RemoteMessagePersisiter 连接 LeanCloud 云端实现的消息持久化类,实现了MessagePersister协议(其实没有任何本地持久化,每次操作都需要走网络)。

用户账户管理

直接使用了 LeanCloud 自带的账户系统来管理,为了简单起见,也省略了用户之间的好友(follow)关系,允许用户可以和应用内任何一个注册用户聊天。

聊天界面上用户头像显示问题

由于 LeanCloud 实时通信服务是与用户账户系统解耦合的,所以对于ChatViewController 来讲,在显示每一条新消息的时候,要显示用户的信息(名字、头像或更多),就比较麻烦。因为从 sdk 里面我们只能拿到用户的 clientId,要从 clientId 再获取到用户的其他信息,可以:

  • 每次通过 AVUser 的方法去异步获取,等操作结束之后更新界面。这样做的好处是可以保证每次取得的都是最新的数据,有效避免了用户换头像、改名等操作带来的数据不一致问题,但是坏处也很明显,会带来过多的网络请求。
  • 通过一个全局的 AVUser 数据缓存来做,每次获取了新用户的信息之后就自动缓存起来,下次直接从缓存获取。这样的优缺点正好和前一种方法相反。

我们这里采用了后一种方法,因为毕竟界面显示的快速和节省流量是第一位的。方案如下:

  • UserProfile 指代界面显示时需要的全部用户信息(demo 中用到了名字和头像)
  • AVUserStore 提供带缓存的 UserProfile 异步获取接口。

消息离线通知

coming soon...

国内和美国节点

现在 LeanCloud 是支持美国节点的,FreeChat 也是确认可以在两个节点运行的。注意如下代码片段,即可在国内/美国节点之间进行切换:

file: AppDelegate.m

// 注意:如果您使用了 LeanCloud 美国节点,请保持这一行;
//      如果您使用 LeanCloud 国内节点,请注释掉这一行。
#define USE_US_CLUSTER 1

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
#ifdef USE_US_CLUSTER
    [AVOSCloud useAVCloudUS];
    [AVOSCloud setApplicationId:@"l8j5lm8c9f9d2l90213i00wsdhhljbrwrn6g0apptblu7l90"
                      clientKey:@"b3uyj9cmk84s5t9n6z1rqs9pvf2azofgacy9bfigmiehhheg"];
    NSLog(@"use us cluster");
#else
    [AVOSCloud setApplicationId:@"xqbqp3jr39p1mfptkswia72icqkk6i2ic3vi4q1tbpu7ce8b"
                      clientKey:@"cfs0hpk9ai3f8kiwua7atnri8hrleodvipjy0dofj70ebbno"];
    NSLog(@"use cn cluster");
#endif

    ...
}

第三方库

所有功能都是基于 LeanCloud 平台完成的,所以第一感谢 LeanCloud。在本项目的开发过程中,还用到了如下第三方代码,在此一并表示感谢:

  • MJRefresh 不多说,用来下拉加载更多历史消息。
  • fmdb sqlite 的 objective-c 封装,本项目中用来本地缓存历史消息。
  • UUChatTableView 非常棒的一个聊天组件库,本项目中部分用来实现聊天界面。
  • AFNetworking 不多说。
  • voiceLib 半天没有找到来路,本项目中用来语音录入及格式转化成MP3。

About

Leancloud instance message v2 sdk demo

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Objective-C 94.7%
  • C 5.3%