ios - telling multiple events apart with NSURLConnection and asynchronous connections -
i'm writing ipad app populates ui based on json data grabbed server. i'm using nsurlconnection make initial connection thusly:
// create request. nsmutableurlrequest* request = [nsmutableurlrequest requestwithurl:[nsurl urlwithstring:@"http://foo.com/login"]]; [request sethttpmethod:@"post"]; nsstring* credentials = @"username=testfoo&password=passfoo"; self.ffooconnectiondata = [credentials datausingencoding:nsutf8stringencoding]; [request sethttpbody:self.ffooconnectiondata]; self.ffoodataconnection = [[nsurlconnection alloc] initwithrequest:request delegate:self]; [self.ffoodataconnection start];
now, issue can catch response in 'connectiondidx' delegate functions, subsequent steps, how should proceed? if synchronous connection, matter easier, i'd wait return value, asynchronous connection, how handle subsequent requests? how tell 1 event (like logging in) (like requesting specific data ui)?
each asynchronous method, function or asynchronous operation has means "signal" client has finished.
nsurlconnection
uses delegate methods signal "events" delegate. delegate method connectiondidfinishloading:
respectively connection:didfailwitherror:
signal data downloaded, respectively error has occurred.
the "call site" (that delegate instance in case of nsurlconnection
) should define what next within delegate method.
you need ensure "execution context" next action appropriate: example, in setup of nsurconnection
, delegate methods may invoked on private secondary thread. suppose, client want's use downloaded data , display in table view. uikit methods shall invoked on main thread. thus, 1 need ensure through, example, dispatching actions onto appropriate queue, main queue.
handling more complex nsurlconnection
tasks asynchronously, delegate approach signal asynchronous events becomes unwieldy. better approach use asynchronous operations network tasks. can "wrap" nsurlconnection
task subclass of nsoperation
dedicated purpose. sophisticated class handles complexity internally , provided easy use api. client needs specify "completion handler" (a block) instead of handling delegate methods. reduces dependencies between objects , tremendously simplifies coding task.
then, it's same said above:
the "call site" (that client of nsoperation
network subclass) should define what next within completion handler.
well, nsoperation
subclass may become unwieldy, if have setup many parameters request , nasty , elaborate error handling. might want simpler way invoke it. so, may define very particular "method" say,
-(void) fetchmessageswithuser:(user*)user completion:(completion_t)completionhandler;
internally, implement method based on subclass of nsoperation
implemented on top of nsurlconnection
. put nasty boiler plate stuff it, including extensively error checks.
then, code becomes more "clean":
- (void) fetchusermessages { [self fetchmessageswithuser:self.currentuser completion:^(id result){ // result nsdata containing json (array of messages user) or nserror if (![result iskindofclass:[nserror class]]) { nsarray* messages = ... // invoke json parser dispatch_async(dispatch_get_main_queue(), ^{ [self updateviewwithmessages:messages]; }); } else { [self handleerror:result]; } }]; }
Comments
Post a Comment