调用: URLDownload *downloader; - (IBAction) download:(id)sender { [urlField resignFirstResponder]; NSString *tmpPath = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp"]; NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:[urlField text]]]; downloader = [[URLDownload alloc] initWithRequest:req directory:tmpPath delegate:self]; } /// //URLDownloadDelegate implements - (void)downloadDidFinish:(URLDownload *)download { LOG(download.filePath); [self releaseDownloader]; } - (void)download:(URLDownload *)download didCancelBecauseOf:(NSException *)exception { UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"" message:[exception reason] delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK",nil] autorelease]; [alert show]; [self releaseDownloader]; } - (void)download:(URLDownload *)download didFailWithError:(NSError *)error { UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"" message:[error localizedDescription] delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK",nil] autorelease]; [alert show]; [self releaseDownloader]; } - (void)download:(URLDownload *)download didReceiveDataOfLength:(NSUInteger)length { } URLDownload.h #import <Foundation/Foundation.h> @class URLDownload; @protocol URLDownloadDeleagte - (void)downloadDidFinish:(URLDownload *)download; - (void)download:(URLDownload *)download didCancelBecauseOf:(NSException *)exception; - (void)download:(URLDownload *)download didFailWithError:(NSError *)error; @optional - (void)download:(URLDownload *)download didReceiveDataOfLength:(NSUInteger)length; - (void)download:(URLDownload *)download didReceiveResponse:(NSURLResponse *)response; @end @interface URLDownload : NSObject { id <URLDownloadDeleagte, NSObject> delegate; NSString *directoryPath; NSString *filePath; NSURLRequest *request; NSFileHandle *file; NSURLConnection *con; } @property(readonly) NSString *filePath; - (id)initWithRequest:(NSURLRequest *)req directory:(NSString *)dir delegate:(id<URLDownloadDeleagte, NSObject>)dg; - (void)dealloc; - (void)cancel; // NSURLConnection delegate - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response; - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error; - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data; - (void)connectionDidFinishLoading:(NSURLConnection *)connection; //- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; //- (void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; //- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse; //- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse; @end URLDownload.m #import "URLDownload.h" @implementation URLDownload @synthesize filePath; - (id)initWithRequest:(NSURLRequest *)req directory:(NSString *)dir delegate:(id<URLDownloadDeleagte, NSObject>)dg { if (self = [super init]) { request = [req retain]; directoryPath = [dir retain]; delegate = [dg retain]; con = [[NSURLConnection alloc] initWithRequest:request delegate:self]; } return self; } - (void)dealloc { [request release]; [directoryPath release]; [filePath release]; [file release]; [delegate release]; [con release]; [super dealloc]; } - (void)cancel { [con cancel]; } // NSURLConnection delegate - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { filePath = [[response suggestedFilename] retain]; if ([delegate respondsToSelector:@selector(download: didReceiveResponse:)]) [delegate download:self didReceiveResponse:response]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { LOG([error localizedDescription]); if ([delegate respondsToSelector:@selector(download: didFailWithError:)]) [delegate download:self didFailWithError:error]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { @try { if (file == nil) { NSFileManager *fm = [NSFileManager defaultManager]; BOOL isDir; if (![fm fileExistsAtPath:directoryPath isDirectory:&isDir]) { NSError *error; if (![fm createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:&error]) { LOG([error localizedDescription]); LOG([error localizedFailureReason]); LOG([error localizedRecoverySuggestion]); [NSException raise:@"Exception" format:[error localizedDescription]]; } } else if (!isDir) { [NSException raise:@"Exception" format:@"Failed to create directory at %@, because there is a file already.", directoryPath]; } NSString *tmpFilePath = [[directoryPath stringByAppendingPathComponent:filePath] stringByStandardizingPath]; int suffix = 0; while ([fm fileExistsAtPath:tmpFilePath]) { suffix++; tmpFilePath = [[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%d", filePath, suffix]] stringByStandardizingPath]; } [fm createFileAtPath:tmpFilePath contents:[NSData data] attributes:nil]; [filePath release]; filePath = [tmpFilePath retain]; file = [[NSFileHandle fileHandleForWritingAtPath:filePath] retain]; } [file writeData:data]; if ([delegate respondsToSelector:@selector(download: didReceiveDataOfLength:)]) [delegate download:self didReceiveDataOfLength:[data length]]; } @catch (NSException * e) { LOG([e reason]); [connection cancel]; [delegate download:self didCancelBecauseOf:e]; } } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { [delegate downloadDidFinish:self]; } /* - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; - (void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; - (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse; - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse; */ @end