Convert JSON to array in Swift 2

I need to build Arrays for a Grouped UITableView , with a Title and Detail line in each cell of the table. I have my json output from a server that puts it in the correct form for repetition using the UITableViewDataSource methods. But what is an easy way to convert them into a readable array that these UITableView functions can use?

The header array refers to Group headers, so it's just a one-dimensional array. I can repeat it. The heading and detail matrices are two-dimensional. I cannot figure out how to do this in 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

Here is my Alamofire asynchronous function that captures data:

 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 } 
+5
source share
4 answers

Alternatively, you can use JSON parsing libraries such as Argo or SwiftyJSON that were created to simplify JSON parsing. They are both well tested and will handle red cases for you, such as missing parameters in JSON responses, etc.

An example of using Argo:

Assuming the JSON response has this format (from the Twitter API )

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

1- Create a Swift class to represent the response

Note that Response is a class that contains a User array, which is another class that is not shown here, but you get the point.

 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- JSON parsing

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

Swifty example

As described in the official documentation:

1- Convert JSON string to SwiftyJSON object

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

2- Access to a specific item

If the data is an array, use an index

 //Getting a double from a JSON Array let name = json[0].double 

If the data is a dictionary, use the key

 //Getting a string from a JSON Dictionary let name = json["name"].stringValue 

2'- Loop over elements

Array

 //If json is .Array //The `index` is 0..<json.count 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 } 
+2
source

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 as follows:

 if let dict = convertStringToDictionary(jsonText) { let array = dict["headings"] as? [String] } 
+4
source

It looks like you get the Dictionary from json, and each key contains Array , you can try something like this, first declare a single instance of the Dictionary and use it with the TableViewDataSource methods.

 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

 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 } 
+2
source

I would suggest using AlamofireObjectMapper. The library allows you to easily map objects to json and, in combination with Alamofire, can display and return your object in server response. The object display 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 separate the json display and parsing logic from your TableViewController.

AlamofireObjectMapper

+2
source

All Articles