背景
咱们在设计聊天类 APP 都会有一套残缺的用户信息存储机制,用来保留咱们的通讯录列表,以及每个用户的头像、昵称、姓名、等等一系列的用户信息,避免咱们过多的进行服务器申请,对用户体验很差。这篇文章就简略的给大家创立一套用户信息机制来提供一个简略的思路。
场景如下:
目前咱们集成了融云的 IMLib SDK , 融云 IMLib SDK 仅提供了音讯数据的存储与查问。用户信息和 UI 界面须要咱们本人来保护,而融云的 IMKit 尽管提供了用户信息的治理,然而局部 UI 还是和咱们产品设计不符的,那么如何设计一套相似于 IMKit 的用户信息管理机制,就是咱们面临的问题。
融云 SDK:
https://docs.rongcloud.cn/v4/
思考
咱们在实现这套机制的时候都须要哪些内容?
- 首先咱们要进行存储,存储那就须要保护一个数据库。参考融云 IMKit 发现有上面一个配置
/*!
是否将用户信息和群组信息在本地长久化存储,默认值为 NO
@discussion
如果设置为 NO,则 SDK 在须要显示用户信息时,会调用用户信息提供者获取用户信息并缓存到 Cache,此 Cache 在 App 生命周期完结时会被移除,下次启动时会再次通过用户信息提供者获取信息。如果设置为 YES,则会将获取到的用户信息长久化存储在本地,App 下次启动时 Cache 会依然无效。*/
@property (nonatomic, assign) BOOL enablePersistentUserInfoCache;
通过测试以及融云业余技术人员的答复,发现这个配置起到的作用就是本次的用户信息是否会进行数据库存储。
这里的数据库存储是指当此配置失效时,会在本地进行数据库文件的创立。而不失效的时候,是不创立的。如果不创立的话还须要存储的话,那应该就是存储到内存了。而咱们是须要每次登陆都有一些用户信息的,那不须要应用内存了,须要咱们进行数据库存储,所以咱们须要筹备一个 db 的治理类,解决所有的数据库操作。
- 须要一个整体治理用户信息的入口 manager,用来整顿一些根本信息。以及提供用户信息管理的代理入口。
- 须要存储哪些用户信息以及筹备对用的 model 类。
- 筹备每种对象的缓存类。
实现
以 融云 SDK 为例,以一个用户的 userinfo 为例大体来绘制一下整个流程图。
首先整顿一些各个类的用途,大体内容如下:
UserInfoDBHelper: 数据库治理
#import <Foundation/Foundation.h>
#import "UserInfo.h"
NS_ASSUME_NONNULL_BEGIN
@interface UserInfoDBHelper : NSObject
- (void)createDB;
- (UserInfo *)getUserInfo:(NSString *)userId;
- (void)refreshUserInfo:(UserInfo *)userInfo;
@end
NS_ASSUME_NONNULL_END
UserInfo: 用户信息模型
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface UserInfo : NSObject
/**
id
name
url
*/
@end
NS_ASSUME_NONNULL_END
UserInfoCache: 用户信息读取类
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface UserInfoCache : NSObject
- (UserInfo *)getUserInfo:(NSString *)userId;
- (void)refreshUserInfo:(UserInfo *)userInfo;
@end
NS_ASSUME_NONNULL_END
UserInfoManager: 对外入口
#import <Foundation/Foundation.h>
#import "UserInfo.h"
NS_ASSUME_NONNULL_BEGIN
@protocol UserInfoDelegate <NSObject>
- (void)getServerUserInfo:(NSString *)userid;
@end
@interface UserInfoManager : NSObject
@property (nonatomic, weak) id<UserInfoDelegate> delegate;
- (UserInfo *)getUserInfo:(NSString *)userid;
- (void)refreshUserInfo:(UserInfo *)userInfo;
@end
NS_ASSUME_NONNULL_END
此处提供了一个简略的流程图,供大家参考
解析:
- 首先用户登录,
- 绘制 UI,同时依据用户的 id 来调用 manager.getuserinfo。
- manager 会调用用户的 cache 类来获取 db 内的用户信息。
- 在 cache 调用的时候如果你进行了内存缓存则先在内存缓存中进行查找,而后调用 db.get 进行查找
- db 在首次应用的时候会进行数据库文件查看,不存在则创立并间接用户信息返回空。而后调用
manager 的 delegate 获取用户信息,再拿到用户信息后发送告诉来刷新 UI。
6. 如果已创立的间接调用 db 的 get。而后刷新 UI。
整体先只提供了一个思路,具体外面的一些外部优化还需实际。
可能用到的技术点:
- SQL 的应用
- 单例类的应用
- GCD 队列
- 告诉
- 代理
- 如果应用内存缓存的话还须要保障线程平安。
整体的一个简略思路就是下面供大家参考,待我写完再分享整体代码给大家。