【待整理】IOS開發之下載

來源:互聯網
上載者:User

標籤:

一、傳統的下載檔案的方式  
- (void)downloaderWithUrl:(NSURL *)url{    NSURLRequest *request = [NSURLRequest requestWithURL:url];        [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {                if (!connectionError)        {            NSHTTPURLResponse *urlResponse = (NSHTTPURLResponse *)response;            if (urlResponse.statusCode == 200 || urlResponse.statusCode == 304)            {                [data writeToFile:@"/Users/gxiangzi/Desktop/a.mp4" atomically:YES];                NSLog(@"OK");            }        }else        {            NSLog(@"錯誤");        }    }];}

 

但是這種方式存在著弊端:

  1> 用不無法跟蹤下載的進度,無法直觀的顯示下載進度

  2> 檔案下載的時候,都會先下載到記憶體之中,導致記憶體 > 所需檔案的大小長度,會造成程式崩潰等現象(可以查看記憶體的耗費)

 

二、代理的方式下載程式(NSURLConnectionDownloadDelegate)
#import "GXDownloader.h"@interface GXDownloader () <NSURLConnectionDownloadDelegate>@end@implementation GXDownloader- (void)downloaderWithUrl:(NSURL*)url{    NSURLRequest* request = [NSURLRequest requestWithURL:url];    [[NSURLConnection alloc] initWithRequest:request delegate:self];}#pragma mark - NSURLConnectionDownloadDelegate/** bytesWritten: 表示下載的資料位元組數 totalBytesWritten:總的已經下載的位元組數 expectedTotalBytes:期望的總的位元組數 */- (void)connection:(NSURLConnection*)connection didWriteData:(long long)bytesWritten totalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long)expectedTotalBytes{    float progress = (float)totalBytesWritten / expectedTotalBytes;    NSLog(@"%f", progress);}/** *  @param connection *  @param totalBytesWritten : 總的已經下載的位元組數 *  @param expectedTotalBytes : 期望總的位元組數 */- (void)connectionDidResumeDownloading:(NSURLConnection*)connection totalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long)expectedTotalBytes{}/** *  @param connection *  @param destinationURL:下載完的目標路徑 */- (void)connectionDidFinishDownloading:(NSURLConnection*)connection destinationURL:(NSURL*)destinationURL{    NSLog(@"%@", destinationURL);}

 

優點:

  1> 該種方式可以追蹤檔案下載的進度;

  2> 也可以解決記憶體消耗過大的問題

弊端:  這丫的 下載的檔案沒有 ,就是雖然你顯示下載完成,但是你本地找不到該檔案------沒有任何卵用

 

 

三、第三種方式--代理(NSURLConnectionDataDelegate)

 

////  GXDownloader.m//  02-下載////  Created by gxiangzi on 15/8/21.//  Copyright (c) 2015年 hqu. All rights reserved.//#import "GXDownloader.h"@interface GXDownloader () <NSURLConnectionDataDelegate>// 檔案的總長度@property (nonatomic, assign) long long expectedContentLength;// 已經接受到檔案的長度@property (nonatomic, assign) long long receivedContentLength;// 已經已接收的檔案的總長度@property (nonatomic, strong) NSMutableData* receivedData;@end@implementation GXDownloader- (void)downloaderWithUrl:(NSURL*)url{    NSURLRequest* request = [NSURLRequest requestWithURL:url];    [[NSURLConnection alloc] initWithRequest:request delegate:self];}#pragma mark - NSURLConnectionDataDelegate/** *  已經接受到回應標頭 */- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response{    self.expectedContentLength = response.expectedContentLength;}/** *  檔案接受到一點的時候就是用 */- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data{    // 把位元據進行拼接    [self.receivedData appendData:data];    // 拼接長度    self.receivedContentLength += data.length;        float progress = (float)self.receivedContentLength / self.expectedContentLength;        NSLog(@"下載進度: %.2f",progress);    }/** *  下載出錯的時候調用 */- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error{}/** *  當下載完成的時候調用 */- (void)connectionDidFinishLoading:(NSURLConnection*)connection{    NSLog(@"下載完成");        // IOS 的檔案路徑,只能講軟體操作的資料放在沙箱內    NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];    NSString *fileName = [path stringByAppendingPathComponent:@"love.mp4"];        NSLog(@"%@",fileName);        [self.receivedData writeToFile:fileName atomically:YES];    }#pragma mark -懶載入- (NSMutableData*)receivedData{    if (!_receivedData) {        _receivedData = [NSMutableData data];    }    return _receivedData;}@end

 

優點: 

  1> 可以檢測到進度的問題

  2> 檔案的寫入的路徑之中,檔案可以存在

弊端:

  佔用的記憶體太大  

 

為瞭解決上面的問題: 引入了NSHandle  和 NSOutputStream ------下一點 寫入檔案一點

四、NSHandle的使用
////  GXDownloader.m//  02-下載////  Created by gxiangzi on 15/8/21.//  Copyright (c) 2015年 hqu. All rights reserved.//#import "GXDownloader.h"@interface GXDownloader () <NSURLConnectionDataDelegate>// 檔案的總長度@property (nonatomic, assign) long long expectedContentLength;// 已經接受到檔案的長度@property (nonatomic, assign) long long receivedContentLength;@end@implementation GXDownloader- (void)downloaderWithUrl:(NSURL*)url{    NSURLRequest* request = [NSURLRequest requestWithURL:url];    [[NSURLConnection alloc] initWithRequest:request delegate:self];}#pragma mark - NSURLConnectionDataDelegate/** *  已經接受到回應標頭 */- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response{    self.expectedContentLength = response.expectedContentLength;}/** *  檔案接受到一點的時候就是用 */- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data{    // 拼接長度    self.receivedContentLength += data.length;    float progress = (float)self.receivedContentLength / self.expectedContentLength;    NSLog(@"%f",progress);        NSString* path = @"/Users/gxiangzi/Desktop/a.mp4";    NSFileHandle* handle = [NSFileHandle fileHandleForWritingAtPath:path];    // 如果handle  不會幫我們建立檔案    if (handle == nil) {        [data writeToFile:path atomically:YES];    }    else {        //讓offset指向檔案的末尾,在末尾處追加資料        [handle seekToEndOfFile];        //寫輸入        [handle writeData:data];        //關閉  (等檔案下載完成關閉更好)        [handle closeFile];    }    }/** *  當下載完成的時候調用 */- (void)connectionDidFinishLoading:(NSURLConnection*)connection{    NSLog(@"下載完成");}@end

 

原理:下載一點資料 寫一點資料

效果:能夠達到佔用很少記憶體

 

五、NSOutputStream的使用

 

////  GXDownloader.m//  02-下載////  Created by gxiangzi on 15/8/21.//  Copyright (c) 2015年 hqu. All rights reserved.//#import "GXDownloader.h"@interface GXDownloader () <NSURLConnectionDataDelegate>// 檔案的總長度@property (nonatomic, assign) long long expectedContentLength;// 已經接受到檔案的長度@property (nonatomic, assign) long long receivedContentLength;@property (nonatomic, strong) NSOutputStream* stream;@end@implementation GXDownloader- (void)downloaderWithUrl:(NSURL*)url{    NSURLRequest* request = [NSURLRequest requestWithURL:url];    [[NSURLConnection alloc] initWithRequest:request delegate:self];}#pragma mark - NSURLConnectionDataDelegate/** *  已經接受到回應標頭 */- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response{    self.expectedContentLength = response.expectedContentLength;        NSString* path = @"/Users/gxiangzi/Desktop/a.mp4";    // 注意 此處的url 為本地的路徑    // 前面加 file:// 無效    // 只能使用 [NSURL fileURLWithPath:path]   self.stream = [NSOutputStream outputStreamWithURL:[NSURL fileURLWithPath:path] append:YES];    [self.stream open];    }/** *  檔案接受到一點的時候就是用 */- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data{    // 拼接長度    self.receivedContentLength += data.length;    float progress = (float)self.receivedContentLength / self.expectedContentLength;    NSLog(@"%f", progress);    [self.stream write:data.bytes maxLength:data.length];}/** *  當下載完成的時候調用 */- (void)connectionDidFinishLoading:(NSURLConnection*)connection{    NSLog(@"下載完成");    [self.stream close];}- (NSOutputStream *)stream{    if (_stream == nil)    {        _stream = [[NSOutputStream alloc] init];    }    return _stream;}@end

 

【待整理】IOS開發之下載

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.