[英]Converting JSON to array in Swift 2
I need to build Arrays
for a Grouped UITableView
, with a Title and Detail line in each table cell. 我需要为Grouped UITableView
构建Arrays
,每个表格单元格中都有一个Title和Detail行。 I've got my json output from the server putting it in the right shape to iterate through the UITableViewDataSource
methods. 我从服务器获得了json输出,使其形状正确,以迭代UITableViewDataSource
方法。 But what's the simplest way to convert these to a readable array that those UITableView
functions can reference? 但是将这些转换为UITableView
函数可以引用的可UITableView
组的最简单方法是什么?
The headings array is for the Group headings, so it's just a one-dimensional array. 标题数组用于组标题,因此它只是一维数组。 I can iterate that. 我可以迭代一下。 The titles and details arrays are both two dimensional. 标题和细节数组都是二维的。 I can't figure out how to do that in Swift. 我无法弄清楚如何在Swift中做到这一点。
"headings":["Tuesday, August 16, 2016","Wednesday, August 17, 2016","Thursday, August 18, 2016","Friday, August 19, 2016","Saturday, August 20, 2016","Sunday, August 21, 2016","Monday, August 22, 2016","Tuesday, August 23, 2016","Wednesday, August 24, 2016","Thursday, August 25, 2016","Friday, August 26, 2016","Saturday, August 27, 2016","Sunday, August 28, 2016","Monday, August 29, 2016","Tuesday, August 30, 2016","Wednesday, August 31, 2016","Thursday, September 1, 2016","Friday, September 2, 2016","Saturday, September 3, 2016","Sunday, September 4, 2016","Monday, September 5, 2016","Tuesday, September 6, 2016","Wednesday, September 7, 2016","Thursday, September 8, 2016","Friday, September 9, 2016","Saturday, September 10, 2016","Sunday, September 11, 2016","Monday, September 12, 2016","Tuesday, September 13, 2016","Wednesday, September 14, 2016","Thursday, September 15, 2016","Friday, September 16, 2016"],
"titles":[["Joe Johnson"],["Joe Johnson"],["Sandy Primmell","Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Sandy Primmell","Joe Johnson"],["Joe Johnson","Joe Johnson"],["Sandy Primmell","Joe Johnson"],["Mark Greene","Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Sandy Primmell","Joe Johnson"],["Joe Johnson"],["Sandy Primmell","Joe Johnson"],["Mark Greene","Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"],["Joe Johnson"]],
"details":[["OFF"],["OFF"],["Gregory","OFF"],["Gregory"],["OFF"],["OFF"],["OFF"],["Weekday Rounders","OFF"],["Weekday Rounders","Night Owls"],["Gregory","OFF"],["Gregory","OFF"],["OFF"],["OFF"],["OFF"],["Gregory"],["Gregory","OFF"],["Gregory"],["Gregory","OFF"],["Gregory","OFF"],["OFF"],["OFF"],["OFF"],["OFF"],["OFF"],["OFF"],["OFF"],["OFF"],["OFF"],["OFF"],["OFF"],["OFF"],["OFF"]]
UPDATE UPDATE
Here's my Alamofire async function that grabs the data: 这是抓取数据的Alamofire异步函数:
manager.request(.POST, getRouter(), parameters:["dev": 1, "app_action": "schedule", "type":getScheduleType(), "days_off":getScheduleDaysOff(), "period":getSchedulePeriod(), "begin_date":getScheduleBeginDate(), "end_date":getScheduleEndDate()])
.responseString {response in
print(response)
var json = JSON(response.result.value!);
// what I'm missing
}
You can use this function: 你可以使用这个功能:
func convertStringToDictionary(text: String) -> [String:AnyObject]? {
if let data = text.dataUsingEncoding(NSUTF8StringEncoding) {
do {
return try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String:AnyObject]
} catch let error as NSError {
print(error)
}
}
return nil
}
and then you can read the array like this: 然后你可以像这样读取数组:
if let dict = convertStringToDictionary(jsonText) {
let array = dict["headings"] as? [String]
}
Looks like you are getting Dictionary
from json and each key contain Array
, you can try something like this, first declare one Dictionary
instance and use that with TableViewDataSource
methods. 看起来你从json获取Dictionary
并且每个键都包含Array
,你可以尝试这样的东西,首先声明一个Dictionary
实例并将其与TableViewDataSource
方法一起使用。
var response = [String: AnyObject]()
do {
self.response = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as! [String: AnyObject]
print(dic)
}
catch let e as NSError {
print(e.localizedDescription)
}
Now inside tableView
methods 现在在tableView
方法中
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
if let arr = self.response["headings"] as? [String] {
return arr.count
}
return 0
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let headings = self.response["headings"] as! [String]
return headings[Int]
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let arr = self.response["titles"] as? [[String]] {
return arr[Int].count
}
return 0
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let titles = self.response["titles"] as! [[String]]
let details = self.response["details"] as! [[String]]
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! EmployeeCell
cell.mainLabel?.text = titles[indexPath.section][indexPath.row]
cell.detailLabel?.text = details[indexPath.section][indexPath.row]
return cell
}
Alternatively, You can use JSON parsing libraries like Argo or SwiftyJSON , which were created to simplify the JSON parsing. 或者,您可以使用JSON解析库,如Argo或SwiftyJSON ,它们是为简化JSON解析而创建的。 They are both well tested and will handle edge cases for you, like missing parameters in the JSON responses etc. 它们都经过了良好的测试,可以为您处理边缘情况,例如JSON响应中缺少参数等。
Assuming the JSON response has this format (from Twitter API ) 假设JSON响应具有此格式(来自Twitter API )
{
"users": [
{
"id": 2960784075,
"id_str": "2960784075",
...
}
}
Note that Response
is a class that contains an array of User
which is another class not shown here, but you get the point. 请注意, Response
是一个包含User
数组的类,这是另一个未在此处显示的类,但您明白了。
struct Response: Decodable {
let users: [User]
let next_cursor_str: String
static func decode(j: JSON) -> Decoded<Response> {
return curry(Response.init)
<^> j <|| "users"
<*> j <| "next_cursor_str"
}
}
//Convert json String to foundation object
let json: AnyObject? = try? NSJSONSerialization.JSONObjectWithData(data, options: [])
//Check for nil
if let j: AnyObject = json {
//Map the foundation object to Response object
let response: Response? = decode(j)
}
As explained in the official documentation : 如官方文档中所述 :
if let dataFromString = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
let json = JSON(data: dataFromString)
}
If data is an array then use the index 如果数据是数组,则使用索引
//Getting a double from a JSON Array
let name = json[0].double
If data is a dictionary then use the key 如果数据是字典,则使用密钥
//Getting a string from a JSON Dictionary
let name = json["name"].stringValue
Array 排列
//If json is .Array
//The `index` is 0..<json.count's string value
for (index,subJson):(String, JSON) in json {
//Do something you want
}
Dictionary 字典
//If json is .Dictionary
for (key,subJson):(String, JSON) in json {
//Do something you want
}
I would suggest using AlamofireObjectMapper. 我建议使用AlamofireObjectMapper。 The library lets you you map objects from json easily and if combined with Alamofire can cast and return your object on the server response. 该库允许您轻松地从json映射对象,如果与Alamofire结合使用,可以在服务器响应上转换和返回您的对象。 The object mapping itself should look like this in your case 在您的情况下,对象映射本身应如下所示
class CustomResponseClass: Mappable {
var headings: [String]?
required init?(_ map: Map){
}
func mapping(map: Map) {
headings <- map["headings"]
}
}
This way you decouple the logic of mapping and parsing json from your tableViewController. 这样就可以解析映射和解析json与tableViewController的逻辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.