I am trying to download multiple images from a URL stored in an XML feed. Getting the image urls from the XML is working correctly. However, the NSURLConnection is creating
You have to wait until the connection tells you it has finished before you can write the data. The connection is handled on another thread; if you try to access the data immediately on the original thread as you're doing, there won't be anything in it.
You should move the writeToFile:
call to the end of connectionDidFinishLoading:
, or to another method that you call from there. That's the first point where you know that the data has all been collected.
I'd also suggest creating the NSMutableData
instance in didRecieveResponse:
, so that you know that it is available at the correct time. That will be more readable/understandable. You can think of the delegate methods as a collective "scope" -- the data is only used inside of them, so it should be created inside of one of them.
In reply to your comment:
One possibility, since you have so much that needs to be done around this one download, and don't seem to be touching the GUI, is to run the whole parsingComplete:
method on a background thread, and using +[NSURLConnection sendSynchronousRequest:returningResponse:error:]. This way your code will just wait until the data comes back, in one piece, and you can write it immediately after the sendSynchronous...
call returns.
NSError * err;
NSURLResponse * response;
NSData * receivedData = [NSURLConnection sendSynchronousRequest:imageRequest
returningResponse:&response
error:&err];
if( !receivedData ){
/* Handle error */
}
/* Check response */
BOOL result = [receivedData writeToFile:fileOut atomically:YES];
/* check result, etc. */
You can use a CustomURLConnection
with Tag to name de images before they download.
With this code you can make a customURLConnection
, name it when you make the request, and ask for the name of the image in the connectionDidFinishLoading:
#import <Foundation/Foundation.h>
@interface CustomURLConnection : NSURLConnection
{
NSString *tag;
}
@property (nonatomic, retain) NSString *tag;
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately tag:(NSString*)aTag;
@end
#import "CustomURLConnection.h"
@implementation CustomURLConnection
@synthesize tag;
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately tag:(NSString*)aTag
{
self = [super initWithRequest:request delegate:delegate startImmediately:startImmediately];
if (self) {
self.tag = aTag;
}
return self;
}
- (void)dealloc
{
[tag release];
[super dealloc];
}
@end
Then make the connection, a custom url connection in your parsingComplete with:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:yourURL];
[request setTimeoutInterval:3000.0];
CustomURLConnection *connection = [[CustomURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES tag:imageTag];
Now you can take the imageName
with the CustomURLConnection
tag, and save it in the connectionDidFinishLoading:
CustomURLConnection *urlConec = (CustomURLConnection*)connection;
NSMutableData *dataFromConnection = [self dataForConnection:urlConec];
and this is the code for the function dataForConnection:
- (NSMutableData*)dataForConnection:(CustomURLConnection*)connection
{
NSMutableData *data = [receivedData objectForKey:connection.tag];
return data;
}
Hope that helps.