Reputation: 141
I have a login method. Inside the method I use NSURLConnection to login and I would like the return the NSData response. The problem is that I return the NSData before the connection actually gets the data.
- (NSData*)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[responseData appendData:data]; //responseData is a global variable
NSLog(@"\nData is: %@", [[[NSString alloc] initWithData:responseData
encoding:NSUTF8StringEncoding]autorelease]);//this works
isLoaded = YES; //isLoaded is a BOOL
}
- (NSData*)login:(NSString*)username withPwd:(NSString*)password{
isLoaded = NO;
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];
if(connection){
NSLog(@"Connected");
}
while(isLoaded = NO){
[NSThread NSSleepForTimeInterval: 1];
}
isLoaded = NO;
return responseData;
}
The program gets stuck at the while loop, but without the while loop the program can retrieve the data from the server, it is just that the method seems to return responseData, before the delegate method changes it.
So my question is how can I make it so the method will return the responseData only after the server is done with it ?
Upvotes: 1
Views: 1372
Reputation: 16663
You can use the sync request method
- (NSData*)login:(NSString*)username withPwd:(NSString*)password
{
NSError *error = nil;
NSURLResponse *response = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]
return responseDate;
}
Upvotes: 0
Reputation: 52237
You should refactor your code.
You are using a asynchronous call (good), but you try to handle it synchronously (not so good — if not using a separate thread).
to use an asynchronous behavior, you need a callback, in cocoa-fashion this is usually a delegate method (or could be a block for newer code). Actually it is your connection:didReceiveData
. this method will work with the returned data — not the one, where you started the request. therefor usually methods, that start a asynchronous request, do not return anything — and for sure not, what is expected to be return form the request.
- (void)login:(NSString*)username withPwd:(NSString*)password
{
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
//Note: you cannot change the delegate method signatures, as you did (your's returns an NSData object)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[self.responseData appendData:data]
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//Now that the connection was successfully terminated, do the real work.
}
look at this apple example code.
Upvotes: 1
Reputation: 4623
Unless otherwise specified, NSURLConnection loads a URL asynchronously. It uses deleegate callbacks to update the delegate about the progress of the URL download.
Specifically, Utilize NSURLConnection delegate's connectionDidFinishLoading: method. Your NSURLConnection object will call this once all the data has been loaded. It is within this method that you can return your data.
You can load the data synchronously but you may end up blocking UI.
Good luck!
Upvotes: 1