0

データを NSUserDefaults に保存する一般的な方法を書き込もうとしています。私が直面している問題は、タイプをNSUserDefaults.standardUserDefaults().setValue(value, forKey: key)取り込んでAnyObject?、プロトコルでタイプを設定すると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()
}    
4

3 に答える 3

0

あまり変更せずにこのコードを機能させたい場合は、値のみをキャストできます。

NSUserDefaults.standardUserDefaults().setValue(value as? AnyObject, forKey: key)

ただし、プロトコルを実装したら、 AnyObject に準拠するために値を確認する必要があると思います。

于 2016-02-01T00:54:47.373 に答える
0

ここでプロトコルを誤用していると思います。特定のタイプのすべての要素に同じキーを持たせたくはありませんが、それが実装方法です。キーはプロトコルの一部であり、拡張機能の一部としてキーをアタッチしているため、文字列を格納できるキーは 1 つだけです。それはあまり役に立たないようです。(おそらく、ここでの使用例を見逃しているかもしれません。どのように使用する予定なのか、例を挙げていただけますか?)

あなたが目指しているように見えるのは、 へのもう少しSwiftyなインターフェースを作ることNSUserDefaultsです。それは問題ありません。

struct UserDefaults {
    static func setValue<T: AnyObject>(value: T, forKey key: String) {
        NSUserDefaults.standardUserDefaults().setValue(value, forKey: key)
    }
    static func valueForKey<T>(key: String) -> T? {
        return NSUserDefaults.standardUserDefaults().valueForKey(key) as? T
    }
}

UserDefaults.setValue("123", forKey: "x")
let str: String? = UserDefaults.valueForKey("x")
print(str)

UserDefaults.setValue(123, forKey: "y")
let num: Int? = UserDefaults.valueForKey("y")
print(num)

補足として、を呼び出す理由はほとんどありませんsynchronize()NSUserDefaults。それはほぼ正確にスリープコールです。実際には何も「同期」しません。

于 2016-02-01T00:55:06.953 に答える
0

目的は、データを NSUserDefaults に保存する一般的な方法を記述しようとしているためです。私はあなたがジェネリックを意味すると仮定しています。もっと簡単なことを試してみることをお勧めします。次のコードをコピーしてプレイグラウンドに貼り付けるだけで、結果を確認できます。



    func getDefault(key: String) -> AnyObject? {
        return NSUserDefaults.standardUserDefaults().valueForKey(key)
    }

    func setDefault(value: AnyObject?, forKey defaultName: String) {
        NSUserDefaults.standardUserDefaults().setValue(value, forKey: defaultName)
    }

    func removeDefault(forKey defaultName: String) {
        NSUserDefaults.standardUserDefaults().removeObjectForKey(defaultName)
    }

    //// String Example
    let key1 = "Key1"
    getDefault(key1)
    setDefault("ABC", forKey: key1)
    getDefault(key1)
    removeDefault(forKey: key1)
    getDefault(key1)

    //// Number Example
    let key2 = "Key2"
    getDefault(key2)
    setDefault(5678, forKey: key2)
    getDefault(key2)
    removeDefault(forKey: key2)
    getDefault(key2)

    //// NSDate Example
    let key3 = "Key3"
    getDefault(key3)
    setDefault(NSDate(), forKey: key3)
    getDefault(key3)
    removeDefault(forKey: key3)
    getDefault(key3)

    //// Array Example
    let key4 = "Key4"
    getDefault(key4)
    setDefault(["One", "Two", "Three", "Four"], forKey: key4)
    getDefault(key4)
    removeDefault(forKey: key4)
    getDefault(key4)

    //// Bool Example
    let key5 = "Key5"
    getDefault(key5)
    setDefault(true, forKey: key5)
    getDefault(key5)
    removeDefault(forKey: key5)
    getDefault(key5)

    //// UserDefaultType
    typealias UserDefaultType = String
    let userDefaultType: UserDefaultType = "AnyStringHere"
    let key6 = "Key6"
    getDefault(key6)
    setDefault(userDefaultType as AnyObject, forKey: key6)
    getDefault(key6)
    removeDefault(forKey: key6)
    getDefault(key6)

于 2016-02-01T08:32:51.067 に答える