Created
June 17, 2015 17:31
-
-
Save algal/13ff4e78f1be42691d1b to your computer and use it in GitHub Desktop.
Helper to encapsulate loading JSON over the network.
This file contains hidden or 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
// | |
// MARK: generic networking and JSON-decoding helper | |
// | |
// give it a NSURLRequest and a session, it gives you back a aresult with an AnyObject or an NSError | |
public class JSONService | |
{ | |
/// returns JSON result on statusCode 200, and an error otherwise | |
public class func taskWithJSONRequest( | |
request:NSURLRequest, | |
session:NSURLSession, | |
completion:(JSONResult)->()) -> NSURLSessionDataTask | |
{ | |
let task = session.dataTaskWithRequest(request, completionHandler: { | |
(data:NSData!, response:NSURLResponse!, error:NSError!) -> Void in | |
if let error = error { | |
dispatch_async(dispatch_get_main_queue()) { | |
completion(JSONResult.Fail(error)) | |
} | |
} | |
else { | |
// assert: sub-HTTP networking succeeded | |
if let httpResponse = response as? NSHTTPURLResponse { | |
if httpResponse.statusCode < 200 || httpResponse.statusCode > 299 { | |
let error = NSError(domain: NSBundle.mainBundle().bundleIdentifier!, code: 0, userInfo: [NSLocalizedFailureReasonErrorKey : "http returned non-200 status code","result":httpResponse]) | |
dispatch_async(dispatch_get_main_queue()) { | |
completion(JSONResult.Fail(error)) | |
} | |
} | |
else { | |
// assert: ... and HTTP succeeded (200) | |
if let data = data { | |
var JSONError:NSError? | |
let JSONValue: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &JSONError) | |
if let JSONValue: AnyObject = JSONValue { | |
// assert: ... and JSON decoding succeeded | |
dispatch_async(dispatch_get_main_queue()) { | |
completion(JSONResult.Success(JSONValue)) | |
} | |
} | |
else { | |
if let JSONError = JSONError { | |
// JSON decoding failed | |
dispatch_async(dispatch_get_main_queue()) { | |
completion(JSONResult.Fail(JSONError)) | |
} | |
} | |
else { | |
Log_asWarn("ERROR: Apple violated its API contract. NSJSONSerialization.JSONObjectWithData returned a nil value, but did not populate its error object") | |
let myJSONError = NSError(domain: NSBundle.mainBundle().bundleIdentifier!, code: 0, userInfo: [NSLocalizedFailureReasonErrorKey :"NSJSONSerialization.JSONObjectWidthData returned nil and no error"]) | |
dispatch_async(dispatch_get_main_queue()) { | |
completion(JSONResult.Fail(myJSONError)) | |
} | |
} | |
} | |
} | |
} | |
} | |
else { | |
let errString = "ERROR: Apple violated its API contract. NSURLSession.dataTaskWithRequest returned a nil NSHTTPURLResponse object even though there was no NSError" | |
Log_asWarn(errString) | |
let myError = NSError(domain: NSBundle.mainBundle().bundleIdentifier!, code: 0, userInfo: [NSLocalizedFailureReasonErrorKey :errString]) | |
dispatch_async(dispatch_get_main_queue()) { | |
completion(JSONResult.Fail(myError)) | |
} | |
} | |
} | |
}) | |
task.resume() | |
return task | |
} | |
public enum JSONResult { | |
case Success(AnyObject) | |
case Fail(NSError) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment