NSURLConnection download large file (>40MB) NSURLConnection download large file (>40MB) ios ios

NSURLConnection download large file (>40MB)


You are currently keeping all downloaded data in a NSMutableData object which is kept within the RAM of your device. That will, depending on the device and the available memory, at some point trigger a memory warning or even a crash.

To get such large downloads to work, you will have to write all downloaded data directly to the filesystem.

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {   //try to access that local file for writing to it...   NSFileHandle *hFile = [NSFileHandle fileHandleForWritingAtPath:self.localPath];   //did we succeed in opening the existing file?   if (!hFile)    {   //nope->create that file!       [[NSFileManager defaultManager] createFileAtPath:self.localPath contents:nil attributes:nil];       //try to open it again...       hFile = [NSFileHandle fileHandleForWritingAtPath:self.localPath];   }   //did we finally get an accessable file?   if (!hFile)   {   //nope->bomb out!       NSLog("could not write to file %@", self.localPath);        return;   }   //we never know - hence we better catch possible exceptions!   @try    {       //seek to the end of the file       [hFile seekToEndOfFile];       //finally write our data to it       [hFile writeData:data];   }   @catch (NSException * e)    {       NSLog("exception when writing to file %@", self.localPath);        result = NO;   }   [hFile closeFile];}


I had the same problem, and seems that I discovered some solution.

In your header file declare:

NSMutableData *webData;NSFileHandle *handleFile;

In your .m file on downloadFileFromURL when you get the connection initiate the NSFileHandle:

if (theConnection) {        webData = [[NSMutableData data] retain];        if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {            [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];        }        handleFile = [[NSFileHandle fileHandleForWritingAtPath:filePath] retain];    }

then in didReceiveData instead of appending data to memory write it to disk, like this:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {    [webData appendData:data];    if( webData.length > SOME_FILE_SIZE_IN_BYTES && handleFile!=nil) {                  [handleFile writeData:recievedData];        [webData release];        webData =[[NSMutableData alloc] initWithLength:0];    }}

when the download finish on connectionDidFinishLoading add this lines to write the file and to release connection:

[handleFile writeData:webData];[webData release];[theConnection release];

I'm trying it right now, hope it works..


This happens because of my downloadable file was in shared hosting which having the download limitations. After I moved that file to dedicated server that working fine. and also I tried to download some other files like videos from some other sites, that also working fine.

So, if you having problem like partial download, don't only stick with the code, check the server too.