- 泛字符串类型 API
// 泛字符串类型
let image = UIImage(named: "PalletTown")
// 强类型
let tableView = UITableView(frame: CGRect(), style: .plain)
- 缺点:
- 拼写错误
UserDefaults.standard.set(true, forKey: “isUserLoggedIn”)
UserDefaults.standard.bool(forKey: "isUserLoggedIn")
- 冲突
let keyA = "isUserLoggedIn"
let keyB = "isUserLoggedIn"
UserDefaults.standard.set(true, forKey: keyA)
UserDefaults.standard.set(false, forKey: keyB)
- 运行时崩溃
tableView.register(UITableViewCell.self,forCellReuseIdentifier: "CellIdentifer")
let cell = tableVie.dequeueReusableCell(withIdentifier: "CelIdentifer")
- 常见处理方法:
- 添加命名空间
struct Constants {
struct Account {
static let isUserLoggedIn = "isUserLoggedIn"
}
}
UserDefaults.standard.set(true, forKey: Constants.Account.isUserLoggedIn)
UserDefaults.standard.bool(forKey: Constants.Account.isUserLoggedIn)
- 不写字符串字面值
enum Constants {
enum Account : String {
case isUserLoggedIn
}
}
UserDefaults.standard.set(true, forKey: Constants.Account.isUserLoggedIn.rawValue)
UserDefaults.standard.bool(forKey: Constants.Account.isUserLoggedIn.rawValue)
- 常见问题:
- 解决冲突
struct Constants {
struct Account {
static let isUserLoggedIn = "Account.isUserLoggedIn"
}
struct Password {
static let isUserLoggedIn = "Password.isUserLoggedIn"
}
}
UserDefaults.standard.set(true, forKey: Constants.Account.isUserLoggedIn)
UserDefaults.standard.set(false, forKey: Constants.Password.isUserLoggedIn)
UserDefaults.standard.bool(forKey: Constants.Account.isUserLoggedIn) // true
- 简单调用
UserDefaults.standard.set(true, forKey: .isUserLoggedIn)
- 扩展协议
- 实现简单调用
protocol BoolUserDefaultable {
associatedtype BoolDefaultKey : RawRepresentable
}
extension BoolUserDefaultable where BoolDefaultKey.RawValue == String {
// Set
static func set(_ value: Bool, forKey key: BoolDefaultKey) {
let key = key.rawValue
UserDefaults.standard.set(value, forKey: key)
}
// Get
static func bool(forKey key: BoolDefaultKey) -> Bool {
let key = key.rawValue
return UserDefaults.standard.bool(forKey: key)
}
}
使用:
struct Account : BoolUserDefaultSettable {
enum BoolDefaultKey : String {
case isUserLoggedIn
}
}
// Setter
Account.set(true, forKey: .isUserLoggedIn)
// Getter
Account.bool(forKey: .isUserLoggedIn)
- 添加命名空间:
protocol KeyNamespaceable { }
extension KeyNamespaceable {
static func namespace<T: RawRepresentable>(_ key: T) -> String where T.RawValue == String {
return "\(Self.self).\(key.rawValue)"
}
}
// MARK: - Bool Defaults
protocol BoolUserDefaultable : KeyNamespaceable {
associatedtype BoolDefaultKey : RawRepresentable
}
extension BoolUserDefaultable where BoolDefaultKey.RawValue == String {
// Set
static func set(_ bool: Bool, forKey key: BoolDefaultKey) {
let key = namespace(key)
UserDefaults.standard.set(bool, forKey: key)
}
// Get
static func bool(forKey key: BoolDefaultKey) -> Bool {
let key = namespace(key)
return UserDefaults.standard.bool(forKey: key)
}
}
使用:
struct Password : BoolUserDefaultSettable {
enum BoolDefaultKey : String {
case isUserLoggedIn
}
}
// Setter
Password.set(true, forKey: .isUserLoggedIn)
// Getter
Password.bool(forKey: .isUserLoggedIn)
- 添加上下文
extension UserDefaults {
struct Account : BoolUserDefaultable {
enum BoolDefaultKey : String {
case isUserLoggedIn
}
}
struct Password : BoolUserDefaultSettable {
enum BoolDefaultKey : String {
case isUserLoggedIn
}
}
}
- 使用:
// Set
UserDefaults.Account.set(true, forKey: .isUserLoggedIn)
// Get
let isUserLoggedIn = UserDefaults.Account.bool(forKey: .isUserLoggedIn)