2015-09-15 14 views
2

我試圖在Swift 2中實現一個類,該類只使用NSUserDefaults下的任何類型的單個設置。Swift 2中的通用設置類

問題:如何定義一個類來存儲和檢索任何類型的對象,包括Dictionary

我有一個與AnyObject一起使用的解決方案,它由通用協議(Settable)和通用類(Setting)組成。 SettingsStore是圍繞NSUserDefaults的包裝。

// MARK: Settable Protocol 

public protocol Settable { 
    typealias T 
    init(key: String, defaultValue: T, settingsStore: SettingsStore) 
    var value: T { get set } 
    func loadCurrentValue() 
} 

// MARK: Settings Class 

public class Setting<T: AnyObject>: Settable { 
    private let key: String 
    private let defaultValue: T 
    private let settingsStore: SettingsStore 

    private var currentValue: T? 

    public required init(key: String, defaultValue: T, settingsStore: SettingsStore) { 
     self.key   = key 
     self.defaultValue = defaultValue 
     self.settingsStore = settingsStore 
    } 

    public var value: T { 
     get { 
      if self.currentValue == nil { 
       self.loadCurrentValue() 
      } 
      return self.currentValue! 
     } 
     set { 
      self.currentValue = newValue 
      self.settingsStore.setObject(newValue.toAnyObject(), forKey: self.key) 
     } 
    } 

    public func loadCurrentValue() { 
     let optionalValue: T? = self.settingsStore.objectForKey(key) as? T 
     if let value = optionalValue { 
      self.currentValue = value 
     } else { 
      self.currentValue = self.defaultValue 
     } 
    } 
} 

這使我創造這樣一個環境:

let specialId: Setting<String> 
init() { 
    self.specialId = Setting<String>(
     key: "specialId", 
     defaultValue: "<somevalue>", 
     settingsStore: self.settingsStore) 
} 

這裏的問題是,它不與價值工種,如StringBoolIntDoubleArrayDictionary,因爲它們都是值類型,值類型不符合AnyObject協議。

我已經解決了使用基於NSStringNSNumber協議和擴展其中的一些問題,但解決Dictionary被證明是難以實現的(我不需要在目前的Array的解決方案,所以我的避風港沒有花時間去解決那個問題)。

// Change definition of Setting class like this: 
public class Setting<T: AnyObjectRepresentable>: Settable { 
    ... 
} 

public protocol AnyObjectRepresentable { 
    func toAnyObject() -> AnyObject 
    static func fromAnyObject(value: AnyObject) -> Self? 
} 

extension AnyObjectRepresentable where Self: AnyObject { 
    public func toAnyObject() -> AnyObject { 
     return self 
    } 
    public static func fromAnyObject(value: AnyObject) -> AnyObject? { 
     return value 
    } 
} 
extension String: AnyObjectRepresentable { 
    public func toAnyObject() -> AnyObject { 
     return NSString(string: self) 
    } 
    public static func fromAnyObject(value: AnyObject) -> String? { 
     let convertedValue = value as? String 
     return convertedValue 
    } 
} 
extension Bool: AnyObjectRepresentable { 
    public func toAnyObject() -> AnyObject { 
     return NSNumber(bool: self) 
    } 
    public static func fromAnyObject(value: AnyObject) -> Bool? { 
     let convertedValue = value as? Bool 
     return convertedValue 
    } 
} 
// Add extensions for Int and Double that look like the above extension for Bool. 

我試過Dictionary兩種不同的方法。第一個是類似於String方法:

extension Dictionary: AnyObjectRepresentable { 
    public func toAnyObject() -> AnyObject { 
     let value = self as NSDictionary 
     return value 
    } 
    public static func fromAnyObject(value: AnyObject) -> Dictionary? { 
     let convertedValue = value as? Dictionary 
     return convertedValue 
    } 
} 

的Xcode給我的toAnyObject()法實施的第一線以下錯誤:

「詞典」是無法轉換爲「NSDictionary的」

接着我試圖直接延伸NSDictionary

extension NSDictionary: AnyObjectRepresentable { 
    public func toAnyObject() -> AnyObject { 
     return NSDictionary(dictionary: self) 
    } 
    public static func fromAnyObject(value: AnyObject) -> NSDictionary? { 
     let convertedValue = value as? NSDictionary 
     return convertedValue 
    } 
} 

的Xcode給我上的fromAnyObject()聲明以下錯誤:在非final類「的NSDictionary」必須返回Self

法「fromAnyObject」,以符合協議「AnyObjectRepresentable」

我在我的鬥智鬥勇。這是可以解決的嗎?

感謝,
大衛

已更新2015年9月15日16:30

爲背景,這裏的定義和SettingsStore實現:

public protocol SettingsStore { 
    func objectForKey(key: String) -> AnyObject? 
    func setObject(value: AnyObject?, forKey key: String) 
    func dictionaryForKey(key: String) -> [String:AnyObject]? 
} 
public class UserDefaultsSettingsStore { 
    private let userDefaults: NSUserDefaults 
    public init() { 
     self.userDefaults = NSUserDefaults.standardUserDefaults() 
    } 
    public init(suiteName: String) { 
     self.userDefaults = NSUserDefaults(suiteName: suiteName)! 
    } 
} 
extension UserDefaultsSettingsStore: SettingsStore { 
    public func objectForKey(key: String) -> AnyObject? { 
     return self.userDefaults.objectForKey(key) 
    } 
    public func setObject(value: AnyObject?, forKey key: String) { 
     self.userDefaults.setObject(value, forKey: key) 
     self.userDefaults.synchronize() 
    } 
    public func dictionaryForKey(key: String) -> [String : AnyObject]? { 
     return self.userDefaults.dictionaryForKey(key) 
    } 
} 
+0

而不是使用AnyObject,關於使用任何什麼? –

+0

關於你的錯誤,看看[協議樂趣返回自我](http://stackoverflow.com/questions/25645090/protocol-func-returning-self)。 – ABakerSmith

+0

我曾經看過那篇文章 - Rob Napier在這個主題上寫得非常好,但不幸的是在這種情況下它並沒有幫助我。 –

回答

0

如果您替換AnyObject任何,我想你會得到你正在尋找的結果。具體來說,替換此行:

public class Setting<T: AnyObject>: Settable { 

這一行

public class Setting<T: Any>: Settable { 
+0

我試過,但後來遇到了SettingsStore的問題,它用於讀取和寫入NSUserDefaults的設置。有任何想法嗎? –