简体   繁体   English

在Swift 2中将JSON转换为数组

[英]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.dataUsingEncodi‌​ng(NSUTF8StringEncodi‌​ng) {
        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解析库,如ArgoSwiftyJSON ,它们是为简化JSON解析而创建的。 They are both well tested and will handle edge cases for you, like missing parameters in the JSON responses etc. 它们都经过了良好的测试,可以为您处理边缘情况,例如JSON响应中缺少参数等。

An example using Argo: 使用Argo的一个例子:

Assuming the JSON response has this format (from Twitter API ) 假设JSON响应具有此格式(来自Twitter API

{
  "users": [
    {
      "id": 2960784075,
      "id_str": "2960784075",
      ...
    }
}

1- Create a Swift class to represent the response 1-创建一个Swift类来表示响应

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"
    }
}

2- Parse the JSON 2-解析JSON

//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)
}

An example using Swifty 使用Swifty的示例

As explained in the official documentation : 官方文档中所述

1- Convert JSON string to SwiftyJSON object 1-将JSON字符串转换为SwiftyJSON对象

if let dataFromString = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
    let json = JSON(data: dataFromString)
}

2- Access specific element 2-访问特定元素

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

2'- Loop over the elements 2'-循环元素

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的逻辑。

AlamofireObjectMapper AlamofireObjectMapper

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM