我使用属性包装来保存我的用户默认值。在iOS 13设备上,这种解决方案非常有效。但是,在IOS 11和IOS 12上,这些值不会保存到用户默认值中。我读到属性包装是向后兼容的,所以我不知道为什么在较旧的IOS版本上不能这样做。
这是属性包装器:
@propertyWrapper
struct UserDefaultWrapper<T: Codable> {
private let key: String
private let defaultValue: T
init(key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T {
get {
guard let data = UserDefaults.standard.object(forKey: key) as? Data else {
// Return defaultValue when no data in UserDefaults
return defaultValue
}
// Convert data to the desire data type
let value = try? JSONDecoder().decode(T.self, from: data)
return value ?? defaultValue
}
set {
// Convert newValue to data
let data = try? JSONEncoder().encode(newValue)
UserDefaults.standard.set(data, forKey: key)
UserDefaults.standard.synchronize()
}
}
}
struct UserDefault {
@UserDefaultWrapper(key: "userIsSignedIn", defaultValue: false)
static var isSignedIn: Bool
}
然后,我可以这样设置
UserDefault.isSignedIn = true
我是不是用错了属性包装器?是否还有其他人在较早的IOS版本上遇到属性包装的问题?
与财产包装无关!问题是,在IOS 12和之前,一个简单的值,比如bool,虽然可以编码为财产可编码结构(例如),则不能。本身被编码。错误(您正在丢弃的)非常清楚这一点:
顶级Bool编码为编号JSON片段。
因此,例如,如果我们将示例更改为:
struct UserDefault { @UserDefaultWrapper(key: "userIsSignedIn", defaultValue: Person(firstName:"Matt")) static var isSignedIn: Person }
struct Person : Codable { let firstName : String } 我们在发射时说
print(UserDefault.isSignedIn) UserDefault.isSignedIn = Person(firstName:"Charlotte") 我们在连续发射时得到了正确的答案。
这一事实说明了一个解决方案。重新定义属性包装器,如下所示:
struct UserDefaultWrapper<T: Codable> { struct Wrapper : Codable where T : Codable { let wrapped : T }
private let key: String
private let defaultValue: T
init(key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T {
get {
guard let data = UserDefaults.standard.object(forKey: key) as? Data
else { return defaultValue }
let value = try? JSONDecoder().decode(Wrapper<T>.self, from: data)
return value?.wrapped ?? defaultValue
}
set {
do {
let data = try JSONEncoder().encode(Wrapper(wrapped:newValue))
UserDefaults.standard.set(data, forKey: key)
} catch {
print(error)
}
}
}
} 现在它可以在iOS 12上工作了。和IOS 13。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。