Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>As far as i can see you are not realizing the asynchronous nature of this process: actually since network or IO operations take a long time to complete we tend to prefer asynchronous access, i mean: the caller (View Controller) calls a message on the web API through the service and then STOPS WAITING FOR A RESPONSE. Actually the network processing could be done on a different process or thread or processor's core.</p> <p>Now then, how can the caller BE NOTIFIED by the service when the operation completes? For this to happen we must bind the two objects using Delegation: we create a protocol (it's just a declaration of messages that an object will be responding to) and we implement it in our View Controller, that way whoever will be using it will know for sure what messages are available. </p> <p>Then we will declare a delegate of type id in our service that will be called once the operations will be completed.</p> <p>It's almost like importing your ViewController.h in the service class and giving the service a pointer to the view controller, but done in the right way (without circular references and respecting SOLID principles)</p> <p>Now some code:</p> <pre><code>//service.h @protocol RemoteApiProtocol &lt;NSObject&gt; @required -(void) UserLoggingIn; -(void) UserLoggedIn:(User*)user; -(void) UserLoginError:(NSError *)error; @end </code></pre> <p>The protocol works like a small interface, it's a contract between two classes/objects. Then in your service you can declare field &amp; property for the protocol:</p> <pre><code>//Service.h #import &lt;UIKit/UIKit.h&gt; #import "AFNetworking.h" @interface Services : NSObject{ __weak id&lt;RemoteApiProtocol&gt; delegate; } @property (nonatomic, assign) id&lt;RemoteApiProtocol&gt; delegate; - (void) doSignUp:(NSMutableDictionary*)params; @end </code></pre> <p>At this point you implement the protocol in your view controller, integrating the contract you just build. This way the server will know that the delegate will always be able to respond to the protocol messages.</p> <pre><code>//SignUpViewController.h #import "Service.h" @interface SignUpViewController : UIViewController &lt;RemoteApiProtocol&gt; { Service * service; } @property (nonatomic, strong) Service * service; </code></pre> <p>After implementing the protocol you can assign your view controller as delegate for the server, this way the server, after calling the apis will be able to call the delegate with the result of the call. For this to happen you implement the protocols messages that will be called by the service:</p> <pre><code>//SignUpViewController.m #import "SignUpViewController.h" @implementation SignUpViewController @synthesize service = __service; - (IBAction) initSignUp:(id)sender { //create the service with params //... //assign self as the delegate self.service.delegate = self; [self.service doSignUp:params]; } #pragma mark - RemoteApiProtocol -(void) UserLoggingIn { //login started, //you can show a spinner or animation here } -(void) UserLoggedIn:(User*)user { //user logged in , do your stuff here } -(void) UserLoginError:(NSError *)error { NSLog(@"error: %@",error); } @end </code></pre> <p>And finally you call the messages in your service, after calling the apis in the success and error block:</p> <pre><code>// Service.m #import "Services.h" #import "Config.h" @implementation Services - (void) doSignUp:(NSMutableDictionary*)params { NSURL *url = [NSURL URLWithString:@"http://MYURL.COM"]; AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url]; NSURLRequest *request = [httpClient requestWithMethod:@"POST" path:@"signup.json" parameters:params]; AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { [self handleSignUp:JSON]; } failure:nil]; //Signaling the start of the signup operation to the delegate if(self.delegate){ [self.delegate UserLoggingIn]; } [operation start]; } - (User*) handleSignUp:(NSMutableArray*)json { User * user = nil; if ([[json valueForKey:@"success"] isEqualToString:@"true"]) { // create user here ... //call the delegate (view controller) passing the user if(self.delegate){ [self.delegate UserLoggedIn:user]; } }else{ //error handling if(self.delegate){ //NSError *error = ... //[self.delegate UserLoginError:error]; } } //return user; } @end </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload