We just created our API Manager folder. Now, let's create the API Manager file:
- Right-click on the Misc folder and select New File.
- On the Choose a template for your new file screen, select iOS at the top. Then, select Swift File. Then, hit Next.
- Name this file RestaurantAPIManager, and hit Create.
We need to define our class definition first; therefore, add the following to the import statement:
- Part A: Here, we define the class:
struct RestaurantAPIManager {
- Part B: The loadJSON() method is known as a type method because it has the static keyword in front of it. Type methods are called using the dot syntax. Static functions cannot be overridden:
static func loadJSON(file name:String) -> [[String:AnyObject]] {
The next bullet list explains what we need to write when we want to call the loadJSON method inside the RestaurantAPIManager file.
- Part C: Calling this method will return an array of dictionary objects. If this sounds familiar, it is because our plist data returns the same thing:
var items = [[String: AnyObject]]()
- Part D: On this line, we declare an array of dictionary objects:
guard let path = Bundle.main.path(forResource: name, ofType: "json"), let data = NSData(contentsOfFile: path) else {
return [[:]]
}
- Part E: Since we are not loading from the internet, we need to make sure that we call the right filename. If the path is found and there is nothing wrong with the data, we will use the data. Otherwise, we will return an empty array with no dictionary objects.
Here, we are using a do...catch. As a reminder, a do-catch statement is used to handle errors by running a block of code. To employ it, we must utilize it with what is known as a try. First, we need to try and serialize or convert the data from the JSON file; if we are successful, we can then access the information inside that file. To obtain the restaurant items in the JSON file (all of which are located inside the restaurant's node), we used json["restaurants"].
Next, we cast this using as? as an array of dictionary objects. Also, since our data types are mixed, we used AnyObject to accept the dictionary of mixed data types. Finally, we set our data to the array of items. We now have the same structure, and the array of dictionary objects that we had in the Map section:
do {
let json = try JSONSerialization.jsonObject(with: data as Data, options: .allowFragments) as AnyObject
if let restaurants = json as? [[String: AnyObject]] {
items = restaurants as [[String : AnyObject]]
}
}
- Part F: This catch only runs if there is a problem serializing the data from the file. If there is a problem, we will return an empty array with no dictionary objects. Using a do-catch allows for our app to keep running without crashing:
catch {
print("error serializing JSON: (error)")
items = [[:]]
}
- Part G: Finally, if all goes well, we return the array of dictionary items back:
return items
This entire class is built so that we can pass any name we want; it will return data if it finds the file.