我正在尝试编写一种将数据存储到 NSUserDefaults 的通用方法。我遇到的问题是 NSUserDefaults.standardUserDefaults().setValue(value, forKey: key)
接受类型 AnyObject?
并且如果我在协议(protocol)、String
、Bool
等不会映射到 AnyObject?
,因为它们不是对象。无论如何,如何使该代码工作而不必为每种类型实现扩展?感谢您的帮助!
protocol UserDefaultUtility {
typealias UserDefaultType
var key: String { get }
func getDefault() -> UserDefaultType?
func setDefault(value: UserDefaultType?)
func removeDefault()
}
extension UserDefaultUtility {
func getDefault() -> UserDefaultType? {
return NSUserDefaults.standardUserDefaults().valueForKey(key) as? UserDefaultType
}
// Doesn't work-- Cannot convert value of type 'Self.UserDefaultType' to expected argument type 'AnyObject?'
/*
func setDefault(value: UserDefaultType) {
NSUserDefaults.standardUserDefaults().setValue(value, forKey: key)
NSUserDefaults.standardUserDefaults().synchronize()
}
*/
func removeDefault() {
NSUserDefaults.standardUserDefaults().removeObjectForKey(key)
NSUserDefaults.standardUserDefaults().synchronize()
}
}
// I have to do this instead to get it to work for any type I want to save to user defaults
extension UserDefaultUtility where UserDefaultType == String {
func setDefault(value: String?) {
NSUserDefaults.standardUserDefaults().setValue(value, forKey: key)
NSUserDefaults.standardUserDefaults().synchronize()
}
}
编辑 1
实现
/**
Strings stored in UserDefaults are accessed by this utility. Note that the String in the enum header is there to tell the enum that it's raw value is a String.
*/
enum StringUserDefaulstUtility: String, UserDefaultsUtility {
typealias UserDefaultType = String
case UserFirstName = "userFirstName"
case UserLastName = "userLastName"
var key: String {
get {
return self.rawValue
}
}
}
enum NSDateUserDefaultsUtility: String, UserDefaultsUtility {
typealias UserDefaultType = NSDate
case TokenExpiration = "tokenExpiration"
var key: String {
get {
return self.rawValue
}
}
}
用例
func someUselessFunc() {
// Sets the user's first name
StringUserDefaulstUtility.UserFirstName.setDefault("Matt")
// Gets the user's first name
StringUserDefaulstUtility.UserFirstName.getDefault()
// Removes the user's first name
StringUserDefaulstUtility.UserFirstName.removeDefault()
}
最佳答案
如果您想让此代码在不进行太多更改的情况下工作,您可以仅转换该值。
NSUserDefaults.standardUserDefaults().setValue(value as? AnyObject, forKey: key)
但是,我认为一旦实现协议(protocol),您就需要验证值以符合 AnyObject。
关于swift - 具有类型别名的协议(protocol)不能符合 AnyObject 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35121205/