zoukankan      html  css  js  c++  java
  • swift 简化使用UserDefaults,UserDefaults使用优化

    用来做简单数据存储的Preference在我们的日常开发中使用的还是比较多的,但使用起来总感觉不那么方便。比如说需要去手动管理key,之前是这样做的。

    public enum UserDefaultsKey: String {
        case keyOne
        case keyTwo
    }
    
    extension UserDefaults {
        /// 存储
        public final class func set(_ value: Any, forKey: UserDefaultsKey) {
            UserDefaults.standard.set(value, forKey: forKey.rawValue)
        }
        /// 读取
        public final class func getString(forKey: UserDefaultsKey) -> String? {
            return UserDefaults.standard.string(forKey: forKey.rawValue)
        }
        public final class func getBool(forKey: UserDefaultsKey) -> Bool? {
            return UserDefaults.standard.bool(forKey: forKey.rawValue)
        }
    }
    
    // 存储数据
    UserDefaults.set(true, forKey: .keyOne)
    // 读取数据        
    UserDefaults.getBool(forKey: .keyOne)

      或者是这样做的

    var AuthToken:String?{
            set{
                let userData:UserDefaults=UserDefaults.standard
                userData.set(newValue, forKey: "AccountInfo_AuthToken")
            }
            get{
                let userData:UserDefaults=UserDefaults.standard
                return userData.object(forKey: "AccountInfo_AuthToken") as? String
            }
    }

      

    我们可以通过使用 #function 避免手动管理key,在存储和读取数据时调动的setget方法也可以交给目标属性默认的setget方法去做。 

    extension UserDefaults {
        /// 通过下标使用枚举
        subscript<T: RawRepresentable>(key: String) -> T? {
            get {
                if let rawValue = value(forKey: key) as? T.RawValue {
                    return T(rawValue: rawValue)
                }
                return nil
            }
            set { set(newValue?.rawValue, forKey: key) }
        }
        
        subscript<T>(key: String) -> T? {
            get { return value(forKey: key) as? T }
            set { set(newValue, forKey: key) }
        }
    }
    
    struct Preference {
        /// bool
        static var isFirstLogin: Bool {
            get { return UserDefaults.standard[#function] ?? false }
            set { UserDefaults.standard[#function] = newValue }
        }
    
        /// string
        static var userName: String {
            get { return UserDefaults.standard[#function] ?? "yourDefaultValue" }
            set { UserDefaults.standard[#function] = newValue }
        }
    
        /// enum
        static var appTheme: Theme {
            get { return UserDefaults.standard[#function] ?? .light }
            set { UserDefaults.standard[#function] = newValue }
        }
        /// 测试服跟正式服之间的切换(默认正式服)
        static var serverUrl: ServerUrlType {
            get { return UserDefaults.standard[#function] ?? .distributeServer }
            set { UserDefaults.standard[#function] = newValue }
        }
    }
    
    enum Theme: Int {
        case light
        case dark
        case blue
    }
    
    enum ServerUrlType: String {
        case developServer = "url: developServer" // 测试服
        case distributeServer = "url: distributeServer" // 正式服
    }
    
    // 存储数据
    Preference.isFirstLogin = true
    Preference.appTheme = .dark
    Preference.serverUrl = .developServer 
    
    // 读取数据
    Preference.isFirstLogin // true
    Preference.appTheme == .dark // true 
    Preference.serverUrl.rawValue // url: developServer

    在测试环节经常需要在测试服和正式服来回切换,为了避免老是打包,我们可以利用UserDefaults去更改服务器地址,在适当的位置(可以是个测试页面)加个UISwitch,然后设置serverUrl的值。 

    UserDefaults有性能问题吗?
    UserDefaults是带缓存的。它会把访问到的key缓存到内存中,下次再访问时,如果内存中命中就直接访问,如果未命中再从文件中载入。它还会时不时调用同步方法来保证内存与文件中的数据的一致性,有时在写入一个值后也最好调用下这个方法来保证数据真正写入文件。

    来源:SwiftTips记录iOS开发中的一些知识点

  • 相关阅读:
    不会吧不会吧,还有开发不会Java填充PDF模板数据的,赶紧看看吧
    关于Redis分布式锁这一篇应该是讲的最好的了,先收藏起来再看!
    iOS-----后台运行
    iOS-----使用GCD实现多线程
    iOS-----线程同步与线程通信
    iOS-----多线程之NSThread
    iOS-----MFMessageCompose 和 MFMailComposeViewController的使用方法
    iOS-----使用AddressBookUI管理联系人
    iOS-----使用addressBook管理联系人之修改联系人
    iOS-----简易地CocoaAsyncSocket使用
  • 原文地址:https://www.cnblogs.com/chzheng/p/13322611.html
Copyright © 2011-2022 走看看