Swift Struct扩展

时间:2019-06-15 10:36:44

标签: ios swift userdefaults

我有一个“设置”结构,该结构将数百个设置存储在jTitle = driver.find_element_by_xpath("//div[@id='vjs-jobtitle']").text myFile = open('output.csv', 'w') with myFile: writer = csv.writer(myFile) writer.writerow(jTitle) 中。 下面的代码:

UserDefaults

我想扩展它。我想获取在对等设备上运行的应用程序的另一个实例的设置,并将其存储为struct Settings { public enum key: String { case mySetting = "mySetting" ... ... } public var mySetting: Bool { get { return UserDefaults.standard.bool(forKey: key.mySetting.rawValue) } set (newValue) { return UserDefaults.standard.set(newValue, forKey: key.mySetting.rawValue) } } .... .... } Dictionary必须返回键值。mySettingmySetting而不是key。但是,如果没有连接对等设备,则它应返回dictionary中的值。

我想知道如何扩展Settings结构(或在需要时将其更改为类)以实现此功能,而无需在代码的数百个位置中放置“ if then else”。

我在数百个地方这样做:

UserDefaults

UserDefaults

一些能够自动提取正确的设置字典以寻找结构的结构是最好的。

编辑:正如我所说,并不是所有的返回类型都可以很简单,这会使工作更加困难。一些返回类型是枚举,一些字典,一些数组。正如有人建议使用一种统一的方法来返回Any ?,例如,在我使用返回类型的地方,这项工作会更加困难。

 var settings = Settings()

1 个答案:

答案 0 :(得分:2)

我会为字典添加一个最佳属性,然后使用一对get和set函数使用字典或UserDefaults

var peerDevice: [String: Any]?

func setting(forKey key: Key) -> Any? {
    if let dictionary = peerDevice {
        return dictionary[key.rawValue]
    }
    return UserDefaults.standard.value(forKey: key.rawValue)
}

mutating func set(_ value: Any, forKey key: Key) {
    if peerDevice != nil {
        peerDevice?[key.rawValue] = value
    } else {
        UserDefaults.standard.set(value, forKey: key.rawValue)
    }        
}

使用原始值的枚举的包装方法示例

mutating func setEnum<T>(_ value: T, forKey key: Key) where T: RawRepresentable {
    set(value.rawValue, forKey: key)
}

func setting<T>(forKey key: Key, andEnumType: T.Type) -> T? where T: RawRepresentable {
    if let value = setting(forKey: key) as? T.RawValue {
        return T.init(rawValue: value)
    }
    return nil
}

我自由地将枚举从key重命名为Key

然后像这样使用它

var settings = Settings()

settings.setSetting(true, forKey: .mySetting)

if let flag = settings.setting(forKey: .mySetting) as? Bool {
    print(flag)
}

settings.setEnum(Microphone.mic2, forKey: .mic)

if let mic = settings.setting(forKey: .mic, andEnumType: Microphone.self) {
    print(mic)
}