简介
用户信息一般都要用,一般一开始从网络读取,然后就缓存起来,随用随取。
缓存类型选择
可以用磁盘缓存,没有问题;
也可以用内存缓存。APP重启之后,就应该从网络去取,时间太长,大概率会有修改,需要更新一下。本次就存在内存缓存中
单例
内存缓存,一般用单例来表示
习惯上,单例都会取名XXXManager
Swift的单例网上有好多种写法,选择了最简单的一种
// MARK: - 单例
final class UserServiceManager {
/// 单例实例
/// UserServiceManager.sharedInstance.就是单例的用法
static let sharedInstance = UserServiceManager()
}
静态方法
直接调用单例,一般都有XXX.sharedInstance.的样子,感觉有点啰嗦,所以考虑再封装一层,提供静态方法,直接XXX.就可以了
封装方式
OC一般分开两个文件,但是Swift感觉只要一个文件就可以了
对外的接口用struct,命名用XXXService;单例用class,放在同一个文件中,命名为XXXServiceManager
单例XXXServiceManager相当于具体实现,结构体XXXService相当于对外接口
所以访问参数,单例用fileprivate,结构体用public
import Foundation
// MARK: - 公共接口
struct UserService {
/// 判断用户信息是否为空
public static func isUserInfoNotEmpty() -> Bool {
if let userInfo = getUserInfo(), let userId = userInfo.userId {
return (userId > 0)
} else {
return false
}
}
/// 保存用户信息;设置为nil,就是清空
public static func saveUserInfo(_ userInfo: UserInfoModel?) {
UserServiceManager.sharedInstance.saveUserInfo(userInfo)
}
/// 读取用户信息
public static func getUserInfo() -> UserInfoModel? {
return UserServiceManager.sharedInstance.getUserInfo()
}
}
// MARK: - 单例
final class UserServiceManager {
/// 单例实例
/// UserServiceManager.sharedInstance.就是单例的用法
fileprivate static let sharedInstance = UserServiceManager()
// MARK: - 接口
fileprivate func saveUserInfo(_ userInfo: UserInfoModel?) {
self.userInfo = userInfo
}
fileprivate func getUserInfo() -> UserInfoModel? {
return self.userInfo
}
// MARK: - 属性
private var userInfo: UserInfoModel? = nil
}
存取方法
默认从缓存中取就可以了,
如果缓存中没有,那么就需要访问网络,
如果怀疑有更新,不想取缓存中的值,直接访问网络,那么就提供一个参数useCache来控制
每次网络数据返回,如果不为空,就缓存在内存缓存中,随时备用
/// User模块接口封装
struct UserApi {
/// 获取用户信息;默认从内存缓存取;缓存没有,才访问网络;useCache = false, 从网络取
public static func asyncGetUserInfo(useCache: Bool = true) async -> UserInfoModel? {
if (useCache && UserService.isUserInfoNotEmpty()) {
return UserService.getUserInfo()
} else {
let moYaModel = await MoyaNetworkManager.sharedInstance.asyncRequest(command: .userGetUserInfo)
if let userInfo = UserInfoModel.deserialize(from:moYaModel.data as? Dictionary<String, Any>) {
/// 保存到内存中缓存起来
UserService.saveUserInfo(userInfo)
return userInfo
} else {
return nil
}
}
}
}
使用
使用的时候,不需要关心数据来自哪里,直接用就好了。如果想更新,通过useCache控制一下就可以了
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: animated)
Task {
if let data = await UserApi.asyncGetUserInfo(useCache: true) {
debugPrint(data)
}
}
}