Note that there are some explanatory texts on larger screens.

plurals
  1. PODownloading a Large File - iPhone SDK
    primarykey
    data
    text
    <p>I am using Erica Sadun's method of Asynchronous Downloads (link here for the project file: <a href="http://uhelios.com/downloaderica.zip" rel="noreferrer">download</a>), however her method does not work with files that have a big size (50 mb or above). If I try to download a file above 50 mb, it will usually crash due to a memory crash. Is there anyway I can tweak this code so that it works with large files as well? Here is the code I have in the DownloadHelper Classes (which is already in the download link):</p> <p>.h</p> <pre><code>@protocol DownloadHelperDelegate &lt;NSObject&gt; @optional - (void) didReceiveData: (NSData *) theData; - (void) didReceiveFilename: (NSString *) aName; - (void) dataDownloadFailed: (NSString *) reason; - (void) dataDownloadAtPercent: (NSNumber *) aPercent; @end @interface DownloadHelper : NSObject { NSURLResponse *response; NSMutableData *data; NSString *urlString; NSURLConnection *urlconnection; id &lt;DownloadHelperDelegate&gt; delegate; BOOL isDownloading; } @property (retain) NSURLResponse *response; @property (retain) NSURLConnection *urlconnection; @property (retain) NSMutableData *data; @property (retain) NSString *urlString; @property (retain) id delegate; @property (assign) BOOL isDownloading; + (DownloadHelper *) sharedInstance; + (void) download:(NSString *) aURLString; + (void) cancel; @end </code></pre> <p>.m</p> <pre><code>#define DELEGATE_CALLBACK(X, Y) if (sharedInstance.delegate &amp;&amp; [sharedInstance.delegate respondsToSelector:@selector(X)]) [sharedInstance.delegate performSelector:@selector(X) withObject:Y]; #define NUMBER(X) [NSNumber numberWithFloat:X] static DownloadHelper *sharedInstance = nil; @implementation DownloadHelper @synthesize response; @synthesize data; @synthesize delegate; @synthesize urlString; @synthesize urlconnection; @synthesize isDownloading; - (void) start { self.isDownloading = NO; NSURL *url = [NSURL URLWithString:self.urlString]; if (!url) { NSString *reason = [NSString stringWithFormat:@"Could not create URL from string %@", self.urlString]; DELEGATE_CALLBACK(dataDownloadFailed:, reason); return; } NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url]; if (!theRequest) { NSString *reason = [NSString stringWithFormat:@"Could not create URL request from string %@", self.urlString]; DELEGATE_CALLBACK(dataDownloadFailed:, reason); return; } self.urlconnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; if (!self.urlconnection) { NSString *reason = [NSString stringWithFormat:@"URL connection failed for string %@", self.urlString]; DELEGATE_CALLBACK(dataDownloadFailed:, reason); return; } self.isDownloading = YES; // Create the new data object self.data = [NSMutableData data]; self.response = nil; [self.urlconnection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; } - (void) cleanup { self.data = nil; self.response = nil; self.urlconnection = nil; self.urlString = nil; self.isDownloading = NO; } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)aResponse { // store the response information self.response = aResponse; // Check for bad connection if ([aResponse expectedContentLength] &lt; 0) { NSString *reason = [NSString stringWithFormat:@"Invalid URL [%@]", self.urlString]; DELEGATE_CALLBACK(dataDownloadFailed:, reason); [connection cancel]; [self cleanup]; return; } if ([aResponse suggestedFilename]) DELEGATE_CALLBACK(didReceiveFilename:, [aResponse suggestedFilename]); } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData { // append the new data and update the delegate [self.data appendData:theData]; if (self.response) { float expectedLength = [self.response expectedContentLength]; float currentLength = self.data.length; float percent = currentLength / expectedLength; DELEGATE_CALLBACK(dataDownloadAtPercent:, NUMBER(percent)); } } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { // finished downloading the data, cleaning up self.response = nil; // Delegate is responsible for releasing data if (self.delegate) { NSData *theData = [self.data retain]; DELEGATE_CALLBACK(didReceiveData:, theData); } [self.urlconnection unscheduleFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; [self cleanup]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { self.isDownloading = NO; NSLog(@"Error: Failed connection, %@", [error localizedDescription]); DELEGATE_CALLBACK(dataDownloadFailed:, @"Failed Connection"); [self cleanup]; } + (DownloadHelper *) sharedInstance { if(!sharedInstance) sharedInstance = [[self alloc] init]; return sharedInstance; } + (void) download:(NSString *) aURLString { if (sharedInstance.isDownloading) { NSLog(@"Error: Cannot start new download until current download finishes"); DELEGATE_CALLBACK(dataDownloadFailed:, @""); return; } sharedInstance.urlString = aURLString; [sharedInstance start]; } + (void) cancel { if (sharedInstance.isDownloading) [sharedInstance.urlconnection cancel]; } @end </code></pre> <p>And finally this is how I write the file with the two classes above it:</p> <pre><code>- (void) didReceiveData: (NSData *) theData { if (![theData writeToFile:self.savePath atomically:YES]) [self doLog:@"Error writing data to file"]; [theData release]; } </code></pre> <p>If someone could help me out I would be so glad!</p> <p>Thanks,</p> <p>Kevin</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload