我对iOS编程比较陌生。但是,我会假设Swift有一种将对象转换为JSON的自动方式,反之亦然。话虽这么说,我找到了几个可以做到这一点的库。
...无论其
似乎无论您如何将数据发布到Web服务(甚至使用类似AlamoFire之类的东西),请求必须是字典。所有这些论坛都展示了将返回的JSON字符串转换为对象是多么容易的示例。真正。但是请求需要手动编码。也就是说,遍历所有对象属性并将它们映射为字典。
所以我的问题是:我错过了什么吗?我是否完全错了,有一种超级简单的方法可以(a)在REQUEST中发送JSON(而不是字典)或(b)自动将对象转换为字典?
再次,我看到处理JSON响应是多么容易。我只是在寻找一种自动方式将我想要发布到Web服务的请求对象转换为像AlamoFire(或其他)这样的库所需的格式。使用其他语言这是相当微不足道的,所以我希望Swift可以采用同样简单易用的方式。
答案 0 :(得分:8)
Swift目前不支持像Java或C#这样的高级反射,所以答案是:不,纯粹的Swift没有同样简单易用的方法。
[更新] Swift 4同时具有Codable
协议,允许序列化到/来自JSON和PLIST。
typealias Codable = Decodable & Encodable
答案 1 :(得分:5)
不使用反射,适用于嵌套对象(Swift 4):
protocol Serializable {
var properties:Array<String> { get }
func valueForKey(key: String) -> Any?
func toDictionary() -> [String:Any]
}
extension Serializable {
func toDictionary() -> [String:Any] {
var dict:[String:Any] = [:]
for prop in self.properties {
if let val = self.valueForKey(key: prop) as? String {
dict[prop] = val
} else if let val = self.valueForKey(key: prop) as? Int {
dict[prop] = val
} else if let val = self.valueForKey(key: prop) as? Double {
dict[prop] = val
} else if let val = self.valueForKey(key: prop) as? Array<String> {
dict[prop] = val
} else if let val = self.valueForKey(key: prop) as? Serializable {
dict[prop] = val.toDictionary()
} else if let val = self.valueForKey(key: prop) as? Array<Serializable> {
var arr = Array<[String:Any]>()
for item in (val as Array<Serializable>) {
arr.append(item.toDictionary())
}
dict[prop] = arr
}
}
return dict
}
}
只需为要转换的自定义对象实现属性和valueForKey。例如:
class Question {
let title:String
let answer:Int
init(title:String, answer:Int) {
self.title = title
self.answer = answer
}
}
extension Question : Serializable {
var properties: Array<String> {
return ["title", "answer"]
}
func valueForKey(key: String) -> Any? {
switch key {
case "title":
return title
case "answer":
return answer
default:
return nil
}
}
}
如果需要,可以在toDictionary函数中添加更多值类型。
答案 2 :(得分:3)
您还可以使用ObjectMapper库。它有一个&#34; toJSON&#34;将对象转换为字典的方法。
答案 3 :(得分:1)
我对此的解决方案将是这样的:
extension Encodable {
var dict : [String: Any]? {
guard let data = try? JSONEncoder().encode(self) else { return nil }
guard let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String:Any] else { return nil }
return json
}
}
用法将是这样的:
movies.compactMap { $0.dict }