Ios Swift结构扩展
我有一个设置结构,它在Ios Swift结构扩展,ios,swift,userdefaults,Ios,Swift,Userdefaults,我有一个设置结构,它在UserDefaults中存储数百个设置。 代码如下: struct Settings { public enum key: String { case mySetting = "mySetting" ... ... } public var mySetting: Bool { get { return UserDefaults.standard.bool(forKey: key.mySetting.rawValue)
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)
}
}
....
....
}
我想扩展它。我想获取在对等设备上运行的应用程序的另一个实例的设置,并将其存储为字典
mySetting
必须返回键的值。mySettingkey
来自该dictionary
而不是UserDefaults
。但是如果没有连接对等设备,那么它应该返回UserDefaults
中的值
我想知道如何扩展Settings结构(或者在需要时将其更改为class)以实现此功能,而无需在代码中的数百个位置添加“if-then-else”
我在数百个地方这样做:
var settings = Settings()
或
一些自动拉取正确设置字典以查找的构造将是最好的
编辑:正如我所说的,并不是所有的退货类型都很简单,这会使工作更困难。一些返回类型是枚举、字典和数组。正如一些人建议使用一个统一的方法返回Any?,例如,在我使用返回类型的地方,这项工作将更加困难
public var microphone: Microphone {
get {
if let mic = Microphone.init(rawValue: UserDefaults.standard.integer(forKey: key.microphone.rawValue)) {
return mic
} else {
return .auto
}
}
set (newValue) {
UserDefaults.standard.set(newValue.rawValue, forKey: key.microphone.rawValue)
}
}
我将为dictionary添加一个optional属性,然后使用一对get和set函数使用dictionary或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
}
我将为dictionary添加一个optional属性,然后使用一对get和set函数使用dictionary或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
}
你能把你的设置结构添加到代码中吗?代码只是设置的一部分,我刚刚更新了它。你的代码的问题是默认设置中的每个设置都通过不同的方法;例如,
public var mySetting
只处理mySetting
defaults键。您应该通过一个方法传递所有内容。@matt问题不是所有设置变量/方法都具有相同的返回类型。有些返回类型是枚举,我在这些方法中做了大量的工作。一种方法怎么能解决所有问题?如果我有一个返回Any?的方法,那么在我使用该方法的地方,我将需要重做艰苦的工作。上面的示例(代码已编辑)。这就是泛型存在的原因。您可以将设置结构添加到代码中吗?代码只是设置,我刚刚更新了它。您的代码的问题是默认设置中的每个设置都通过不同的方法;例如,public var mySetting
只处理mySetting
defaults键。您应该通过一个方法传递所有内容。@matt问题不是所有设置变量/方法都具有相同的返回类型。有些返回类型是枚举,我在这些方法中做了大量的工作。一种方法怎么能解决所有问题?如果我有一个返回Any?的方法,那么在我使用该方法的地方,我将需要重做艰苦的工作。上面的示例(代码编辑)。这就是泛型存在的原因。我编辑了代码,让我知道如何处理设置中所有可能的返回类型。也许我遗漏了一些东西,但是如果您有复杂的返回类型,例如enum,那么这段代码是否仍然可以正常工作?@DeepakSharma将第一个方法视为获取和设置值的基本方法,然后您可以添加包装器方法以用于不同的类型。我在我的回答中增加了一个Enum,谢谢你的回答。一个简单的问题,将设置作为一个struct vs class,因为会有太多的方法,将设置作为一个class而不是struct有意义吗?这并不重要,我可能会使用struct。既然你只想,至少我假设,一个设置对象的实例,你应该考虑把它变成一个单独的.@ DeMakSaMARA对于大多数类型,你应该能够使用我的基本函数使用<代码>任何< /代码>,也许这对数组和字典这样的集合不起作用,但您不必实现那么多额外的函数。我编辑了代码,让我知道如何在设置中处理所有可能的返回类型。也许我遗漏了一些东西,但是如果您有复杂的返回类型,例如enum,那么这段代码是否仍然可以正常工作?@DeepakSharma将第一个方法视为获取和设置值的基本方法,然后您可以添加包装器方法以用于不同的类型。我在我的回答中增加了一个Enum,谢谢你的回答。一个简单的问题,将设置作为一个struct vs class,因为会有太多的方法,将设置作为一个class而不是struct有意义吗?这并不重要,我可能会使用struct。既然你只想,至少我假设,一个设置对象的实例,你应该考虑把它变成一个单独的.@ DeMakSaMARA对于大多数类型,你应该能够使用我的基本函数使用<代码>任何< /代码>,也许这对数组和字典这样的集合不起作用,但您不应该实现那么多额外的函数