Alright. Hopefully this will be my last post about the download manager I am writing in Objective-C. Everything seems to work well except the pause/resume functionality. My issue is that when a download tries to continue from where it left off, it appends the data it receives to the file, but it still seems that it's trying 开发者_开发技巧to download the entire file. This results in a file that is larger than the original file is supposed to be. Here is the code I am using for downloading files. Am I doing something wrong?
-(void)start:(unsigned int)fromByte {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:DEFAULT_TIMEOUT];
// Define the bytes we wish to download.
NSString *range = [NSString stringWithFormat:@"bytes=%i-", fromByte];
[request setValue:range forHTTPHeaderField:@"Range"];
// Data should immediately start downloading after the connection is created.
self.urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:TRUE];
if (!self.urlConnection) {
#warning Handle error.
}
}
I see you are specifying the Range header in the request. First thing to check is whether the server is actually honoring the Range request, by checking the headers in the response object (which should be an NSHTTPURLResponse
) in connection:didReceiveResponse:
for a proper Content-Range.
I finally figured this out. It turns out that the 'getFilesizeInBytes'
method I had was get the NSFileSize
object from the file's attributes, but I was directly casting this to an int
. This caused the number to be about 20 times larger than it should have been. I was able to fix this by using [@"" intValue]
. Once this was fixed, the servers were able to give me the rest of the file starting with the correct byte. It seems that before my issue was not that the server wasn't honoring my request, but that it couldn't honor my request due to me requesting data that was well beyond the final byte of the file.
There's no support for pause/resume in NSURLConnection. You can emulate it by stopping the request, then issuing a request for the rest of the content with a Range
header on resume. Some support from the HTTP server is required for that, and is not guaranteed.
Looks like lack of support at the server is what you're facing.
Most download managers, however, implement their own HTTP stack on top of sockets.
精彩评论