1.NSURLConnection和Runloop(面試)
- 1.1 涉及知識點
(1)兩種為NSURLConnection設定代理方式的差別
//第一種設定方式:
//通過該方法設定代理,會自動的發送請求
// [[NSURLConnection alloc]initWithRequest:request delegate:self];
//第二種設定方式:
//設定代理,startImmediately為NO的時候,該方法不會自動發送請求
NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
//手動通過代碼的方式來發送請求
//注意該方法内部會自動的把connect添加到目前線程的RunLoop中在預設模式下執行
[connect start];
```
(2)如何控制代理方法在哪個線程調用
```objc
//說明:預設情況下,代理方法會在主線程中進行調用(為了友善開發者拿到資料後處理一些重新整理UI的操作不需要考慮到線程間通信)
//設定代理方法的執行隊列
[connect setDelegateQueue:[[NSOperationQueue alloc]init]];
<div class="se-preview-section-delimiter"></div>
(3)開子線程發送網絡請求的注意點,适用于自動發送網絡請求模式
//使用GCD開啟一個子線程來發送網絡請求
dispatch_async(dispatch_get_global_queue(, ), ^{
//使用非自動發送網絡請求模式,發送請求OK
/*
//建立NSURLConnection對象,設定代理,暫不發送
NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
//設定代理方法的執行隊列
[connect setDelegateQueue:[[NSOperationQueue alloc]init]];
//調用start發送網絡請求
[connect start];
*/
//使用自動發送網絡請求模式,發送請求失敗(需要改造代碼)
//WHY?
/* 網絡請求發送和資料接收是否成功,和一些因素相關,比如用戶端的網速、伺服器端的查詢速度等等。
而在子線程中建立的NSURLConnection對象是一個臨時變量,當請求發送完成之後就被釋放了,是以這個時候它的代理方法不會調用用。
為什麼使用非自動發送網絡請求模式是OK的。
因為在該模式中,調用了start來開始發送網絡請求,該方法内部會自動将目前的connect作為一個Source添加到目前線程所在的Runloop中
如果目前線程是子線程(即目前線程的runloop并未建立),那麼該方法内部會預設先建立目前線程的Runloop,設定在runloop的預設模式下運作。
此時runloop會對這個Connect對象進行強引用,保證了代理方法被調用的前提
*/
NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self];
[connect setDelegateQueue:[[NSOperationQueue alloc]init]];
//建立目前線程的runloop,并開啟runloop
[[NSRunLoop currentRunLoop] run];
});
```
---
<div class="se-preview-section-delimiter"></div>
###NSURLSession的基本使用
- 涉及知識點
()使用步驟
使用NSURLSession建立task,然後執行task
()關于task
a.NSURLSessionTask是一個抽象類,本身不能使用,隻能使用它的子類
b.NSURLSessionDataTask\NSURLSessionUploadTask\NSURLSessionDownloadTask
()發送get請求
<div class="se-preview-section-delimiter"></div>
```objc
//1.建立NSURLSession對象(可以擷取單例對象)
NSURLSession *session = [NSURLSession sharedSession];
//2.根據NSURLSession對象建立一個Task
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=ss&pwd=ss&type=JSON"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//方法參數說明
/*
注意:該block是在子線程中調用的,如果拿到資料之後要做一些UI重新整理操作,那麼需要回到主線程重新整理
第一個參數:需要發送的請求對象
block:當請求結束拿到伺服器響應的資料時調用block
block-NSData:該請求的響應體
block-NSURLResponse:存放本次請求的響應資訊,響應頭,真實類型為NSHTTPURLResponse
block-NSErroe:請求錯誤資訊
*/
NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error) {
//拿到響應頭資訊
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
//4.解析拿到的響應資料
NSLog(@"%@\n%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],res.allHeaderFields);
}];
//3.執行Task
//注意:剛建立出來的task預設是挂起狀态的,需要調用該方法來啟動任務(執行任務)
[dataTask resume];
(4)發送get請求的第二種方式
“`
(3)開子線程發送網絡請求的注意點,适用于自動發送網絡請求模式
“`objc
//使用GCD開啟一個子線程來發送網絡請求
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//使用非自動發送網絡請求模式,發送請求OK
/*
//建立NSURLConnection對象,設定代理,暫不發送
NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
//設定代理方法的執行隊列
[connect setDelegateQueue:[[NSOperationQueue alloc]init]];
//調用start發送網絡請求
[connect start];
*/
//使用自動發送網絡請求模式,發送請求失敗(需要改造代碼)
//WHY?
/*01 網絡請求發送和資料接收是否成功,和一些因素相關,比如用戶端的網速、伺服器端的查詢速度等等。
02 而在子線程中建立的NSURLConnection對象是一個臨時變量,當請求發送完成之後就被釋放了,是以這個時候它的代理方法不會調用用。
03 為什麼使用非自動發送網絡請求模式是OK的。
因為在該模式中,調用了start來開始發送網絡請求,該方法内部會自動将目前的connect作為一個Source添加到目前線程所在的Runloop中
如果目前線程是子線程(即目前線程的runloop并未建立),那麼該方法内部會預設先建立目前線程的Runloop,設定在runloop的預設模式下運作。
此時runloop會對這個Connect對象進行強引用,保證了代理方法被調用的前提
*/
NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self];
[connect setDelegateQueue:[[NSOperationQueue alloc]init]];
//建立目前線程的runloop,并開啟runloop
[[NSRunLoop currentRunLoop] run];
});
```
2.NSURLSession的基本使用
- 2.1 涉及知識點
(1)使用步驟
使用NSURLSession建立task,然後執行task
(2)關于task
a.NSURLSessionTask是一個抽象類,本身不能使用,隻能使用它的子類
b.NSURLSessionDataTask\NSURLSessionUploadTask\NSURLSessionDownloadTask
(3)發送get請求
3.NSURLSession下載下傳檔案-代理
- 3.1 涉及知識點
(1)建立NSURLSession對象,設定代理(預設配置)
//1.建立NSURLSession,并設定代理
/*
第一個參數:session對象的全局配置設定,一般使用預設配置就可以
第二個參數:誰成為session對象的代理
第三個參數:代理方法在哪個隊列中執行(在哪個線程中調用),如果是主隊列那麼在主線程中執行,如果是非主隊列,那麼在子線程中執行
*/
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
(2)根據Session對象建立一個NSURLSessionDataTask任務(post和get選擇)
//建立task
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];
//注意:如果要發送POST請求,那麼請使用dataTaskWithRequest,設定一些請求頭資訊
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url];
(3)執行任務(其它方法,如暫停、取消等)
//啟動task
//[dataTask resume];
//其它方法,如取消任務,暫停任務等
//[dataTask cancel];
//[dataTask suspend];
(4)遵守代理協定,實作代理方法(3個相關的代理方法)
/*
1.當接收到伺服器響應的時候調用
session:發送請求的session對象
dataTask:根據NSURLSession建立的task任務
response:伺服器響應資訊(響應頭)
completionHandler:通過該block回調,告訴伺服器端是否接收傳回的資料
*/
-(void)URLSession:(nonnull NSURLSession *)session dataTask:(nonnull NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler
/*
2.當接收到伺服器傳回的資料時調用
該方法可能會被調用多次
*/
-(void)URLSession:(nonnull NSURLSession *)session dataTask:(nonnull NSURLSessionDataTask *)dataTask didReceiveData:(nonnull NSData *)data
/*
3.當請求完成之後調用該方法
不論是請求成功還是請求失敗都調用該方法,如果請求失敗,那麼error對象有值,否則那麼error對象為空
*/
-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error
(5)當接收到伺服器響應的時候,告訴伺服器接收資料(調用block)
//預設情況下,當接收到伺服器響應之後,伺服器認為用戶端不需要接收資料,是以後面的代理方法不會調用
//如果需要繼續接收伺服器傳回的資料,那麼需要調用block,并傳入對應的政策
/*
NSURLSessionResponseCancel = 0, 取消任務
NSURLSessionResponseAllow = 1, 接收任務
NSURLSessionResponseBecomeDownload = 2, 轉變成下載下傳
NSURLSessionResponseBecomeStream NS_ENUM_AVAILABLE(10_11, 9_0) = 3, 轉變成流
*/
completionHandler(NSURLSessionResponseAllow);
4.NSURLSessionDownloadTask實作大檔案下載下傳
- 4.1 涉及知識點
(1)使用NSURLSession和NSURLSessionDownload可以很友善的實作檔案下載下傳操作
/*
第一個參數:要下載下傳檔案的url路徑
第二個參數:當接收完伺服器傳回的資料之後調用該block
location:下載下傳的檔案的儲存位址(預設是存儲在沙盒中tmp檔案夾下面,随時會被删除)
response:伺服器響應資訊,響應頭
error:該請求的錯誤資訊
*/
//說明:downloadTaskWithURL方法已經實作了在下載下傳檔案資料的過程中邊下載下傳檔案資料,邊寫入到沙盒檔案的操作
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url completionHandler:^(NSURL * __nullable location, NSURLResponse * __nullable response, NSError * __nullable error)
(2)downloadTaskWithURL内部預設已經實作了變下載下傳邊寫入操作,是以不用開發人員擔心記憶體問題
(3)檔案下載下傳後預設儲存在tmp檔案目錄,需要開發人員手動的剪切到合适的沙盒目錄
(4)缺點:沒有辦法監控下載下傳進度
5.使用NSURLSessionDownloadTask實作大檔案下載下傳-監聽下載下傳進度
- 5.1 涉及知識點
(1)建立NSURLSession并設定代理,通過NSURLSessionDownloadTask并以代理的方式來完成大檔案的下載下傳
//1.建立NSULRSession,設定代理
self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//2.建立task
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
self.downloadTask = [self.session downloadTaskWithURL:url];
//3.執行task
[self.downloadTask resume];
(2)常用代理方法的說明
/*
1.當接收到下載下傳資料的時候調用,可以在該方法中監聽檔案下載下傳的進度
該方法會被調用多次
totalBytesWritten:已經寫入到檔案中的資料大小
totalBytesExpectedToWrite:目前檔案的總大小
bytesWritten:本次下載下傳的檔案資料大小
*/
-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
/*
2.恢複下載下傳的時候調用該方法
fileOffset:恢複之後,要從檔案的什麼地方開發下載下傳
expectedTotalBytes:該檔案資料的總大小
*/
-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
/*
3.下載下傳完成之後調用該方法
*/
-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location
/*
4.請求完成之後調用
如果請求失敗,那麼error有值
*/
-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error
(3)實作斷點下載下傳相關代碼
//如果任務,取消了那麼以後就不能恢複了
// [self.downloadTask cancel];
//如果采取這種方式來取消任務,那麼該方法會通過resumeData儲存目前檔案的下載下傳資訊
//隻要有了這份資訊,以後就可以通過這些資訊來恢複下載下傳
[self.downloadTask cancelByProducingResumeData:^(NSData * nullable resumeData) {
self.resumeData = resumeData;
}];
-----------
//繼續下載下傳
//首先通過之前儲存的resumeData資訊,建立一個下載下傳任務
self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];
[self.downloadTask resume];
(4)計算目前下載下傳進度
//擷取檔案下載下傳進度
self.progress.progress = * totalBytesWritten/totalBytesExpectedToWrite;
```
()局限性
如果使用者點選暫停之後退出程式,那麼需要把恢複下載下傳的資料寫一份到沙盒,代碼複雜度更
如果使用者在下載下傳中途未儲存恢複下載下傳資料即退出程式,則不具備可操作性
---
###使用NSURLSessionDataTask實作大檔案離線斷點下載下傳(完整)
- 涉及知識點
()關于NSOutputStream的使用
```objc
// 建立一個輸入流,資料追加到檔案的屁股上
//把資料寫入到指定的檔案位址,如果目前檔案不存在,則會自動建立
NSOutputStream *stream = [[NSOutputStream alloc]initWithURL:[NSURL fileURLWithPath:[self fullPath]] append:YES];
// 打開流
[stream open];
// 寫入流資料
[stream write:data.bytes maxLength:data.length];
//當不需要的時候應該關閉流
[stream close];
<div class="se-preview-section-delimiter"></div>
(2)關于網絡請求請求頭的設定(可以設定請求下載下傳檔案的某一部分)
//1. 設定請求對象
//1.1 建立請求路徑
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
//1.2 建立可變請求對象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//1.3 拿到目前檔案的殘留資料大小
self.currentContentLength = [self FileSize];
//1.4 告訴伺服器從哪個地方開始下載下傳檔案資料
NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentContentLength];
NSLog(@"%@",range);
//1.5 設定請求頭
[request setValue:range forHTTPHeaderField:@"Range"];
<div class="se-preview-section-delimiter"></div>
(3)NSURLSession對象的釋放
-(void)dealloc
{
//在最後的時候應該把session釋放,以免造成記憶體洩露
// NSURLSession設定過代理後,需要在最後(比如控制器銷毀的時候)調用session的invalidateAndCancel或者resetWithCompletionHandler,才不會有記憶體洩露
// [self.session invalidateAndCancel];
[self.session resetWithCompletionHandler:^{
NSLog(@"釋放---");
}];
}
<div class="se-preview-section-delimiter"></div>
(4)優化部分
01 關于檔案下載下傳進度的實時更新
02 方法的獨立與抽取
7.NSURLSession實作檔案上傳
- 7.1 涉及知識點
(1)實作檔案上傳的方法
/*
第一個參數:請求對象
第二個參數:請求體(要上傳的檔案資料)
block回調:
NSData:響應體
NSURLResponse:響應頭
NSError:請求的錯誤資訊
*/
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error)
<div class="se-preview-section-delimiter"></div>
(2)設定代理,在代理方法中監聽檔案上傳進度
/*
調用該方法上傳檔案資料
如果檔案資料很大,那麼該方法會被調用多次
參數說明:
totalBytesSent:已經上傳的檔案資料的大小
totalBytesExpectedToSend:檔案的總大小
*/
-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
NSLog(@"%.2f", * totalBytesSent/totalBytesExpectedToSend);
}
<div class="se-preview-section-delimiter"></div>
(3)關于NSURLSessionConfiguration相關
01 作用:可以統一配置NSURLSession,如請求逾時等
02 建立的方式和使用
//建立配置的三種方式
+ (NSURLSessionConfiguration *)defaultSessionConfiguration;
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(_10, _0);
//統一配置NSURLSession
-(NSURLSession *)session
{
if (_session == nil) {
//建立NSURLSessionConfiguration
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
//設定請求逾時為10秒鐘
config.timeoutIntervalForRequest = ;
//在蜂窩網絡情況下是否繼續請求(上傳或下載下傳)
config.allowsCellularAccess = NO;
_session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}
<div class="se-preview-section-delimiter"></div>
8.AFN架構基本使用
- 8.1 AFN内部結構
AFN結構體
- NSURLConnection
+ AFURLConnectionOperation
+ AFHTTPRequestOperation
+ AFHTTPRequestOperationManager(封裝了常用的 HTTP 方法)
* 屬性
* baseURL :AFN建議開發者針對 AFHTTPRequestOperationManager 自定義個一個單例子類,設定 baseURL, 所有的網絡通路,都隻使用相對路徑即可
* requestSerializer :請求資料格式/預設是二進制的 HTTP
* responseSerializer :響應的資料格式/預設是 JSON 格式
* operationQueue
* reachabilityManager :網絡連接配接管理器
* 方法
* manager :友善建立管理器的類方法
* HTTPRequestOperationWithRequest :在通路伺服器時,如果要告訴伺服器一些附加資訊,都需要在 Request 中設定
* GET
* POST
- NSURLSession
+ AFURLSessionManager
+ AFHTTPSessionManager(封裝了常用的 HTTP 方法)
* GET
* POST
* UIKit + AFNetworking 分類
* NSProgress :利用KVO
- 半自動的序列化&反序列化的功能
+ AFURLRequestSerialization :請求的資料格式/預設是二進制的
+ AFURLResponseSerialization :響應的資料格式/預設是JSON格式
- 附加功能
+ 安全政策
* HTTPS
* AFSecurityPolicy
+ 網絡檢測
* 對蘋果的網絡連接配接檢測做了一個封裝
* AFNetworkReachabilityManager
建議:
可以學習下AFN對 UIKit 做了一些分類, 對自己能力提升是非常有幫助的
<div class="se-preview-section-delimiter"></div>
- 8.2 AFN的基本使用
(1)發送GET請求的兩種方式(POST同)
-(void)get1
{
//1.建立AFHTTPRequestOperationManager管理者
//AFHTTPRequestOperationManager内部是基于NSURLConnection實作的
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
//2.發送請求
/*
http://120.25.226.186:32812/login?username=ee&pwd=ee&type=JSON
第一個參數:NSString類型的請求路徑,AFN内部會自動将該路徑包裝為一個url并建立請求對象
第二個參數:請求參數,以字典的方式傳遞,AFN内部會判斷目前是POST請求還是GET請求,以選擇直接拼接還是轉換為NSData放到請求體中傳遞
第三個參數:請求成功之後回調Block
第四個參數:請求失敗回調Block
*/
NSDictionary *param = @{
@"username":@"520it",
@"pwd":@"520it"
};
//注意:字元串中不能包含空格
[manager GET:@"http://120.25.226.186:32812/login" parameters:param success:^(AFHTTPRequestOperation * _Nonnull operation, id _Nonnull responseObject) {
NSLog(@"請求成功---%@",responseObject);
} failure:^(AFHTTPRequestOperation * _Nonnull operation, NSError * _Nonnull error) {
NSLog(@"失敗---%@",error);
}];
}
-(void)get2
{
//1.建立AFHTTPSessionManager管理者
//AFHTTPSessionManager内部是基于NSURLSession實作的
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//2.發送請求
NSDictionary *param = @{
@"username":@"520it",
@"pwd":@"520it"
};
//注意:responseObject:請求成功傳回的響應結果(AFN内部已經把響應體轉換為OC對象,通常是字典或數組)
[manager GET:@"http://120.25.226.186:32812/login" parameters:param success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) {
NSLog(@"請求成功---%@",[responseObject class]);
} failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
NSLog(@"失敗---%@",error);
}];
}
<div class="se-preview-section-delimiter"></div>
(2)使用AFN下載下傳檔案
-(void)download
{
//1.建立一個管理者
AFHTTPSessionManager *manage = [AFHTTPSessionManager manager];
//2.下載下傳檔案
/*
第一個參數:請求對象
第二個參數:下載下傳進度
第三個參數:block回調,需要傳回一個url位址,用來告訴AFN下載下傳檔案的目标位址
targetPath:AFN内部下載下傳檔案存儲的位址,tmp檔案夾下
response:請求的響應頭
傳回值:檔案應該剪切到什麼地方
第四個參數:block回調,當檔案下載下傳完成之後調用
response:響應頭
filePath:檔案存儲在沙盒的位址 == 第三個參數中block的傳回值
error:錯誤資訊
*/
//2.1 建立請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_02.png"]];
//2.2 建立下載下傳進度,并監聽
NSProgress *progress = nil;
NSURLSessionDownloadTask *downloadTask = [manage downloadTaskWithRequest:request progress:&progress destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
//拼接檔案全路徑
NSString *fullpath = [caches stringByAppendingPathComponent:response.suggestedFilename];
NSURL *filePathUrl = [NSURL fileURLWithPath:fullpath];
return filePathUrl;
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nonnull filePath, NSError * _Nonnull error) {
NSLog(@"檔案下載下傳完畢---%@",filePath);
}];
//2.3 使用KVO監聽下載下傳進度
[progress addObserver:self forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew context:nil];
//3.啟動任務
[downloadTask resume];
}
//擷取并計算目前檔案的下載下傳進度
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(NSProgress *)progress change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
NSLog(@"%zd--%zd--%f",progress.completedUnitCount,progress.totalUnitCount, * progress.completedUnitCount/progress.totalUnitCount);
}
<div class="se-preview-section-delimiter"></div>
9.Cocoapods的安裝
先更新Gem
sudo gem update --system
切換cocoapods的資料源
【先删除,再添加,檢視】
gem sources --remove https://rubygems.org/
gem sources -a https://ruby.taobao.org/
gem sources -l
安裝cocoapods
sudo gem install cocoapods
将Podspec檔案托管位址從github切換到國内的oschina
【先删除,再添加,再更新】
pod repo remove master
pod repo add master http://git.oschina.net/akuandev/Specs.git
pod repo add master https://gitcafe.com/akuandev/Specs.git
pod repo update
設定pod倉庫
pod setup
測試
【如果有版本号,則說明已經安裝成功】
pod --version
利用cocoapods來安裝第三方架構
進入要安裝架構的項目的.xcodeproj同級檔案夾
在該檔案夾中建立一個檔案Podfile
在檔案中告訴cocoapods需要安裝的架構資訊
a.該架構支援的平台
b.适用的iOS版本
c.架構的名稱
d.架構的版本
安裝
pod install --no-repo-update
pod update --no-repo-update
//如果任務,取消了那麼以後就不能恢複了
// [self.downloadTask cancel];
//如果采取這種方式來取消任務,那麼該方法會通過resumeData儲存目前檔案的下載下傳資訊
//隻要有了這份資訊,以後就可以通過這些資訊來恢複下載下傳
[self.downloadTask cancelByProducingResumeData:^(NSData * nullable resumeData) {
self.resumeData = resumeData;
}];
-----------
//繼續下載下傳
//首先通過之前儲存的resumeData資訊,建立一個下載下傳任務
self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];
[self.downloadTask resume];
(4)計算目前下載下傳進度
objc
//擷取檔案下載下傳進度
self.progress.progress = 1.0 * totalBytesWritten/totalBytesExpectedToWrite;
(5)局限性
01 如果使用者點選暫停之後退出程式,那麼需要把恢複下載下傳的資料寫一份到沙盒,代碼複雜度更
02 如果使用者在下載下傳中途未儲存恢複下載下傳資料即退出程式,則不具備可操作性