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開發中的一些知識點


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM