import UIKit import XCPlayground XCPSetExecutionShouldContinueIndefinitely() typealias JSON = AnyObject typealias JSONDictionary = [String: JSON] typealias JSONArray = [JSON] let url = "http://api.openweathermap.org/data/2.5/weather?q=London,uk" let request = NSURLRequest(URL: NSURL.URLWithString(url)) final class Box { let value: A init(_ value: A) { self.value = value } } struct Weather { let id: Int let name: String static func create(id: Int)(name: String) -> Weather { return Weather(id: id, name: name) } } enum Result { case Error(NSError) case Value(Box) } func JSONString(object: JSON?) -> String? { return object as? String } func JSONInt(object: JSON?) -> Int? { return object as? Int } func JSONObject(object: JSON?) -> JSONDictionary? { return object as? JSONDictionary } infix operator >>> {associativity left precedence 150} func >>>(a: A?, f: A->B?) -> B? { if let x = a { return f(x) } else { return .None } } func getData(request: NSURLRequest, callback: (Result) -> ()) { let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, urlResponse, error in if let err = error { callback(Result.Error(err)) return } var jsonErrorOptional: NSError? let jsonOptional: JSON! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0), error: &jsonErrorOptional) // println(jsonOptional) if let err = jsonErrorOptional { callback(Result.Error(err)) return } if let json = jsonOptional >>> JSONObject { if let id = json["id"] >>> JSONInt { if let name = json["name"] >>> JSONString { let weather = Weather(id: id, name: name) callback(Result.Value(Box(weather))) return } } } } task.resume() } getData(request) { result in switch result { case let .Error(error): println(error) case let .Value(boxedUser): let weather = boxedUser.value println(weather.id) println(weather.name) } }