1

I'm calling one method from another method.The method exits in the middile. After completing some tasks, it will run the remaining method.

-(void)stateMethod{
    [self.pickerView selectRow:0 inComponent:0 animated:YES];
    lblTitle.text=@"State";
    self.stateTF.text=@"";
    self.stateTF.inputView=_pickerView;
    [self.stateTF setInputAccessoryView:toolBar];
    NSString * method=@"***************************?countryID=";
    NSString *urlString=[NSString stringWithFormat:@"%@%@%@",MAIN_URL,method,_countryId];
    NSURL *url_ac=[[NSURL alloc]initWithString:urlString];
    NSMutableURLRequest *request_ac=[[NSMutableURLRequest alloc]initWithURL:url_ac];
    [request_ac setValue:loginUser.acessTokenStr forHTTPHeaderField:@"access_token"];

   [NSURLConnection sendAsynchronousRequest:request_ac queue:[NSOperationQueue currentQueue] completionHandler:
 ^(NSURLResponse ac_response, NSData acData, NSError *connectionError) {
     if (connectionError)
     {
         NSLog(@"ERROR CONNECTING DATA FROM SERVER: %@", connectionError.localizedDescription);
     }
    else {            
    dispatch_async(dispatch_get_main_queue(), ^{
             NSString *responseString = [[NSString alloc] initWithData:acData encoding:NSUTF8StringEncoding];
             [self parseStateListResult:acData];
         });
     }
 }];  
}

I want the response when i'm calling the state method. Based on state method response,i'm executing one task after calling [self statemethod]. That task need 'state methodresponce. That task is executing before getting the data from state method. The method exits afterNSURLConnection` line. I want to run the method asynchronously. Please help me.

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • 4
    "The compiler is leaving the method at the middile"? What do you mean? – trojanfoe Aug 21 '19 at 13:01
  • I'm calling `stateMethod` from `another method`. compiler will compile upto `NSURLConnection` line,after that it will exit from the method and executing some tasks which are there after the line i.e., [self stateMethod]; .Again compiler entering to this method and executing remaining lines (i.e., after `NSURLConnection`). –  Aug 21 '19 at 13:53
  • 1
    When you say "compiling" are you sure you don't mean "running". You also seem confused about the concept of asynchronous operation as what you describe sounds right; i.e. the connection is established in the background and the completion handler is called when the response is received. – trojanfoe Aug 21 '19 at 13:58
  • you are telling correct.It's happening at the time of app running only. I put debuggers to see the flow of application,at that time method will exit at the middle. –  Aug 21 '19 at 14:04
  • Where exactly is it exiting? – trojanfoe Aug 21 '19 at 14:05
  • after `NSURLConnection` –  Aug 21 '19 at 14:06
  • 1
    But that is correct. The connection will happen in a background thread and `stateMethod` will exit. – trojanfoe Aug 21 '19 at 14:07
  • yes.It is correct but i want the response when i'm calling the `state method`. Based on `state method response`,i'm executing one task after calling `[self statemethod]`. That task need 'state method` responce. That task is executing before getting the data from `state method`. –  Aug 21 '19 at 14:14
  • Then I believe you want `URLSessionDataTask`. See [this tutorial](https://www.raywenderlich.com/3244963-urlsession-tutorial-getting-started). Although it's in Swift :-| – trojanfoe Aug 21 '19 at 14:17
  • How to use `NSSessionDataTask`. –  Aug 21 '19 at 14:19
  • [Here's an answer](https://stackoverflow.com/a/34200617/299924) with some code in Objective-C. – trojanfoe Aug 21 '19 at 14:22
  • `NSSessionDataTask` is also working same like `NSURLConnection` –  Aug 22 '19 at 05:39
  • I have got the output I want.I placed my task in `state method` after I got the Url responce by using condition.Thanks for your help. –  Aug 22 '19 at 06:03

1 Answers1

1

I'm calling one method from another method.The method exits in the middile. After completing some tasks, it will run the remaining method.

It doesn't exit in the middle... the part after the sendAsynchronousRequest call is a completion handler. It's a separate block of code that you're passing into the request to run at a later time. Think of it as a parameter to the method, not part of the code of stateMethod.

With that in mind, you can see that stateMethod really does run to the end, because the last line of code in the method is the sendAsyncronousRequest call.

Based on state method response, I'm executing one task after calling [self statemethod]. That task need state method responce. That task is executing before getting the data from state method. The method exits after NSURLConnection line. I want to run the method asynchronously.

Since you haven't given the name of the method that needs the response, let's just call it foo. Your problem is that the request is asynchronous, so foo gets called before the response is available. One way to handle that would be to put the call to foo inside the request's completion block, but you might not want to do that directly because stateMethod might be called from several places, only one of which subsequently calls foo. Instead, you might change stateMethod so that the caller can specify a completion block:

-(void)stateMethodWithCompletion:(nullable void (^)(NSURLResponse* response))stateCompletion {
    [self.pickerView selectRow:0 inComponent:0 animated:YES];
    lblTitle.text=@"State";
    self.stateTF.text=@"";
    self.stateTF.inputView=_pickerView;
    [self.stateTF setInputAccessoryView:toolBar];
    NSString * method=@"***************************?countryID=";
    NSString *urlString=[NSString stringWithFormat:@"%@%@%@",MAIN_URL,method,_countryId];
    NSURL *url_ac=[[NSURL alloc]initWithString:urlString];
    NSMutableURLRequest *request_ac=[[NSMutableURLRequest alloc]initWithURL:url_ac];
    [request_ac setValue:loginUser.acessTokenStr forHTTPHeaderField:@"access_token"];

    [NSURLConnection sendAsynchronousRequest:request_ac queue:[NSOperationQueue currentQueue] completionHandler:
        ^(NSURLResponse ac_response, NSData acData, NSError *connectionError) {
        if (connectionError) {
             NSLog(@"ERROR CONNECTING DATA FROM SERVER: %@", connectionError.localizedDescription);
        }
        else {
            if (stateCompletion != nil) {
                stateCompletion(acResponse);
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                     NSString *responseString = [[NSString alloc] initWithData:acData encoding:NSUTF8StringEncoding];
                     [self parseStateListResult:acData];
                 });
        }
    }];  
}

That replaces the old stateMethod, but if you want to have a version that doesn't have the extra parameter you can always do that too:

-(void)stateMethod {
     [self stateMethodWithCompletion:nil];
}
Caleb
  • 124,013
  • 19
  • 183
  • 272
  • I tried your code.It is also working same like before. –  Aug 22 '19 at 05:56
  • I have got the output I want.I placed my task in `state method` after I got the Url responce by using condition.Thanks for helping me. –  Aug 22 '19 at 06:01
  • Depending on what you're trying to do, you might need or want to run the `stateCompletion` block on the main thread. If so, move the `if (stateCompletion != nil)...` block inside the block that gets dispatched to the main thread. – Caleb Aug 22 '19 at 13:42