Reputation: 41858
I have looked at NSURLConnectionDelegate connection:didReceiveData not working already, but there didn't seem to be any good result from that, so I am curious why I am not able to get any data.
I put in breakpoints in didReceiveResponse
and didReceiveData
.
It does print out "connection succeeded", so I know that the connection is started.
I am using ARC for memory management.
- (void)load {
request = [NSMutableURLRequest requestWithURL:myURL
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (conn) {
[conn start];
NSLog(@"connection succeeded, %s", [myURL description]);
responseData = [NSMutableData data];
} else {
NSLog(@"connection failed");
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
UPDATE:
To see how I test this look at Asynchronous unit test not being called by SenTestCase.
I did implement the two methods mentioned by jonkroll, in his answer, I just didn't show them, but, they also aren't being called.
I had added [conn start]
only because it wasn't working, and I was hoping that may solve it, but no such luck.
Upvotes: 0
Views: 1025
Reputation: 27147
When you declare your connection like this:
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
You are creating a local pointer. When your method completes, since it was the last strong reference to the NSURLConnection
, ARC
releases it. You need to use a strong ivar (and/or) property to hold a strong reference to the NSURLConnection
you create.
Edit
Here is basic sample of code that I tested in a sample project. Give it a run. Verbose logging helps.
@implementation <#Your class here#> {
// With ARC ivars are strong by default
NSMutableData *_downloadedData;
NSURLConnection *_connection;
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSHTTPURLResponse *realResponse = (NSHTTPURLResponse *)response;
if (realResponse.statusCode == 200){
// Really any 2** but for example
_downloadedData = [[NSMutableData alloc] init];
NSLog(@"Good response");
} else {
NSLog(@"Bad response = %i",realResponse.statusCode);
}
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
if (connection == _connection){
[_downloadedData appendData:data];
NSLog(@"Getting data...");
}
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
if (connection == _connection){
_connection = nil;
NSLog(@"We're done, inform the UI or the delegates");
}
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
_connection = nil;
NSLog(@"Oh no! Error:%@",error.localizedDescription);
}
- (void)load {
NSURL *url = [NSURL URLWithString:@"http://www.google.com/"];
NSURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60];
// Assign strong pointer to new connection
_connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(@"Connection was initialized? = %@",(!!_connection)?@"YES":@"NO");
}
@end
Upvotes: 3
Reputation: 15722
The NSURLConnection method initWithRequest
starts an asynchronous request for data from a url. Because the request is done asynchronously you can't expect to work with the response in the same method in which the request is invoked. Instead you need to do so in the NSURLConnection's delegate callback methods. You have already implemented didReceiveResponse:
and didReceiveData:
, but there are a couple others that will be useful to you.
If you want to look at the contents of the response you should do so in connectionDidFinishLoading:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// response is complete, do something with the data
NSLog(@"%@", responseData);
}
The fact that your code prints out "connection succeeded" doesn't really mean that the request was successful, only that the NSURLConnection object was created successfully. To test whether there was a problem with the connection you can implement the delegate method connection:didFailWithError:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"Connection failed! Error - %@ %@",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
Also there is no need to call [conn start]
. The request will be started automatically when you call initWithRequest:
I suggest reading Apple's documentation on Using NSURLConnection for more details.
Upvotes: 0