Created
August 11, 2016 19:45
-
-
Save 4xes/bb5c85e9a3b742bb7cc4ef6f77912d7c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: To run this playground start a SimpleHTTPServer on the commandline like this: | |
//: | |
//: `python -m SimpleHTTPServer 8000` | |
//: | |
//: It will serve up the current directory, so make sure to be in the directory containing episodes.json | |
import UIKit | |
import PlaygroundSupport | |
typealias JSONDictionary = [String: AnyObject] | |
let url = URL(string: "http://localhost:8000/episodes.json")! | |
struct Episode { | |
let id: String | |
let title: String | |
} | |
extension Episode { | |
init?(dictionary: JSONDictionary) { | |
guard let id = dictionary["id"] as? String, | |
let title = dictionary["title"] as? String else { return nil } | |
self.id = id | |
self.title = title | |
} | |
} | |
struct Media {} | |
struct Resource<A> { | |
let url: URL | |
let parse: (Data) -> A? | |
} | |
public enum Result<A> { | |
case success(A) | |
case error(Error) | |
} | |
extension Result { | |
public init(_ value: A?, or error: Error){ | |
if let value = value { | |
self = .success(value) | |
} else{ | |
self = .error(error) | |
} | |
} | |
public var value: A? { | |
guard case .success(let v) = self else { | |
return nil | |
} | |
return v | |
} | |
} | |
public enum WebserviceError: Error { | |
case other | |
} | |
extension Resource { | |
init(url: URL, parseJSON: (AnyObject) -> A?) { | |
self.url = url | |
self.parse = { data in | |
let json = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) | |
return json.flatMap(parseJSON) | |
} | |
} | |
} | |
extension Episode { | |
static let all = Resource<[Episode]>(url: url, parseJSON: { json in | |
guard let dictionaries = json as? [JSONDictionary] else { return nil } | |
return dictionaries.flatMap(Episode.init) | |
}) | |
} | |
func mainQueue(block: ()->()){ | |
DispatchQueue.main.async { | |
block() | |
} | |
} | |
final class Webservice { | |
func load<A>(resource: Resource<A>, completion: (Result<A>) -> ()) { | |
URLSession.shared.dataTask(with: resource.url) { data, _, _ in | |
let parsed = data.flatMap(resource.parse) | |
let result = Result(parsed, or: WebserviceError.other) | |
mainQueue { | |
completion(result) | |
} | |
}.resume() | |
} | |
} | |
PlaygroundPage.current.needsIndefiniteExecution = true | |
Webservice().load(resource: Episode.all) { result in | |
print(result) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment