UserDefaults的三种优雅使用方式
第一种
实现方式
- 首先定义一个
UserDefaultsSettable
的协议
protocol UserDefaultsSettable {
associatedtype defaultKeys: RawRepresentable
static var token: String? { get }
}
- 然后对协议进行拓展
extension UserDefaultsSettable where defaultKeys.RawValue == String {
static var token: String? { return nil }
/// 对key加密
static func forKey(_ key: defaultKeys) -> String {
var string = String(format: "%@_%@", arguments: [String(describing: self),
key.rawValue])
if let token = token {
string += String(format: "_%@", token)
}
// return string.md5
return string
}
// setter
static func set(_ value: String?, forKey key: defaultKeys) {
UserDefaults.standard.set(value, forKey: forKey(key))
}
static func set(_ value: Bool, forKey key: defaultKeys) {
UserDefaults.standard.set(value, forKey: forKey(key))
}
static func set(_ value: Int, forKey key: defaultKeys) {
UserDefaults.standard.set(value, forKey: forKey(key))
}
static func set(_ value: Float, forKey key: defaultKeys) {
UserDefaults.standard.set(value, forKey: forKey(key))
}
static func set(_ value: Double, forKey key: defaultKeys) {
UserDefaults.standard.set(value, forKey: forKey(key))
}
static func set(_ value: URL?, forKey key: defaultKeys) {
UserDefaults.standard.set(value, forKey: forKey(key))
}
static func set(_ value: Any?, forKey key: defaultKeys) {
UserDefaults.standard.set(value, forKey: forKey(key))
}
static func set<T: Encodable>(model: T?, forKey key: defaultKeys) {
UserDefaults.standard.set(model: model, forKey: forKey(key))
}
/// getter
static func string(forKey key: defaultKeys) -> String? {
return UserDefaults.standard.string(forKey: forKey(key))
}
static func bool(forKey key: defaultKeys) -> Bool {
return UserDefaults.standard.bool(forKey: forKey(key))
}
static func integer(forKey key: defaultKeys) -> Int {
return UserDefaults.standard.integer(forKey: forKey(key))
}
static func float(forKey key: defaultKeys) -> Float {
return UserDefaults.standard.float(forKey: forKey(key))
}
static func double(forKey key: defaultKeys) -> Double {
return UserDefaults.standard.double(forKey: forKey(key))
}
static func url(forKey key: defaultKeys) -> URL? {
return UserDefaults.standard.url(forKey: forKey(key))
}
static func object(forKey key: defaultKeys) -> Any? {
return UserDefaults.standard.object(forKey: forKey(key))
}
static func model<T: Decodable>(forKey key: defaultKeys) -> T? {
return UserDefaults.standard.model(forKey: forKey(key))
}
/// remove
static func remove(forKey key: defaultKeys){
return UserDefaults.standard.removeObject(forKey: forKey(key))
}
}
/// 对UserDefaults扩展支持model存储
extension UserDefaults {
func set<T: Encodable>(model: T?, forKey key: String) {
if let model = model {
let encoded = try? JSONEncoder().encode(model)
UserDefaults.standard.set(encoded, forKey: key)
} else {
UserDefaults.standard.removeObject(forKey: key)
}
}
func model<T: Decodable>(forKey key: String) -> T? {
if let data = UserDefaults.standard.data(forKey: key) {
return try? JSONDecoder().decode(T.self, from: data)
}
return nil
}
}
如何使用
- 首先定义使用的defaultKeys枚举
extension UserDefaults {
// 设置信息
enum SettingInfo: UserDefaultsSettable {
enum defaultKeys: String {
case dxva
case background
}
}
// 用户信息
enum UserInfo: UserDefaultsSettable {
enum defaultKeys: String {
case isLogin
case name
}
}
}
- 存取
//存储
UserDefaults.UserInfo.set("XXX", forKey: .name)
UserDefaults.SettingInfo.set(false, forKey: .background)
//取出
UserDefaults.UserInfo.string(forKey: .name)
UserDefaults.SettingInfo.bool(forKey: .background)
第二种方式
实现方式
- 同样首先定义一个
UserDefaultSettable
的协议
public protocol UserDefaultSettable {
var rawValueKey: String { get }
static var token: String? { get }
}
// MARK: - 生成rawValueKey
public extension UserDefaultSettable where Self: RawRepresentable, Self.RawValue == String {
static var token: String? { return nil }
fileprivate func forKey(_ key: String) -> String {
var string = String(format: "%@", arguments: [key])
if let token = Self.token {
string += String(format: "_%@", token)
}
return string
}
public var rawValueKey: String {
return forKey("\(Self.self).\(rawValue)")
}
}
// MARK: - setter
public extension UserDefaultSettable where Self: RawRepresentable, Self.RawValue == String {
public func store(_ value: Any?){
UserDefaults.standard.set(value, forKey: rawValueKey)
}
public func store(_ value: String?) {
UserDefaults.standard.set(value, forKey: rawValueKey)
}
public func store(_ value: Bool?) {
UserDefaults.standard.set(value, forKey: rawValueKey)
}
public func store(_ value: Int?) {
UserDefaults.standard.set(value, forKey: rawValueKey)
}
public func store(_ value: Float?) {
UserDefaults.standard.set(value, forKey: rawValueKey)
}
func store(_ value: Double?) {
UserDefaults.standard.set(value, forKey: rawValueKey)
}
func store(_ value: URL?) {
UserDefaults.standard.set(value, forKey: rawValueKey)
}
func store<T: Encodable>(_ value: T?) {
UserDefaults.standard.set(model: value, forKey: rawValueKey)
}
}
// MARK: - getter
public extension UserDefaultSettable where Self: RawRepresentable, Self.RawValue == String {
// typealias T = Decodable
public var value: Any? {
return UserDefaults.standard.value(forKey: rawValueKey)
}
public var string: String? {
return value as? String
}
public var bool: Bool? {
return UserDefaults.standard.bool(forKey: rawValueKey)
}
public var int: Int? {
return UserDefaults.standard.integer(forKey: rawValueKey)
}
public var float: Float? {
return UserDefaults.standard.float(forKey: rawValueKey)
}
public var double: Double? {
return UserDefaults.standard.double(forKey: rawValueKey)
}
public var url: URL? {
return UserDefaults.standard.url(forKey: rawValueKey)
}
func model<T: Decodable>() -> T? {
return UserDefaults.standard.model(forKey: rawValueKey)
}
}
// MARK: - removed
public extension UserDefaultSettable where Self: RawRepresentable, Self.RawValue == String {
public func removed() {
UserDefaults.standard.removeObject(forKey: rawValueKey)
}
}
如何使用
- 同样首先定义key的枚举
extension UserDefaults {
enum UserInfo: String,UserDefaultSettable {
case name
case url
case isLogin
case jump
static var token: String { return "11111111" }
}
}
- 存取
//存储
UserDefaults.UserInfo.name.store("小明")
UserDefaults.UserInfo.isLogin.store(false)
//取出
let name = UserDefaults.UserInfo.name.string
let isLogin = UserDefaults.UserInfo.isLogin.bool
第三中方式
一个github上的第三方库也可以很优雅的写UserDefaults