JL *_*ley 30 service json dictionary swift alamofire
我对iOS编程比较陌生.但是,我会假设Swift有一种将对象转换为JSON的自动方式,反之亦然.话虽这么说,我发现有几个库可以做到这一点.
然而...
似乎无论您如何将数据发布到Web服务(甚至使用类似AlamoFire之类的东西),请求必须是字典.所有这些论坛都显示了将返回的JSON字符串转换为对象是多么容易的示例.真正.但是请求需要手动编码.也就是说,遍历所有对象属性并将它们映射为字典.
所以我的问题是:我错过了什么吗?我是否完全错了,并且有一种超级简单的方法可以(a)在REQUEST中发送JSON(而不是字典)或(b)将对象自动转换为字典?
我再次看到处理JSON响应是多么容易.我只是在寻找一种自动方式将我想要发布到Web服务的请求对象转换为像AlamoFire(或其他)这样的库所需的格式.使用其他语言这是相当微不足道的,所以我希望有一个与Swift同样简单和自动化的方式.
fen*_*ode 45
我必须不同意@Darko.
在Swift 2中,
使用面向协议的编程和Mirror类提供的简单反射:
protocol JSONAble {}
extension JSONAble {
func toDict() -> [String:Any] {
var dict = [String:Any]()
let otherSelf = Mirror(reflecting: self)
for child in otherSelf.children {
if let key = child.label {
dict[key] = child.value
}
}
return dict
}
}
Run Code Online (Sandbox Code Playgroud)
那么您可以将此协议与您的请求类一起使用并生成所需的字典:
class JsonRequest : JSONAble {
var param1 : String?
// ...
}
let request = JsonRequest()
// set params of the request
let dict = request.toDict()
// use your dict
Run Code Online (Sandbox Code Playgroud)
Mic*_*bro 12
我对此的解决方案将是这样的:
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
}
}
Run Code Online (Sandbox Code Playgroud)
和用法将是这样的:
movies.compactMap { $0.dict }
Run Code Online (Sandbox Code Playgroud)
Swift目前不支持像Java或C#这样的高级反射,所以答案是:不,纯粹的Swift没有同样简单和自动化的方式.
[更新] Swift 4同时具有Codable允许序列化到/来自JSON和PLIST 的协议.
typealias Codable = Decodable & Encodable
Run Code Online (Sandbox Code Playgroud)
无需使用反射,并且适用于嵌套对象(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
}
}
Run Code Online (Sandbox Code Playgroud)
只需为要转换的自定义对象实现属性和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
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果需要,可以在toDictionary函数中添加更多值类型。
小智 5
经过对 Stack Overflow 的大量挖掘后,我发现的最新解决方案是:
//This block of code used to convert object models to json string
let jsonData = try JSONEncoder().encode(requestData)
let jsonString = String(data: jsonData, encoding: .utf8)!
print(jsonString)
//This method is used to convert jsonstring to dictionary [String:Any]
func jsonToDictionary(from text: String) -> [String: Any]? {
guard let data = text.data(using: .utf8) else { return nil }
let anyResult = try? JSONSerialization.jsonObject(with: data, options: [])
return anyResult as? [String: Any]
}
//Use above method something like this
let params = jsonToDictionary(from: jsonString) ?? [String : Any]()
//Use params to pass in paramters
Alamofire.request(completeUrl, method: .post, parameters: params, encoding:JSONEncoding.prettyPrinted, headers: myHeaders){
response in
//Do whatever you want with response of it.
}
Run Code Online (Sandbox Code Playgroud)
笔记:
| 归档时间: |
|
| 查看次数: |
21286 次 |
| 最近记录: |