NSKeyedArchiver缓存app用户账号数据

某些app用户只需要登录一次,退出app再次打开后还是保持登录状态。实现这个需求,用脚趾头都能想到用户账号数据已经做了持久化处理,那么怎么做的呢?今天我就写一篇笔记,给没有经验的朋友参考。

iOS的存储方式

NSKeyedArchiver:使用归档保存数据需要遵守NSCoding协议,并且该对象对应的类必须提供encodeWithCoder:initWithCoder:方法。前一个方法告诉系统怎么对对象进行编码,而后一个方法则是告诉系统怎么对对象进行解码。

NSUserDefaults:偏好设置用于保存一些简单数据,比如app里一些设置数据、状态。NSUserDefaults可以存储的数据类型包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。如果要存储其他类型,则需要转换为前面的类型,才能用NSUserDefaults存储。

Write:直接将对象永久写入到本地磁盘中,一些类自带写入属性。比如UIImage、NSString等,或者使用NSFileManager进行文件操作。

SQLite:采用数据库的形式存储数据,iOS中使用SQLite来存储一些数据量比较大的数据。比如新闻资讯类的app实现本地数据缓存,大都是采用数据库形式存储。数据库存储相比前面三种存储方式来说,相对比较复杂一些,但对大量数据进行缓存管理还是得需要数据库的。

需求分析

首先我们要明确一点,我们实现用户数据缓存的目的是保持用户的登录状态和数据(由于本人垃圾,所以这里不考虑用户数据隐私)。

一般app里我们都会定义一个用户账号类来管理用户数据,然后让这个类的对象能够一直保存在内存中,被整个app共享,并且修改了用户数据也要及时更新(更新本地数据、异步上传更新服务端的用户数据)。然后提供登录后的初始化操作方法和注销登录后的清理方法,在登录后就将数据缓存,退出后清除用户数据。

并且,一般后台会提供一个token字段和token有效期字段,用于判断用户登录状态是否有效。如果token失效,则清理用户数据。

代码实现

这里我就以最近写的一个 六阿哥客户端 app为例,创建账号类JFAccountModel,并声明一堆用户相关的属性,并提供一个转模型的构造方法:

遵守协议实现归档和解档方法:

定义一个私有的静态属性用于持久保存JFAccountModel对象在内存中:

创建归档JFAccountModel对象的路径,一般都是保存在沙盒中的Document目录下:

归档JFAccountModel的方法:

登录成功后保存JFAccountModel的方法:

这里我们来模拟登录,发送登录请求:

在登录成功后调用上面的 updateUserinfo() 方法进行更新本地缓存数据。

退出登录后的清理工作,因为我这里也使用了第三方登录,所以在退出登录的同时取消授权:

至此,从登录成功并归档账号数据,到退出后清理归档和内存中的账号数据就做完了。

补充完善

上面只是实现了基本的用户数据归档和清理,但是这样的还不够。比如,开头我们说到的让JFAccountModel对象能够给整个app共享,我们什么时候去登录有效期处理,在进行一些用户操作的时候判断当前用户是否是登录状态。这些我们都可以封装在JFAccountModel用户类里面的。

我这里的做法是,在app启动的时候去判断是否已经登录,首先我们需要提供一个方法来让JFAccountModel对象能够被app共享:

调用上面的方法,如果返回不为nil,则说明已经登录,并获取到了JFAccountModel对象。我们再提供一个便捷的方法直接判断用户是否已经登录:

app启动时在appDelegatedidFinishLaunchingWithOptions方法中去判断当前用户信息是否有效:

这个方法也可以作为更新本地用户信息的方法,比如用户在其他手机上的app登录过后的一些数据改变,我们需要去更新同步这些数据。当然,还有一种情况,也就是没有网络或者网络差的情况,直接去调用这个方法会导致清空本地用户数据,这个可以根据自己的需求去变通。比如判断请求结果,根据不同情况去处理,或者判断当前网络状态,无网络情况不去更新用户信息。

这只是举一个栗子,真正做项目的时候还是得根据后端api返回的具体数据去具体分析的,比如我们这里将用户登录有效期和更新用户信息给写成一个方法了,因为我对用户是否是真的登录,要求并不是很高。就算登录失效,本地用户的数据也是可以用的。只是在调用一些接口的时候,需要传递token,这个时候可能传递错误的token,后台就会返回对应错误码给你,你再去针对处理就行。一些对用户安全性要求比较低的app,可能根本就没有token字段,或者有token字段但没有token有效期。

下一篇继续讲解缓存,使用SQLite缓存本地数据。

六阿哥

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: