var matchmakingIds: [Int] = [] for categoryDictionary in categoryDictionaries { if let title = categoryDictionary["title"] as? String, title == "Matchmaking"{ guard let children = categoryDictionary["children"] as? [NSDictionary] else { print("Cannot find key 'children' in \(categoryDictionary)") return } for child in children { guard let categoryId = child["categoryId"] as? Int else { print("Cannot find key 'categoryId' in \(child)") return } matchmakingIds.append(categoryId) } } }
Category: Swift / SwiftUI
JSON Example
{ "first": "John", "last": "Smith", "age": 35, "employeed": true, "hobbies": [ "fishing", "bowling", "programming" ], "relatives": { "mother": "Susan", "father": "Eric", "siblings": null } }
Here is a simple mapping JSON types to Swift types(JSON –> Swift)
null ==> nil
Number ==> Int, Float, Double
String ==> Bool
Array ==> [AnyObject]
Object ==> [String:AnyObject]
guard let arrayOfPhotoDictionaries = photosDictionary["photo"] as? [[String:AnyObject]] else { print("Cannot find key 'photo' in \(photosDictionary)") return }
for (index, photo) in arrayOfPhotoDictionaries.enumerated(){ print("\(index):\(photo)") }
let rarities = ["Free", "Common"] for rarity in rarities { numCostForRarityItemsDictionary[rarity] = 0 sumCostForRarityDictionary[rarity] = 0 } guard let rarityForCard = cardDictionary["rarity"] as? String else { print("Cannot find key 'rarityForCard' in \(cardDictionary)") return } numCostForRarityItemsDictionary[rarityForCard]! += 1 sumCostForRarityDictionary[rarityForCard]! += manaCost guard let arrayOfBasicSetCardDictionaries = parsedHearthstoneJSON["Basic"] as? [[String:AnyObject]] else { print("cannot find key 'basic" in \(parsedHearthstoneJSON)") return }
Parsing JSON
keyX, valueX: numbers, array, even dictionary
Parsing JSON
1. get the raw JSON data
2. parse the JSON data into a funcation object
3. grab the data from the foundation object
if let photosDictionary = parseResult[Constants.FlickrResponseKeys.Photos] as? [String: AnyObject], photoArray = photosDictonary[Constants.FlickrResponseKeys.Photo] as? [String:AnyObject]{ let randomPhotoIndex = Int(ar:4random_uniform(UInt32(photoArray.count))) }
private func getImageFromFlickr(){ let methodParameters = [ Constants.FlickrParameterKeys.Method: Constants.FlickrParameterValues.GalleryPhotosMethod, Constants.FlickrParameterKeys.APIKey: Constants.FlickrParameterValues.APIKey, Constants.FlickrParameterKeys.GalleryID: Constants.FlickrParameterValues.GalleryID, Constants.FlickrParameterKeys.Extras: Constants.FlickrParameterValues.MediumURL, Constants.FlickrParameterKeys.Format: Constants.FlickrParameterValues.ResponseFormat, Constants.FlickrParameterKeys.NoJSONCallback: Constants.FlickrParameterValues.DisableJSONCallback ] let session = URLSession.shared lel urlString = Constants.Flickr.APIBaseURL + escapedParameters(methodParameters as [String:AnyObject]) let url = URL(string: urlString)! let request = URLRequest(url: url) let task = session.dataTask(with: request){ (data, response, error) in func displayError(_ error: String){ print(error) print("URL at time of error: \(url)") performUIUpdatesOnMain{ self.setUIEnabled(true) } guard(error == nil) else { displayError("There was an error with your request: \(error)") return } guard let statusCode = (response as? HTTPURLResponse)?.statusCode, statusCode displayError("Your request returned a status code other than 2xx!") return } guard let data = data else { displayError("No data was returned by the request!") return } let parsedResult: [String:AnyObject]! do { parsedResult = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:AnyObject]) } catch { displayError("Could not parse the data as JSON:'\(data)'") return } guard let stat = parsedResult[Constants.FlickrResponseKeys.Status] as ? String, stat == Constants.FlickrResponseValues.OKStatus else { displayError("Cannot find keys '\(Constants.FlickrResponseKeys.Photos)'") return } let randomPhotoIndex = Int(arc4random_uniform(UInt32(photoArray.count))) let photoDictionary = photoArray[randomPhotoIndex] as [String:AnyObject] let photoIitle = photoDictionary[Constants.FlickrResponseKeys.Title]as? String guard let imageUrlString = photoDictionary[Constants.FlickrResponseKeys.MediumURL] as? String else { displayError("Cannot find key '\(Constants.FlickrResponseKeys.MediumURL)' in \(photoDictionary)") return } let imageURL = URL(string: imageUrlString) if let imageData = try? Data(contentsOf: imageURL!){ performUIUpdatesOnMain { self.setUIEnabled(true) self.photoImageView.image = UIImage(data: imageDAta) self.photoTitleLabel.text = photoTitle ?? "(Untitled)" } } else { displayError("Image does not exist at \(imageURL)") } task.resume()
Basics of Serialization
if let data = data { let parsedResult: AnyObject! do { parsedResult = try NSJSONSerialization.JSONObjectWithData(data, options: AllowFraments) } catch { displayError("could not parse the data as JSON: '\(data)'") return } }
Making a request
let urlString = constant.Flickr.APIBaseURL + escapeParameters(methodParameters) let url = NSURL(string: urlString)! let request = NSURLRequest(URL: url) let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ (data, response, error) in if error == nil { print(data) } }
Escaping Parameters
private func escapedParameters(parameters: [String:]) -> String { if parameters.isEmpty { return "" } else { var keyValuePairs = [String]() for(key, value) in parameters { let stringVavlue "\(value)" let escapeValue = stringValue. stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()) keyValuePairs.append(key + "=" + "\(escapedValue!)") } return "?\(keyValuePairs.joinWithSeparator("&"))" } }
let someParameters = [ "course": "networking", "hogehoge":"ios", "quiz":"escaping parameters" ] print(escapedParameters(someParameters))
flickr API Method
flickr.galleries.getPhotos – to get a list of photos for a gallery
flickr.peoplegetPublicPhotos – to get a list of public photos for the given user
flickr.stats.getPhotoStas- to get the number of views, comment and favoites on a photo for a fiven date
flickr.urls.getUserPhotos- to get the url to a user’s photos
specifies the API
https://api.flickr.com/services/rest?method=flickr.galleries.getPhotos&api_key=hogehoge&gallery_id=hogehoge&extras=url_m&format=json&nojsoncallback=1&api_sig=hogehoge
import UIKit class ViewController: UIViewController { @IBOutlet weak var photoImageView: UIImageView! @IBOutlet weak var photoTitleLabel: UILabel! @IBOutlet weak var grabImageButton: UIButton! @IBAction func grabNewImage(_ sender: AnyObject){ setUIEnabled(false) getImageFromFlickr() } private func setUIEnabled(_ enabled: Bool){ photoTitleLabel.isEnabled = enabled grabImageButton.isEnabled = enabled if enabled { grabImageButton.alpha = 1.0 } else { grabImageButton.alpha = 0.5 } private func getImageFromFlickr(){ } } }
App Transport Security(ATS)
Client <-http-> Server
Get in touch with the people running the server
Web Services and API
client(app) HTTP server
Flicker API document
https://www.flickr.com/services/api/
42 *, 43 +, 44,, 45 -, 46.,47/,
https://api.flicker.com/services/rest/?method=*&api_key=*&text=*&extras=url_m
some of API
OpenMenu API, World Bank API, Sunlight API, Gilt API, Riot GAmes API
To use an API:
1. Sign up for an account with the service
2. Register the app
3. [Usually] source authentication process
NSURLSession
network requests are known as “tasks”
->
NSURLSessionTask
Data: into memory as NSData
Download:
Upload: specialized for uploading
Apple Documentation: URLSessionTask
https://developer.apple.com/documentation/foundation/urlsessiontask
Apple Documentation: URLSessionDataTask
Apple Documentation: URLSessionDownloadTask
Apple Documentation: URLSessionDelegate
Apple Documentation: URLSessionDataDelegate
Apple Documentation: URLSessionDownloadDelegate
Apple Documentation: URLSessionTaskDelegate
import UIKit class ViewController: UIViewController { @IBOutlet weak var imageView: UIImageView! override func viewDidLoad(){ super.viewDidLoad() let imageURL = NSURL(string: "https://upload.wikimedia.org/wikipedia/commons/4/4d/Cat_November_2010-1a.jpg"); let task = NSURLSession.sharedSession().dataTaskWithURL(url: NSURL, completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void) } }
if error == nil { let downloadedImage = UIImage(data: data!) self.imageView.image = downloadedImage }
GET Request
client – Server
Understanding New Concepts
GET request: An HTTP request where a client requests a specified resource from a server.
HTTP method: Another term for the type of HTTP request.
URL: Specifies a location for retrieving data over the network.
Status code: A number returned in response to an HTTP request that indicates the results of the request.
Client: The role that an iPhone play if it is accessing data from the network(ex. downloading images from Facebook)
import UIKit class ViewController: UIViewController { @IBOutlet weak var imageView: UIImageView! override func viewDidLoad(){ super.viewDidLoad() let imageURL = NSURL(string: "https://upload.wikimedia.org/wikipedia/commons/4/4d/Cat_November_2010-1a.jpg"); NSURLSession.sharedSession() } }