Skip to content

Instantly share code, notes, and snippets.

@4xes
Created August 11, 2016 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 4xes/bb5c85e9a3b742bb7cc4ef6f77912d7c to your computer and use it in GitHub Desktop.
Save 4xes/bb5c85e9a3b742bb7cc4ef6f77912d7c to your computer and use it in GitHub Desktop.
//: 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