I need to build Arrays
for a Grouped UITableView
, with a Title and Detail line in each table cell. I've got my json output from the server putting it in the right shape to iterate through the UITableViewDataSource
methods. But what's the simplest way to convert these to a readable array that those UITableView
functions can reference?
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.
"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's my Alamofire async function that grabs the 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
}
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]
}
Alternatively, You can use JSON parsing libraries like Argo or SwiftyJSON, which were created to simplify the JSON parsing. They are both well tested and will handle edge cases for you, like missing parameters in the JSON responses etc.
Assuming the JSON response has this format (from 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.
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. 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. 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.
AlamofireObjectMapper
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With