swift - 具有类型别名的协议(protocol)不能符合 AnyObject 类型?

标签 swift nsuserdefaults swift-protocols

我正在尝试编写一种将数据存储到 NSUserDefaults 的通用方法。我遇到的问题是 NSUserDefaults.standardUserDefaults().setValue(value, forKey: key) 接受类型 AnyObject? 并且如果我在协议(protocol)、StringBool 等不会映射到 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/

相关文章:

ios - UICollectionView 检测滚动方向并更改图像

arrays - SWIFT - 将 Int append 到 NSUser 默认字典中的数组

ios - defaults.setValue 保存值始终为 nil 字符串

swift - Swift 中 Container View 和 ViewController 之间的委托(delegate)

swift - 如何用可选方法包装协议(protocol)?

ios - 导航回 TableViewController 时如何恢复单元格的先前状态

ios - 如何直接获取Firebase用户(fb auth)? (没有实时数据库引用)

ios - 如何保存和重用整数

ios - 是否可以动态创建 swift 协议(protocol)的可选和非可选版本?

swift - 我如何在 Swift 中切换图像?