NSUserDefaults in Swift - implementing type safety

后端 未结 2 1902
独厮守ぢ
独厮守ぢ 2021-02-02 01:43

One of the things that bugs me about Swift and Cocoa together is working with NSUserDefaults, because there is no type information and it is always necessary to cast the result

相关标签:
2条回答
  • 2021-02-02 02:39

    I don't mean to brag but ... oh who am I kidding, I totally do!

    Preferences.set([NSData()], forKey: "MyKey1")
    Preferences.get("MyKey1", type: type([NSData]))
    Preferences.get("MyKey1") as [NSData]?
    
    func crunch1(value: [NSData])
    {
        println("Om nom 1!")
    }
    
    crunch1(Preferences.get("MyKey1")!)
    
    Preferences.set(NSArray(object: NSData()), forKey: "MyKey2")
    Preferences.get("MyKey2", type: type(NSArray))
    Preferences.get("MyKey2") as NSArray?
    
    func crunch2(value: NSArray)
    {
        println("Om nom 2!")
    }
    
    crunch2(Preferences.get("MyKey2")!)
    
    Preferences.set([[String:[Int]]](), forKey: "MyKey3")
    Preferences.get("MyKey3", type: type([[String:[Int]]]))
    Preferences.get("MyKey3") as [[String:[Int]]]?
    
    func crunch3(value: [[String:[Int]]])
    {
        println("Om nom 3!")
    }
    
    crunch3(Preferences.get("MyKey3")!)
    
    0 讨论(0)
  • 2021-02-02 02:39

    I'd like to introduce my idea. (Sorry for my poor English in advance.)

    let plainKey = UDKey("Message", string)
    let mixedKey
        = UDKey("Mixed"
            , array(dictionary(
                string, tuple(
                    array(integer),
                    optional(date)))))
    
    let ud = UserDefaults(NSUserDefaults.standardUserDefaults())
    ud.set(plainKey, "Hello")
    ud.set(plainKey, 2525) // <-- compile error
    ud.set(mixedKey, [ [ "(^_^;)": ([1, 2, 3], .Some(NSDate()))] ])
    ud.set(mixedKey, [ [ "(^_^;)": ([1, 2, 3], .Some(NSData()))] ]) // <-- compile error
    

    The only difference is that UDKey() now requires #2 argument, a value of BiMap class. I've uncoupled the work originally of UDKey into BiMap which converts a value of a type to/from a value of another type.

    public class BiMap<A, B> {
        public func AtoB(a: A) -> B?
        public func BtoA(b: B) -> A?
    }
    

    Consequently, types that set/get can accepts are conducted by BiMap, and no longer limited to types as can automatically cast from/to AnyObject (more specifically, types NSUserDefaults can accepts.).

    Because BiMap is a generic class, you can easily create subtypes of that, interchanging arbitrary two types you want.

    Here is full source code. (But there are bugs yet to be fixed..) https://gist.github.com/hisui/47f170a9e193168dc946

    0 讨论(0)
提交回复
热议问题