ios - Error handling in block with Swift syntax -
the error handling here doesn't feel right. have suggests how improve it? using optional binding establish errors , return value variable.
that cool?
class chargepointsfetcher { func getdevices(location: nsurl, completion handler:([chargedevice]?, error: nserror?) -> void) { let request = nsurlrequest(url: location) let session = nsurlsession.sharedsession() let task = session.datataskwithrequest(request, completionhandler: { (let data, let response, let error) -> void in var returnvalue: nserror? if let e = error { returnvalue = e } var collection: [chargedevice]? if returnvalue == nil { collection = [chargedevice]() var parsingerror: nserror? if let json: nsdictionary = nsjsonserialization.jsonobjectwithdata(data, options: .allowfragments, error: &parsingerror) as? nsdictionary { if let chargedevices = json.valueforkey("chargedevice") as? nsarray { chargedevice in chargedevices { let device = chargedevice() collection!.append(device) } } } if let e = parsingerror { returnvalue = e } } dispatch_async(dispatch_get_main_queue(), { () -> void in handler(collection, error: returnvalue) }) }) } }
in opinion, should try hard avoid (value?, error?)
pattern when can. creates bad corner cases since 2 combinations illegal. instead, when possible, suggest (value, error?)
time value
has sensible "zero". in case "zero" "empty array". matches objc sense closely, since nil
nsarray similar empty array.
doing that, can substantially simplify code:
func getdevices(location: nsurl, completion handler:([chargedevice], error: nserror?) -> void) { // note error marked "var" can modify it, , switched nserror! nserror? let task = session.datataskwithrequest(request, completionhandler: { (let data, let response, var error: nserror?) -> void in var result = [chargedevice]() if error == nil { // avoid nsarray , nsdictionary wherever can in swift if let json = nsjsonserialization.jsonobjectwithdata(data, options: .allowfragments, error: &error ) as? [string:anyobject], chargedevices = json["chargedevice"] as? [anyobject] { // map simpler in case, in full code, may fine fine result = chargedevices.map{ _ in chargedevice() } } } dispatch_async(dispatch_get_main_queue(), { () -> void in handler(result, error: error) }) }) }
note in code , code, incorrect valid json not generate error of kind. it'll quietly skip through as?
calls. move of json work function keep closure getting out of hand.
another approach here called result
. preferred example rob rix's. though i've done lot of work on result
, i've find difficult bridge cocoa cleanly. it's useful if entire program uses it, , if encapsulate cocoa interaction, i've found cumbersome use one-off solution. (many people disagree me here, it's experience. result
worth exploring form own opinion.)
Comments
Post a Comment