0

I have seen a lot of tutorials about nsurl asynchronous. I followed those tutorials and implement following.

-(id) connect_asych:(NSDictionary *)input page:(NSString *)page{
    NSString* urlString= [@"*s.com/music/" stringByAppendingString:page];
    NSURL *url = [NSURL URLWithString:urlString];
    //initialize a request from url
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[url standardizedURL]];

    //set http method
    [request setHTTPMethod:@"POST"];
    //initialize a post data

    NSString *post = [self convert:input];


    //set request content type we MUST set this value.

    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

    //set post data of request
    [request setHTTPBody:[post dataUsingEncoding:NSUTF8StringEncoding]];
    NSError *error = nil;
    NSHTTPURLResponse *responseCode = nil;
    NSOperationQueue *queue = [NSOperationQueue mainQueue];


    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError  *error1) {
      if(error !=nil){

          _responseData=nil;

      }
        [_responseData appendData: data];
      NSLog(@"%@",_responseData);
    }];


    id object = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingAllowFragments error:&error];
    if(error !=nil){
        _error=[[NSString alloc] initWithFormat:@"error"];
        return error;
    }
    return object;
}

if my viewdidload, I called the above method.

I got the data from the database successfully by using synchronous method. The problem is when I used asynchronous method, I could not get data. Should I call asynchronous method in the viewdidload?

Rob
  • 415,655
  • 72
  • 787
  • 1,044
user2612912
  • 63
  • 1
  • 6

2 Answers2

0

You are using an asynchronous method but don't wait for its execution

_responseData is used right after the asynchronous call. At this time your call is not finished, therefore _responseData not set.

You have to provide a block for callback in your connect_async method and execute that callback when your sendAsynchronousRequest is finished.

I wrote some comments

[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError  *error1) {
    if(error !=nil) {
        _responseData=nil;
    }

    [_responseData appendData: data];
    // right here you have to execute some callback function

    NSLog(@"%@",_responseData);
}];

// at this time your sendAsynchronousRequest is not finished
// _responseData will always be unset at this time
id object = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingAllowFragments error:&error];
if(error !=nil) {
    _error=[[NSString alloc] initWithFormat:@"error"];
    return error;
}

// note: it's always a bad idea to try to return a result of an asynchronous call this way. It will never work because of the asynchronous nature.
return object;

For information about how to implement blocks for callback

Please refer to this answer: Implementing a method taking a block to use as callback

TL;DR

+ (void)myMethod:(UIView *)exampleView completion:(void (^)(BOOL finished))completion {
    if (completion) {
        completion(finished);
    }
}
Community
  • 1
  • 1
Tuan
  • 893
  • 1
  • 9
  • 24
-1

You hâve to add the processions of data in the same block juste after [_responseData appendData: data];

Idali
  • 1,023
  • 7
  • 10