下載, 上傳與解壓

小文件下載
如果文件比較小,下載方式會(huì)比較多
直接用NSData的+ (id)dataWithContentsOfURL:(NSURL *)url;
利用NSURLConnection發(fā)送一個(gè)HTTP請(qǐng)求(默認(rèn)是get請(qǐng)求)去下載
如果是下載圖片,還可以利用SDWebImage框架
如果是大文件下載,建議使用或者使用NSURLSession第三方框架
HTTP Range的示例
通過設(shè)置請(qǐng)求頭Range可以指定位置每次從網(wǎng)路下載數(shù)據(jù)包的大小
Range示例
bytes=0-499 從0到499的頭500個(gè)字節(jié)
bytes=500-999 從500到999的第二個(gè)500字節(jié)
bytes=500- 從500字節(jié)以后的所有字節(jié)

bytes=-500 最后500個(gè)字節(jié)
bytes=500-599,800-899 同時(shí)指定幾個(gè)范圍
Range小結(jié)

  • 用于分隔
    前面的數(shù)字表示起始字節(jié)數(shù)
    后面的數(shù)組表示截止字節(jié)數(shù),沒有表示到末尾
    , 用于分組,可以一次指定多個(gè)Range,不過很少用
    第三方解壓縮框架——SSZipArchive
    下載地址:https://github.com/samsoffes/ssziparchive
    注意:需要引入libz.dylib框架
    Unzipping
NSString *zipPath = @"path_to_your_zip_file";
NSString *destinationPath = @"path_to_the_folder_where_you_want_it_unzipped";
[SSZipArchive unzipFileAtPath:zipPath toDestination:destinationPath];
 
 Zipping
NSString *zippedPath = @"path_where_you_want_the_file_created";
NSArray *inputPaths = [NSArray arrayWithObjects:
                       [[NSBundle mainBundle] pathForResource:@"photo1" ofType:@"jpg"],
                       [[NSBundle mainBundle] pathForResource:@"photo2" ofType:@"jpg"]
                       nil];
[SSZipArchive createZipFileAtPath:zippedPath withFilesAtPaths:inputPaths];

第三方解壓縮框架——ZipArchive
下載地址:https://github.com/ZipArchive/ZipArchive
需要引入libz.dylib框架
導(dǎo)入頭文件Main.h
創(chuàng)建壓縮文件

+ (BOOL)createZipFileAtPath:(NSString *)path
           withFilesAtPaths:(NSArray *)paths;
+ (BOOL)createZipFileAtPath:(NSString *)path
    withContentsOfDirectory:(NSString *)directoryPath;

解壓

+ (BOOL)unzipFileAtPath:(NSString *)path
          toDestination:(NSString *)destination

文件上傳的步驟
設(shè)置請(qǐng)求頭

[request setValue:@"multipart/form-data; boundary=分割線"forHTTPHeaderField:@"Content-Type"];

設(shè)置請(qǐng)求體
非文件參數(shù)
--分割線\r\n

Content-Disposition: form-data; name="參數(shù)名"\r\n
\r\n

參數(shù)值
\r\n
文件參數(shù)
--分割線\r\n
Content-Disposition: form-data; name="參數(shù)名"; filename="文件名"\r\n
Content-Type: 文件的MIMEType\r\n
\r\n
文件數(shù)據(jù)
\r\n

參數(shù)結(jié)束的標(biāo)記
--分割線--\r\n
multipart/form-data格式小結(jié)
[圖片上傳中。。。(1)]
部分文件的MIMEType
類型

文件拓展名

MIMEType

圖片

png

image/png

bmp\dib

image/bmp

jpe\jpeg\jpg

image/jpeg

gif

image/gif

多媒體

mp3

audio/mpeg

mp4\mpg4\m4vmp4v

video/mp4

文本

js

application/javascript

pdf

application/pdf

text\txt

text/plain

json

application/json

xml

text/xml

獲得文件的MIMEType
利用NSURLConnection
- (NSString *)MIMEType:(NSURL *)url
{
     1.創(chuàng)建一個(gè)請(qǐng)求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
     2.發(fā)送請(qǐng)求(返回響應(yīng))
    NSURLResponse *response = nil;
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
     3.獲得MIMEType
    return response.MIMEType;
}
 
獲得文件的MIMEType
C語(yǔ)言API
+ (NSString *)mimeTypeForFileAtPath:(NSString *)path
{
    if (![[NSFileManager alloc] init] fileExistsAtPath:path]) {
        return nil;
    }
        
    CFStringRef UTI =      
UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
(CFStringRef)[path pathExtension], NULL);
 
    CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI,   
kUTTagClassMIMEType);
 
    CFRelease(UTI);
 
    if (!MIMEType) {
        return @"application/octet-stream";
    }
        return NSMakeCollectable(MIMEType);
}

1.0 文件下載

  • 1.1 小文件下載

(1)第一種方式(NSData)

使用NSDta直接加載網(wǎng)絡(luò)上的url資源(不考慮線程)
-(void)dataDownload
{
   1.確定資源路徑
   NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];
   
   2.根據(jù)URL加載對(duì)應(yīng)的資源
   NSData *data = [NSData dataWithContentsOfURL:url];
   
   3.轉(zhuǎn)換并顯示數(shù)據(jù)
   UIImage *image = [UIImage imageWithData:data];
   self.imageView.image = image;
   
}

(2)第二種方式(NSURLConnection-sendAsync)

使用NSURLConnection發(fā)送異步請(qǐng)求下載文件資源
-(void)connectDownload
{
   1.確定請(qǐng)求路徑
   NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];
   
   2.創(chuàng)建請(qǐng)求對(duì)象
   NSURLRequest *request = [NSURLRequest requestWithURL:url];
   
   3.使用NSURLConnection發(fā)送一個(gè)異步請(qǐng)求
   [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
       4.拿到并處理數(shù)據(jù)
       UIImage *image = [UIImage imageWithData:data];
       self.imageView.image = image;
       
   }];
}

(3)第三種方式(NSURLConnection-delegate)

使用NSURLConnection設(shè)置代理發(fā)送異步請(qǐng)求的方式下載文件
-(void)connectionDelegateDownload
{
   1.確定請(qǐng)求路徑
   NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
   
   2.創(chuàng)建請(qǐng)求對(duì)象
   NSURLRequest *request = [NSURLRequest requestWithURL:url];
   
   3.使用NSURLConnection設(shè)置代理并發(fā)送異步請(qǐng)求
   [NSURLConnection connectionWithRequest:request delegate:self];
   
}
#pragma mark--NSURLConnectionDataDelegate

當(dāng)接收到服務(wù)器響應(yīng)的時(shí)候調(diào)用,該方法只會(huì)調(diào)用一次
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
   創(chuàng)建一個(gè)容器,用來(lái)接收服務(wù)器返回的數(shù)據(jù)
   self.fileData = [NSMutableData data];
   
   獲得當(dāng)前要下載文件的總大?。ㄍㄟ^響應(yīng)頭得到)
   NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
   self.totalLength = res.expectedContentLength;
   NSLog(@"%zd",self.totalLength);
   
   拿到服務(wù)器端推薦的文件名稱
   self.fileName = res.suggestedFilename;
}

當(dāng)接收到服務(wù)器返回的數(shù)據(jù)時(shí)會(huì)調(diào)用
該方法可能會(huì)被調(diào)用多次

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    拼接每次下載的數(shù)據(jù)
    [self.fileData appendData:data];
    
    計(jì)算當(dāng)前下載進(jìn)度并刷新UI顯示
    self.currentLength = self.fileData.length;
    
    NSLog(@"%f",1.0* self.currentLength/self.totalLength);
    self.progressView.progress = 1.0* self.currentLength/self.totalLength;  
}
當(dāng)網(wǎng)絡(luò)請(qǐng)求結(jié)束之后調(diào)用
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    文件下載完畢把接受到的文件數(shù)據(jù)寫入到沙盒中保存
    
    1.確定要保存文件的全路徑
    caches文件夾路徑
    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    
    NSString *fullPath = [caches stringByAppendingPathComponent:self.fileName];
    
    2.寫數(shù)據(jù)到文件中
    [self.fileData writeToFile:fullPath atomically:YES];
    
    NSLog(@"%@",fullPath);
}
 
當(dāng)請(qǐng)求失敗的時(shí)候調(diào)用該方法
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"%s",__func__);
}
  • 3.2 大文件的下載

(1)實(shí)現(xiàn)思路

邊接收數(shù)據(jù)邊寫文件以解決內(nèi)存越來(lái)越大的問題
(2)核心代碼

當(dāng)接收到服務(wù)器響應(yīng)的時(shí)候調(diào)用,該方法只會(huì)調(diào)用一次

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    0.獲得當(dāng)前要下載文件的總大?。ㄍㄟ^響應(yīng)頭得到)
    NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
    self.totalLength = res.expectedContentLength;
    NSLog(@"%zd",self.totalLength);
    
    創(chuàng)建一個(gè)新的文件,用來(lái)當(dāng)接收到服務(wù)器返回?cái)?shù)據(jù)的時(shí)候往該文件中寫入數(shù)據(jù)
    1.獲取文件管理者
    NSFileManager *manager = [NSFileManager defaultManager];
    
    2.拼接文件的全路徑
    caches文件夾路徑
    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    
    NSString *fullPath = [caches stringByAppendingPathComponent:res.suggestedFilename];
    self.fullPath  = fullPath;
    3.創(chuàng)建一個(gè)空的文件
    [manager createFileAtPath:fullPath contents:nil attributes:nil];
    
}
當(dāng)接收到服務(wù)器返回的數(shù)據(jù)時(shí)會(huì)調(diào)用
該方法可能會(huì)被調(diào)用多次
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    
    1.創(chuàng)建一個(gè)用來(lái)向文件中寫數(shù)據(jù)的文件句柄
    注意當(dāng)下載完成之后,該文件句柄需要關(guān)閉,調(diào)用closeFile方法
    NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
    
    2.設(shè)置寫數(shù)據(jù)的位置(追加)
    [handle seekToEndOfFile];
    
    3.寫數(shù)據(jù)
    [handle writeData:data];
    
    4.計(jì)算當(dāng)前文件的下載進(jìn)度
    self.currentLength += data.length;
    
    NSLog(@"%f",1.0* self.currentLength/self.totalLength);
    self.progressView.progress = 1.0* self.currentLength/self.totalLength;
}
  • 1.3 大文件斷點(diǎn)下載

(1)實(shí)現(xiàn)思路

在下載文件的時(shí)候不再是整塊的從頭開始下載,而是看當(dāng)前文件已經(jīng)下載到哪個(gè)地方,然后從該地方接著往后面下載??梢酝ㄟ^在請(qǐng)求對(duì)象中設(shè)置請(qǐng)求頭實(shí)現(xiàn)。

(2)解決方案(設(shè)置請(qǐng)求頭)

2.創(chuàng)建請(qǐng)求對(duì)象

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

2.1 設(shè)置下載文件的某一部分
只要設(shè)置HTTP請(qǐng)求頭的Range屬性, 就可以實(shí)現(xiàn)從指定位置開始下載

表示頭500個(gè)字節(jié):Range: bytes=0-499
表示第二個(gè)500字節(jié):Range: bytes=500-999
表示最后500個(gè)字節(jié):Range: bytes=-500
表示500字節(jié)以后的范圍:Range: bytes=500-

NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentLength];
[request setValue:range forHTTPHeaderField:@"Range"];

(3)注意點(diǎn)(下載進(jìn)度并判斷是否需要重新創(chuàng)建文件)

獲得當(dāng)前要下載文件的總大?。ㄍㄟ^響應(yīng)頭得到)
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;

注意點(diǎn):res.expectedContentLength獲得是本次請(qǐng)求要下載的文件的大小(并非是完整的文件的大?。?br> 因此:文件的總大小 == 本次要下載的文件大小+已經(jīng)下載的文件的大小
self.totalLength = res.expectedContentLength + self.currentLength;

NSLog(@"----------------------------%zd",self.totalLength);

0 判斷當(dāng)前是否已經(jīng)下載過,如果當(dāng)前文件已經(jīng)存在,那么直接返回
if (self.currentLength >0) {
return;
}

  • 1.4 輸出流

(1)使用輸出流也可以實(shí)現(xiàn)和NSFileHandle相同的功能

(2)如何使用

1.創(chuàng)建一個(gè)數(shù)據(jù)輸出流

第一個(gè)參數(shù):二進(jìn)制的流數(shù)據(jù)要寫入到哪里
第二個(gè)參數(shù):采用什么樣的方式寫入流數(shù)據(jù),如果YES則表示追加,如果是NO則表示覆蓋

NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath:fullPath append:YES];

只要調(diào)用了該方法就會(huì)往文件中寫數(shù)據(jù)
如果文件不存在,那么會(huì)自動(dòng)的創(chuàng)建一個(gè)
[stream open];
self.stream = stream;

2.當(dāng)接收到數(shù)據(jù)的時(shí)候?qū)憯?shù)據(jù)
使用輸出流寫數(shù)據(jù)

第一個(gè)參數(shù):要寫入的二進(jìn)制數(shù)據(jù)
第二個(gè)參數(shù):要寫入的數(shù)據(jù)的大小

[self.stream write:data.bytes maxLength:data.length];

3.當(dāng)文件下載完畢的時(shí)候關(guān)閉輸出流
關(guān)閉輸出流
[self.stream close];
self.stream = nil;

  • 1.5 使用多線程下載文件思路

01 開啟多條線程,每條線程都只下載文件的一部分(通過設(shè)置請(qǐng)求頭中的Range來(lái)實(shí)現(xiàn))
02 創(chuàng)建一個(gè)和需要下載文件大小一致的文件,判斷當(dāng)前是那個(gè)線程,根據(jù)當(dāng)前的線程來(lái)判斷下載的數(shù)據(jù)應(yīng)該寫入到文件中的哪個(gè)位置。(假設(shè)開5條線程來(lái)下載10M的文件,那么線程1下載0-2M,線程2下載2-4M一次類推,當(dāng)接收到服務(wù)器返回的數(shù)據(jù)之后應(yīng)該先判斷當(dāng)前線程是哪個(gè)線程,假如當(dāng)前線程是線程2,那么在寫數(shù)據(jù)的時(shí)候就從文件的2M位置開始寫入)
03 代碼相關(guān):使用NSFileHandle這個(gè)類的seekToFileOfSet方法,來(lái)向文件中特定的位置寫入數(shù)據(jù)。
04 技術(shù)相關(guān)
a.每個(gè)線程通過設(shè)置請(qǐng)求頭下載文件中的某一個(gè)部分
b.通過NSFileHandle向文件中的指定位置寫數(shù)據(jù)

2.0 文件的壓縮和解壓縮

(1)說(shuō)明

使用ZipArchive來(lái)壓縮和解壓縮文件需要添加依賴庫(kù)(libz),使用需要包含Main文件,如果使用cocoaPoads來(lái)安裝框架,那么會(huì)自動(dòng)的配置框架的使用環(huán)境

(2)相關(guān)代碼

壓縮文件的第一種方式

第一個(gè)參數(shù):壓縮文件要保存的位置
第二個(gè)參數(shù):要壓縮哪幾個(gè)文件

[Main createZipFileAtPath:fullpath withFilesAtPaths:arrayM];

壓縮文件的第二種方式

第一個(gè)參數(shù):文件壓縮到哪個(gè)地方
第二個(gè)參數(shù):要壓縮文件的全路徑

[Main createZipFileAtPath:fullpath withContentsOfDirectory:zipFile];

如何對(duì)壓縮文件進(jìn)行解壓

第一個(gè)參數(shù):要解壓的文件
第二個(gè)參數(shù):要解壓到什么地方

[Main unzipFileAtPath:unZipFile toDestination:fullpath];

2.0 文件的上傳

  • 2.1 文件上傳步驟

(1)確定請(qǐng)求路徑
(2)根據(jù)URL創(chuàng)建一個(gè)可變的請(qǐng)求對(duì)象
(3)設(shè)置請(qǐng)求對(duì)象,修改請(qǐng)求方式為POST
(4)設(shè)置請(qǐng)求頭,告訴服務(wù)器我們將要上傳文件(Content-Type)
(5)設(shè)置請(qǐng)求體(在請(qǐng)求體中按照既定的格式拼接要上傳的文件參數(shù)和非文件參數(shù)等數(shù)據(jù))
001 拼接文件參數(shù)
002 拼接非文件參數(shù)
003 添加結(jié)尾標(biāo)記
(6)使用NSURLConnection sendAsync發(fā)送異步請(qǐng)求上傳文件
(7)解析服務(wù)器返回的數(shù)據(jù)

  • 2.2 文件上傳設(shè)置請(qǐng)求體的數(shù)據(jù)格式

請(qǐng)求體拼接格式
分隔符:----WebKitFormBoundaryhBDKBUWBHnAgvz9c

01.文件參數(shù)拼接格式

--分隔符
Content-Disposition:參數(shù)
Content-Type:參數(shù)
空行
文件參數(shù)

02.非文件拼接參數(shù)
--分隔符
Content-Disposition:參數(shù)
空行
非文件的二進(jìn)制數(shù)據(jù)

03.結(jié)尾標(biāo)識(shí)
--分隔符--

  • 2.3 文件上傳相關(guān)代碼

  • (void)upload
    {
    1.確定請(qǐng)求路徑
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];

    2.創(chuàng)建一個(gè)可變的請(qǐng)求對(duì)象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    3.設(shè)置請(qǐng)求方式為POST
    request.HTTPMethod = @"POST";

    4.設(shè)置請(qǐng)求頭
    NSString *filed = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary];
    [request setValue:filed forHTTPHeaderField:@"Content-Type"];

    5.設(shè)置請(qǐng)求體
    NSMutableData *data = [NSMutableData data];
    5.1 文件參數(shù)

    --分隔符
    Content-Disposition:參數(shù)
    Content-Type:參數(shù)
    空行
    文件參數(shù)

    [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    [data appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"test.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    [data appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    [data appendData:KnewLine];
    [data appendData:KnewLine];
    
    UIImage *image = [UIImage imageNamed:@"test"];
    NSData *imageData = UIImagePNGRepresentation(image);
    [data appendData:imageData];
    [data appendData:KnewLine];
    

    5.2 非文件參數(shù)

    --分隔符
    Content-Disposition:參數(shù)
    空行
    非文件參數(shù)的二進(jìn)制數(shù)據(jù)

    [data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    [data appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    [data appendData:KnewLine];
    [data appendData:KnewLine];
    
    NSData *nameData = [@"wendingding" dataUsingEncoding:NSUTF8StringEncoding];
    [data appendData:nameData];
    [data appendData:KnewLine];
    
    5.3 結(jié)尾標(biāo)識(shí)
    --分隔符--
    [data appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:KnewLine];
    
    request.HTTPBody = data;
    
    6.發(fā)送請(qǐng)求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * __nullable response, NSData * __nullable data, NSError * __nullable connectionError) {
        
        7.解析服務(wù)器返回的數(shù)據(jù)
        NSLog(@"%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
    }];
    

}

- 2.4 如何獲得文件的MIMEType類型

(1)直接對(duì)該對(duì)象發(fā)送一個(gè)異步網(wǎng)絡(luò)請(qǐng)求,在響應(yīng)頭中通過response.MIMEType拿到文件的MIMEType類型

如果想要及時(shí)拿到該數(shù)據(jù),那么可以發(fā)送一個(gè)同步請(qǐng)求

  • (NSString *)getMIMEType
    {
    NSString *filePath = @"/Users/文頂頂/Desktop/備課/其它/swift.md";

    NSURLResponse *response = nil;
    [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]] returningResponse:&response error:nil];
    return response.MIMEType;
    }

對(duì)該文件發(fā)送一個(gè)異步請(qǐng)求,拿到文件的MIMEType

  • (void)MIMEType
    {

     NSString *file = @"file:///Users/Edison/Desktop/test.png";
    

    [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:@"/Users/Edison/Desktop/test.png"]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * __nullable response, NSData * __nullable data, NSError * __nullable connectionError) {

      NSLog(@"%@",response.MIMEType);
    

    }];
    }
    (2)通過UTTypeCopyPreferredTagWithClass方法

注意:需要依賴于框架MobileCoreServices

  • (NSString *)mimeTypeForFileAtPath:(NSString *)path
    {
    if (![[[NSFileManager alloc] init] fileExistsAtPath:path]) {
    return nil;
    }

    CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[path pathExtension], NULL);
    CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);
    CFRelease(UTI);
    if (!MIMEType) {
    return @"application/octet-stream";
    }
    return (__bridge NSString *)(MIMEType);
    }

****************************************************************
**************************筆記****************************
一、大文件下載
1.方案:利用NSURLConnection和它的代理方法
1> 發(fā)送一個(gè)請(qǐng)求
1.URL
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/videos.zip"];
2.請(qǐng)求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
3.下載(創(chuàng)建完conn對(duì)象后,會(huì)自動(dòng)發(fā)起一個(gè)異步請(qǐng)求)
[NSURLConnection connectionWithRequest:request delegate:self];

2> 在代理方法中處理服務(wù)器返回的數(shù)據(jù)

在接收到服務(wù)器的響應(yīng)時(shí):
1.創(chuàng)建一個(gè)空的文件
2.用一個(gè)句柄對(duì)象關(guān)聯(lián)這個(gè)空的文件,目的是:方便后面用句柄對(duì)象往文件后面寫數(shù)據(jù)

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    文件路徑
   NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
   NSString *filepath = [caches stringByAppendingPathComponent:@"videos.zip"];
   
    創(chuàng)建一個(gè)空的文件 到 沙盒中
   NSFileManager *mgr = [NSFileManager defaultManager];
   [mgr createFileAtPath:filepath contents:nil attributes:nil];
   
    創(chuàng)建一個(gè)用來(lái)寫數(shù)據(jù)的文件句柄
   self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:filepath];
}


在接收到服務(wù)器返回的文件數(shù)據(jù)時(shí),利用句柄對(duì)象往文件的最后面追加數(shù)據(jù)

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    移動(dòng)到文件的最后面
   [self.writeHandle seekToEndOfFile];
   
    將數(shù)據(jù)寫入沙盒
   [self.writeHandle writeData:data];
}


在所有數(shù)據(jù)接收完畢時(shí),關(guān)閉句柄對(duì)象

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    關(guān)閉文件
   [self.writeHandle closeFile];
   self.writeHandle = nil;
}

2.注意點(diǎn):千萬(wàn)不能用NSMutableData來(lái)拼接服務(wù)器返回的數(shù)據(jù)

二、NSURLConnection發(fā)送異步請(qǐng)求的方法
1.block形式- 除開大文件下載以外的操作,都可以用這種形式
[NSURLConnection sendAsynchronousRequest:<#(NSURLRequest *)#> queue:<#(NSOperationQueue *)#> completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
   
}];

2.代理形式- 一般用在大文件下載
1.URL
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/login?username=123&pwd=123"];
2.請(qǐng)求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
3.下載(創(chuàng)建完conn對(duì)象后,會(huì)自動(dòng)發(fā)起一個(gè)異步請(qǐng)求)
[NSURLConnection connectionWithRequest:request delegate:self];

三、NSURLSession
1.使用步驟
1> 獲得NSURLSession對(duì)象
2> 利用NSURLSession對(duì)象創(chuàng)建對(duì)應(yīng)的任務(wù)(Task)
3> 開始任務(wù)([task resume])

2.獲得NSURLSession對(duì)象
1> [NSURLSession sharedSession]
2>
NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:cfg delegate:self delegateQueue:[NSOperationQueue mainQueue]];

3.任務(wù)類型
1> NSURLSessionDataTask
* 用途:用于非文件下載的GET\POST請(qǐng)求
NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request];
NSURLSessionDataTask *task = [self.session dataTaskWithURL:url];
NSURLSessionDataTask *task = [self.session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
   
}];

2> NSURLSessionDownloadTask
* 用途:用于文件下載(小文件、大文件)
NSURLSessionDownloadTask *task = [self.session downloadTaskWithRequest:request];
NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:url];
NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
   
}];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容