NSURL Connection sendAsynchronousRequest How to save the response?

Ælex picture Ælex · Apr 24, 2012 · Viewed 7.1k times · Source
.h
@property (strong) NSString *reply;

I have the following method:

.m
@synthesize reply;

- (void)send
 {
 [NSURLConnection sendAsynchronousRequest:[self request] 
                 queue:[[NSOperationQueue alloc] init] 
                 completionHandler:
                        ^(NSURLResponse *response, NSData *data, NSError *error)       
                        {
                            if (error)
                            {
                                //NSLog(@"Error,%@", [error localizedDescription]);
                                [self setReply: [[NSString alloc] initWithString:[error localizedDescription]]];
                            }
                            else 
                            {
                                //NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
                                [self setReply: [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]];
                            } 
                        }];

}

Now, I have tried to return a value from the block/handler, but apparently this is not possible ( or I haven't figured out the syntax yet ).

I have tried to set a local variable to get the value of the reply (Data) but it produces errors.

The only way that errors were not produced is by using a class property. But when I try to read the value of [self reply] it is null, which makes me think that it is never set.

I understand that the sendAsync function is threaded and asynchronous, so is that the reason that the value of [self reply] is null, while when I use a sendSynchronousRequest, I always get a reply ???

What am I doing wrong, and how can I return a value from within the completionHandler ???

Edit#1: It appears to me that Im doing something very wrong. I was tracing into the code, and when I used the synchronous send, everything worked fine. Using the asynchronous one, the actual call to sendAsynchronousRequest was never executed, making me think that the thread is not being invoked, and hence the empty value.

Edit#2: I have found a way around this, by adding the following:

[NSURLConnection sendAsynchronousRequest:[self request] 
                 queue:[NSOperationQueue alloc] init
                 completionHandler:
                        ^(NSURLResponse *response, NSData *data, NSError *error)       
                        {
                            if (error)
                            {
                                //NSLog(@"Error,%@", [error localizedDescription]);
                                [self setReply: [[NSString alloc] initWithString:[error localizedDescription]]];
                            }
                            else 
                            {
                                //NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
                                [self setReply: [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]];
                            } 
                        }];

[[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 2]];

However, I am not entirely sure I understand how it works. I imagine that RunLoop tells the async operation to run for 2 seconds ( I can verify because when setting the date interval to a low value, I get a null response, due to testing with a live server ). What I do not understand, is when I just tell the RunLoop to run, it keeps blocking everything forever, as if the current thread never terminated.

Answer

tronbabylove picture tronbabylove · Apr 24, 2012

Get rid of that runUntilDate and try using [NSOperationQueue mainQueue], see if that changes anything.

[NSURLConnection sendAsynchronousRequest:[self request] 
             queue:[NSOperationQueue mainQueue]
             completionHandler:
                    ^(NSURLResponse *response, NSData *data, NSError *error)...