Skip to content

Instantly share code, notes, and snippets.

@amadeu01
Last active February 12, 2018 02:55
Show Gist options
  • Save amadeu01/71695b633a4fa07264b5cd196c45e0c0 to your computer and use it in GitHub Desktop.
Save amadeu01/71695b633a4fa07264b5cd196c45e0c0 to your computer and use it in GitHub Desktop.
import UIKit
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let endpoint = "https://api.punkapi.com/v2/beers/1"
let url = URL(string: endpoint)!
typealias JSONDictionary = [String: Any]
struct Beer: Codable {
let id: Int
let name: String
}
extension Beer {
init?(json: JSONDictionary) {
guard let id = json["id"] as? Int,
let name = json["name"] as? String else {
return nil
}
self.id = id
self.name = name
}
}
struct Resource<A> {
let url: URL
let parse: (Data) -> A?
}
extension Resource {
init(url: URL, parseJSON: @escaping (Any) -> A?) {
self.url = url
self.parse = { data in
let json = try? JSONSerialization.jsonObject(with: data, options: [])
return json.flatMap(parseJSON)
}
}
}
extension Beer {
static let all = Resource<[Beer]>(url: url, parseJSON: { json in
guard let dictionaries = json as? [JSONDictionary] else { return nil }
return dictionaries.flatMap(Beer.init)
})
}
final class Webservice {
func load<A>(resource: Resource<A>, completion: @escaping (A?) -> ()) {
URLSession.shared.dataTask(with: resource.url) { data, response, error in
guard let data = data else {
completion(nil)
return
}
completion(resource.parse(data))
}.resume()
}
}
Webservice().load(resource: Beer.all) { result in
if let result = result as [Beer]! {
if let beer = result.first as! Beer! {
print(beer)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment