我正在尝试解析从Web服务接收的JSON对象,该对象将结果作为状态和数据的JSON对象给出。data还是一个对象数组,我想从这个对象中获取一个元素作为基础必须填写表格视图。
Web服务结果如下
{"status":1,"data":[{"service_id":"1","service_name":"Painter"},{"service_id":"2","service_name":"Plumber"},{"service_id":"3","service_name":"Electrician"},{"service_id":"4","service_name":"Handyman"},{"service_id":"5","service_name":"Carpenter"},{"service_id":"6","service_name":"Mason"}]}
我迅速解析为:- 创建了一个班级
class ABC: NSObject {
var service_name:String?
var service_id : Int?
init(service_name:String,service_id:Int) {
self.service_name = service_name
self.service_id = service_id
}
let myUrl = URL(string: "services.php");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"// Compose a query string
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil
{
print("error=\(String(describing: error))")
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json
{
let status=parseJSON["status"] as? Int
let newdata : NSDictionary = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
self.model=(newdata.value(forKey: "data") as? [ABC])!
我的问题是我在self.model中得到一个对象数组作为service_name和service_id键,现在我想取出一个包含所有service_name对象值的字符串数组,这意味着无法将NSArray转换为swift数组。
答案 0 :(得分:0)
现在随处使用Dictionary
的地方都使用本机Swift类型NSDictionary
然后通过在字典的下标中指定键来获得键的特定值
if let model = newData["data"] as? [ABC] {
self.model = model
}
无论如何,我建议您开始使用Codable
而不是JSONSerialization
struct Response: Decodable {
let status: Int
let data: [ABC]
}
struct ABC: Decodable {
let serviceName: String
let serviceId: String // note that `serviceId` isn’t `Int` But `String`
}
,然后使用JSONDecoder
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
let response = try decoder.decode(Response.self, from: data!)
self.model = response.data
} catch { print(error) }
答案 1 :(得分:0)
我建议删除JSONSerialization
并使用Codable
协议代替CodingKeys
。
这里是一个简单的示例,以了解其工作原理。
struct Service : Codable {
let id : Int
let name : String
// keys
private enum CodingKeys: String, CodingKey {
case id = "service_id"
case name = "service_name"
}
}
...
// assuming our data comes from server side
let jsonString = "..."
let jsonData = jsonString.data(using: .utf8)!
do {
let jsonDecoder = JSONDecoder()
let user = try jsonDecoder.decode(Service.self, from: jsonData)
print("Getting service: \(service.id) \(service.name)")
} catch {
print("Unexpected error: \(error).")
}
更多documentation在这里。
答案 2 :(得分:0)
其他人已经提到过使用(De)codable
。它易于使用且非常舒适。没有类型转换,也没有文字键。
创建两个结构,将成员声明为具有 camelCased 名称的非可选常量,并省略初始化程序。
struct Root : Decodable {
let status : Int
let data : [Service]
}
struct Service : Decodable {
let serviceName : String
let serviceId : String
}
然后在另一个类或结构中解码JSON
let myUrl = URL(string: "services.php")
var request = URLRequest(url: myUrl!)
request.httpMethod = "POST"// Compose a query string
let task = URLSession.shared.dataTask(with: request) { data, _, error in
if let error = error { print(error); return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let json = try decoder.decode(Root.self, from: data!)
let status = json.status
let newdata = json.data
} catch { print(error))
}
task.resume()