JSON and iOS
Because the components in a JSON string can be represented using dictionary objects and arrays in iOS, manipulating JSON strings in iOS is extremely easy.
Consider the following code snippet in Swift:
var courses = [ "IOS101": [ "title" :"Foundation of iPhone Programming", "duration": 2, "starttime": 900, "endtime": 1700, "dates" : ["25/02/2015", "09/03/2015"] ], "IOS301": [ "title" :"Advanced iOS - iBeacon Programming", "duration": 1, "starttime": 900, "endtime": 1700, "dates" : ["12/03/2015"] ] ]
Using type inference, courses is inferred to be of type NSDictionary.
- Each element has a key (“IOS101” and “IOS301”), and each key has a value.
- Each value is another NSDictionary object with keys (“title”, “duration”, “starttime”, etc.) and values.
- In particular, the “dates” key has a value of type NSArray (of strings“25/02/2015”, “09/03/2015”, etc.).
Persisting a Dictionary as JSON
You could persist the courses dictionary as a JSON string and save it to a file, such as the Documents folder in your application sandbox. The following code snippet shows how you can create a filename to save the dictionary as a file in the Documents folder:
//---get the path of the Documents folder--- var paths = NSSearchPathForDirectoriesInDomains( NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true) var documentsDirectory = paths.first as NSString //---full path of file to save in--- var filePath = documentsDirectory.stringByAppendingPathComponent("Courses.json")
To save the dictionary to a file, use the following code snippet:
var outputStream = NSOutputStream(toFileAtPath: filePath, append: false) outputStream?.open() NSJSONSerialization.writeJSONObject( courses, toStream: outputStream!, options: NSJSONWritingOptions.PrettyPrinted, error: nil) outputStream?.close()
You basically use the NSOutputStream class to open an output stream, and then use the writeJSONObject:toStream:options:error: method of the NSJSONSerialization class to use the output stream to write the dictionary object to file. Interestingly, you can use the NSJSONWritingOptions.PrettyPrinted option to add whitespaces to make the resultant JSON string more readable (with additional formatting). However, this approach takes additional spaces on file, so if you're concerned about storage sizes, you should use the NSJSONWritingOptions.allZeros option instead.
To verify that the JSON string is written correctly to file, you can read it from file by using the following code snippet:
var JSONString = String(contentsOfFile: filePath, encoding: NSASCIIStringEncoding, error: nil) println(JSONString!)
That code snippet prints the following result for the Swift code shown earlier:
{ "IOS301" : { "starttime" : 900, "dates" : [ "12\/03\/2015" ], "title" : "Advanced iOS - iBeacon Programming", "endtime" : 1700, "duration" : 1 }, "IOS101" : { "starttime" : 900, "dates" : [ "25\/02\/2015", "09\/03\/2015" ], "title" : "Foundation of iPhone Programming", "endtime" : 1700, "duration" : 2 } }
Converting JSON to Dictionary
Now that you have the Dictionary object saved as a JSON string, it's usually common to do the reverse—load the JSON back into a Dictionary object and then retrieve the required data. To do that, you can use the NSInputStream class to open an input stream, and then use the NSJSONSerialization class's JSONObjectWithStream:options:error: method to use the input stream to read the JSON file. Once the JSON file is read, you can typecast it as an NSDictionary object.
var inputStream = NSInputStream(fileAtPath: filePath) inputStream?.open() var coursesRead = NSJSONSerialization.JSONObjectWithStream( inputStream!, options: NSJSONReadingOptions.allZeros, error:nil) as NSDictionary inputStream?.close()
The coursesRead object would now be of type NSDictionary. To print out the details of the courses, you can first obtain all the keys in coursesRead:
var courseIDs = coursesRead.allKeys
The courseIDs would now be an array. You can iterate through the keys using a For-In loop, like this:
for id in courseIDs { println(id) println("******") var courseDetails = coursesRead[id as String] as NSDictionary var title = courseDetails["title"] as String var startTime = courseDetails["starttime"] as Int var endTime = courseDetails["endtime"] as Int var duration = courseDetails["duration"] as Int var dates = courseDetails["dates"] as NSArray println("\(title) - \(duration) days") println("Timing: \(startTime) to \(endTime) hrs") print("Dates:") for date in dates { print(" \(date)") } println() }
That code snippet prints out the following output:
IOS101 ****** Foundation of iPhone Programming - 2 days Timing: 900 to 1700 hrs IOS301 ****** Advanced iOS - iBeacon Programming - 1 days Timing: 900 to 1700 hrs Dates: 12/03/2015