Ravi Ojha
Ravi Ojha

Reputation: 1480

Return Response data from nsurlconnection delegate method

Hi I am using a webservice for registration, I have made a separate class to hit the webservice and return the response on view class.

Here is my code on Button

-(IBAction)placeOrder:(id)sender
 {               
 url = [[NSURL alloc]initWithString:@"http://54.25fdg.239.126/tfl/index.php/service/register"];
 NSString *str = [NSString stringWithFormat:@"name=%@&phoneNumber=%@&emailAddress=%@&password=%@&addressLine1=%@&addressLine2=%@&city=%@&pincode=%@&landmark=%@&specialInstruction=%@",txtUserName.text,txtPhone.text,txtEmail.text,txtPassword.text,addressLine1Tf.text,addressLine2Tf.text,cityTf.text,pinCodeTf.text,landMarkTf.text,specialInstrTv.text];
 WebServices *webservice = [[WebServices alloc]init];
 [webservice getDataFromService:url data:str];
 responseDictionary = [webservice returnResponseData];
 }

After calling the getDataFromService method it calls returnRespnoseData method. Then it call the connection method which is called from getDataFromService. So I got the nil response from returnResponseData. Can any body tell me how can I manage it or how can I return the response from didfinishloading method to main view class? In webservice.m

-(void)getDataFromService:(NSURL *)url data:(NSString *)parameterString
 {
  NSData *postData = [parameterString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
  NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[postData length]];
  NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  [request setURL:url];
  [request setHTTPMethod:@"POST"];
  [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
  [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
  [request setHTTPBody:postData];
  NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
  [conn start];
 }

In connection last method I have got the response in a dictionary as jsonDec.

 -(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError* error ;
 _jsonDec = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingAllowFragments error:&error];
}

Return the jsonDec to View class

-(NSDictionary *)returnResponseData
{
 return _jsonDec;
}

Upvotes: 0

Views: 662

Answers (2)

Finn Fahrenkrug
Finn Fahrenkrug

Reputation: 91

To make sure that the app will return the jsondata to viewclass after the response has arrived define a block in the .h-file of your class:

typedef void(^getDataBlock)(id jsonObject);

Then your getDataFromService-method could look like this:

-(void)getDataFromService:(NSURL *)url data:(NSString *)parameterString getDataBlock:(getDataBlock)returnBlock{
NSLog(@"Getting Data");
NSData *postData = [parameterString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    NSError *error = [[NSError alloc] init];
    id jsonDec = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
    returnBlock(jsonDec);
}];
}

In your view class you can do this now:

-(void)test{
//Insert the right name for your class where you do the request and insert the right values
[backendClass getDataFromService:[NSURL URLWithString:@"www.google.de"] data:@"blablabla" getDataBlock:^(id jsonObject) {
   //Make sure you're on the mainthread for UI-updates
    dispatch_async(dispatch_get_main_queue(), ^{
        self.titleLabel.text = [jsonObject objectForKey:@"title"];
    });
}];
}

Upvotes: 1

Skyler Lauren
Skyler Lauren

Reputation: 3812

The issue is you are calling returnResponseData before you get the data back.

Assuming you are getting data back you will see that logs come back in an unexpected order.

-(IBAction)placeOrder:(id)sender
{
    NSLog(@"Button Pressed");     
    url = [[NSURL alloc]initWithString:@"http://54.254.239.126/tfl/index.php/service/register"];
    NSString *str = [NSString stringWithFormat:@"name=%@&phoneNumber=%@&emailAddress=%@&password=%@&addressLine1=%@&addressLine2=%@&city=%@&pincode=%@&landmark=%@&specialInstruction=%@",txtUserName.text,txtPhone.text,txtEmail.text,txtPassword.text,addressLine1Tf.text,addressLine2Tf.text,cityTf.text,pinCodeTf.text,landMarkTf.text,specialInstrTv.text];
    WebServices *webservice = [[WebServices alloc]init];
    [webservice getDataFromService:url data:str];
    responseDictionary = [webservice returnResponseData];
}

-(void)getDataFromService:(NSURL *)url data:(NSString *)parameterString
{
    NSLog(@"Getting Data");
    NSData *postData = [parameterString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[postData length]];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:url];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:postData];
    NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
    [conn start];
 }

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"Finished getting data");
    NSError* error ;
    _jsonDec = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingAllowFragments error:&error];
}

-(NSDictionary *)returnResponseData
{
    NSLog(@"Returning data");
    return _jsonDec;
}

You will need to wait until didFinishConnection is called before doing anything with _jsonDec. Also if you are updating UI you may want to make sure you are on the MainThread. "If" my memory is correct didFinishConnection may not come back on the main thread.

Upvotes: 1

Related Questions