Swift UserDefaults的简单封装处理

UserDefaults 平常我们的项目中都会用来保存一些账号信息等,但是它的存取需要写很长的方法调用,感觉很费劲, 而且多人开发的时候不利于代码的统一。
之前从 Apple Sample Code 看到 RawRepresentable 的用法获得启发 :

extension UserDefaultNameSpace {
    static func namespace<T>(_ key:T) -> String where T :RawRepresentable {
        return "\(Self.self).\(key.rawValue) "
    }
}
protocol UserDefaultSettable: UserDefaultNameSpace {
    associatedtype UserDefaultKey : RawRepresentable
}

之前一直没用过 RawRepresentable这个协议, 通过查看源码可以发现(虽然只有三行代码, 但是注释却有很长的一大段, )

public protocol RawRepresentable {
    associatedtype RawValue
    public init?(rawValue: Self.RawValue)
    public var rawValue: Self.RawValue { get }
}

遵循这个协议的类型可以表示另一个类型,并且可以通过 rawValue 这个属性得到它表示的值, 看到这里你会疑问这么写会有什么作用, 往下看你就知道了

extension UserDefaultSettable where UserDefaultKey.RawValue == String {}

我们经常使用UserDefaults 主要是 Int, String, Any 这几个类型
那么可以这样实现set方法

extension UserDefaultSettable {
    
    static func set(value:Int, forKey key:UserDefaultKey){
        let key = namespace(key)
        UserDefaults.standard.set(value, forKey: key)
    }
    
    static func integer(forKey key:UserDefaultKey) -> Int {
        let key = namespace(key)
        return UserDefaults.standard.integer(forKey: key)
    }
    
    static func set(value:Any?, forKey key:UserDefaultKey){
        let key = namespace(key)
        UserDefaults.standard.set(value, forKey: key)
    }
    
    static func string(forKey key:UserDefaultKey) -> String? {
        let key = namespace(key)
        return UserDefaults.standard.string(forKey: key)
    }
}

我在处理用户缓存的时候, 需要直接把整个usermodel缓存起来

extension UserDefaults {
    //账号的信息
    struct Account: UserDefaultSettable {
        enum UserDefaultKey : String {
            case token
            case name
            case age
           // ... 你可以在此自由添加对应模型字段
        }
    }
    // 缓存账号信息
    class func setUserInfo(userInfo: userInfoModel, token:String) {
        UserDefaults.Account.set(value: token, forKey: .token)
        UserDefaults.Account.set(value: userInfo.id, forKey: .id)
        UserDefaults.Account.set(value: userInfo.nickname, forKey: .nickname)
           // ... 你可以在此自由添加对应模型字段
    }
    
    // 清除账号信息
    class func clearUserInfo() {
        UserDefaults.Account.set(value: "", forKey: .token)
        UserDefaults.Account.set(value: "", forKey: .uid)
        UserDefaults.Account.set(value: "", forKey: .pk)
           // ... 你可以自由添加对应模型字段
    }
}

使用示例

//存:
      UserDefaults.setUserInfo(userInfo: (response.returnValue?.info)!, token: token)

//取:
      let username = UserDefaults.Account.string(forKey: .userId) ?? ""

以后, 一起开发的同事们都不会再为缓存代码烦恼啦~

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,284评论 25 708
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,929评论 2 59
  • 心理FM接口 1-启动封面图 http://yiapi.xinli001.com/fm/initial-cover...
    清無阅读 4,778评论 0 4
  • 《江湖情》 文/l墨若子兮(裸奔歌者) 江湖相交一杯酒, 酒浓醉后情自深。 称兄道弟生死共, 酒醒难来无一踪。 桌...
    无戒诗书阅读 385评论 0 0
  • 凌晨三点。 窗外楼下,剧烈的咳嗽声响彻空荡荡的小区。睡前迷迷糊糊感觉到的剧烈风声,此刻似乎被吓住了,闃然被一声高过...
    春天里的一棵树阅读 338评论 0 0