我想从字典中实现模型的泛型填充。我使用以下测试测试模型是否具有属性,但条件总是失败:
if (self.responds(to:(NSSelectorFromString(keyName)))){
self.setValue(keyValue, forKey: key )
}
下面是一个示例代码:
import UIKit
class myModel: NSObject {
var userName: String = ""
var phoneNumber: String = ""
init(dict: Dictionary<String, Any>) {
super.init()
for (key, value) in dict {
let keyName = key
let keyValue: String = String(describing: value)
print("key (key) value (value)")
if (self.responds(to:(NSSelectorFromString(keyName)))){
self.setValue(keyValue, forKey: key )
}
}
}
}
你快完成了。在 NSObject 类的顶部添加以下内容 - @objcMembers
如-
import UIKit
@objcMembers
class myModel: NSObject {
这如您所料(在操场上测试(:
import UIKit
class myModel: NSObject {
@objc var userName: String = ""
@objc var phoneNumber: String = ""
init(dict: Dictionary<String, Any>) {
super.init()
for (key, value) in dict {
let keyCapitalized = key.prefix(1).uppercased() + key.dropFirst()
let keyName = "set(keyCapitalized):"
let keyValue: String = String(describing: value)
print("key (key) (selector: '(keyName))' value (value)")
if self.responds(to: Selector(keyName)) {
self.setValue(keyValue, forKey: key)
}
}
}
}
let m = myModel(dict: ["userName" : "milan", "data" : "data"])
print(">>> (m.userName)") // prints ">>> milan"
print(">>> (m.phoneNumber)") // prints ">>> " (number was not provided, and data key was ignored)
只有两点。
首先,您需要将这些属性公开给 ObjectiveC 才能responds()
工作 - 因此我在这两个属性上都添加了@objc
注释。
其次,测试是否可以设置名为 userName
的属性的正确选择器语法不是 Selector("userName")
,而是Selector("setUserName:")
(您正在测试一个 setter(。
需要为其键和值指定一个类型。初始化器中的内容太模糊了。
因为从字典中获取某些内容的结果可能是 nil,所以您需要提供一个默认值,即??
之后发生的情况
class MyModel: NSObject {
var userName: String = ""
var phoneNumber: String = ""
init(dict: [String : String]) {
self.userName = dict["userName"] ?? ""
self.phoneNumber = dict["phoneNumber"] ?? ""
super.init()
}
}
您可以通过以下方式从字典中设置模型值。
class MyModel {
var userName: String?
var phoneNumber: String?
init(dict: [String:Any]?) {
self.userName = dict?["username"] as? String
self.phoneNumber = dict?["phonenumber"] as? String
}
}
示例用法 :
let myModel = MyModel(dict: ["username":"test","phonenumber":"1234567890"])