多線程網(wǎng)絡(luò)-6

Xmind

多線程和網(wǎng)絡(luò)6.jpg

基本使用

/*A*網(wǎng)頁(yè)操控相關(guān)方法**/
    [self.webView goBack];      回退
    [self.webView goForward];   前進(jìn)
    [self.webView reload];      刷新

    //設(shè)置是否能夠前進(jìn)和回退
    self.goBackBtn.enabled = webView.canGoBack;
    self.fowardBtn.enabled = webView.canGoForward;

/*B*常用的屬性設(shè)置**/
    self.webView.scalesPageToFit = YES; 設(shè)置網(wǎng)頁(yè)自動(dòng)適應(yīng)
    self.webView.dataDetectorTypes = UIDataDetectorTypeAll; 設(shè)置檢測(cè)網(wǎng)頁(yè)中的格式類型未斑,all表示檢測(cè)所有類型包括超鏈接吉执、電話號(hào)碼、地址等。
    self.webView.scrollView.contentInset = UIEdgeInsetsMake(50, 0, 0, 0);

/*C*相關(guān)代理方法**/
    //每當(dāng)將加載請(qǐng)求的時(shí)候調(diào)用該方法,返回YES 表示加載該請(qǐng)求,返回NO 表示不加載該請(qǐng)求
    //可以在該方法中攔截請(qǐng)求
    -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
        return ![request.URL.absoluteString containsString:@"dushu"];
    }

    //開(kāi)始加載網(wǎng)頁(yè),不僅監(jiān)聽(tīng)我們指定的請(qǐng)求,還會(huì)監(jiān)聽(tīng)內(nèi)部發(fā)送的請(qǐng)求
    -(void)webViewDidStartLoad:(UIWebView *)webView

    //網(wǎng)頁(yè)加載完畢之后會(huì)調(diào)用該方法
    -(void)webViewDidFinishLoad:(UIWebView *)webView

    //網(wǎng)頁(yè)加載失敗調(diào)用該方法
    -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error

/*D*其它知識(shí)點(diǎn)-加載本地資源**/
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"text.html" withExtension:nil];
    [self.webView loadRequest:[NSURLRequest requestWithURL:url]];

PPT

文件下載上傳

Snip20170409_1.png
Snip20170409_2.png
Snip20170409_3.png
Snip20170409_4.png
Snip20170409_5.png
Snip20170409_6.png
Snip20170409_7.png

NSURLSession

Snip20170409_8.png
Snip20170409_9.png
Snip20170409_10.png
Snip20170409_11.png

UIWebView

Snip20170409_12.png
Snip20170409_13.png
Snip20170409_14.png
Snip20170409_15.png
Snip20170409_16.png
Snip20170409_17.png
Snip20170409_18.png
Snip20170409_19.png

GitBook

1 NSURLConnection和Runloop(面試)

(1)兩種為NSURLConnection設(shè)置代理方式的區(qū)別

    //第一種設(shè)置方式:
    //通過(guò)該方法設(shè)置代理喊儡,會(huì)自動(dòng)的發(fā)送請(qǐng)求
    // [[NSURLConnection alloc]initWithRequest:request delegate:self];

    //第二種設(shè)置方式:
    //設(shè)置代理,startImmediately為NO的時(shí)候稻据,該方法不會(huì)自動(dòng)發(fā)送請(qǐng)求
    NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
    //手動(dòng)通過(guò)代碼的方式來(lái)發(fā)送請(qǐng)求
    //注意該方法內(nèi)部會(huì)自動(dòng)的把connect添加到當(dāng)前線程的RunLoop中在默認(rèn)模式下執(zhí)行
    [connect start];

(2)如何控制代理方法在哪個(gè)線程調(diào)用

    //說(shuō)明:默認(rèn)情況下艾猜,代理方法會(huì)在主線程中進(jìn)行調(diào)用(為了方便開(kāi)發(fā)者拿到數(shù)據(jù)后處理一些刷新UI的操作不需要考慮到線程間通信)
    //設(shè)置代理方法的執(zhí)行隊(duì)列
    [connect setDelegateQueue:[[NSOperationQueue alloc]init]];

(3)開(kāi)子線程發(fā)送網(wǎng)絡(luò)請(qǐng)求的注意點(diǎn),適用于自動(dòng)發(fā)送網(wǎng)絡(luò)請(qǐng)求模式


//在子線程中發(fā)送網(wǎng)絡(luò)請(qǐng)求-調(diào)用startf方法發(fā)送
-(void)createNewThreadSendConnect1
{
    //1.創(chuàng)建一個(gè)非主隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

    //2.封裝操作,并把任務(wù)添加到隊(duì)列中執(zhí)行
    [queue addOperationWithBlock:^{

        NSLog(@"%@",[NSThread currentThread]);
        //2-1.確定請(qǐng)求路徑
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=dd&pwd=ww&type=JSON"];

        //2-2.創(chuàng)建請(qǐng)求對(duì)象
        NSURLRequest *request = [NSURLRequest requestWithURL:url];

        //2-3.使用NSURLConnection設(shè)置代理匆赃,發(fā)送網(wǎng)絡(luò)請(qǐng)求
        NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES];

        //2-4.設(shè)置代理方法在哪個(gè)隊(duì)列中執(zhí)行淤毛,如果是非主隊(duì)列,那么代理方法將再子線程中執(zhí)行
        [connection setDelegateQueue:[[NSOperationQueue alloc]init]];

        //2-5.發(fā)送網(wǎng)絡(luò)請(qǐng)求
        //注意:start方法內(nèi)部會(huì)把當(dāng)前的connect對(duì)象作為一個(gè)source添加到當(dāng)前線程對(duì)應(yīng)的runloop中
        //區(qū)別在于炸庞,如果調(diào)用start方法開(kāi)發(fā)送網(wǎng)絡(luò)請(qǐng)求钱床,那么再添加source的過(guò)程中,如果當(dāng)前runloop不存在
        //那么該方法內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)當(dāng)前線程對(duì)應(yīng)的runloop,并啟動(dòng)埠居。
        [connection start];

    }];
}

//在子線程中發(fā)送網(wǎng)絡(luò)請(qǐng)求-自動(dòng)發(fā)送網(wǎng)絡(luò)請(qǐng)求
-(void)createNewThreadSendConnect2
{
    NSLog(@"-----");
    //1.創(chuàng)建一個(gè)非主隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

    //2.封裝操作查牌,并把任務(wù)添加到隊(duì)列中執(zhí)行
    [queue addOperationWithBlock:^{

        //2-1.確定請(qǐng)求路徑
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=dd&pwd=ww&type=JSON"];

        //2-2.創(chuàng)建請(qǐng)求對(duì)象
        NSURLRequest *request = [NSURLRequest requestWithURL:url];

        //2-3.使用NSURLConnection設(shè)置代理,發(fā)送網(wǎng)絡(luò)請(qǐng)求
        //注意:該方法內(nèi)部雖然會(huì)把connection添加到runloop,但是如果當(dāng)前的runloop不存在滥壕,那么不會(huì)主動(dòng)創(chuàng)建纸颜。
        NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];

        //2-4.設(shè)置代理方法在哪個(gè)隊(duì)列中執(zhí)行,如果是非主隊(duì)列绎橘,那么代理方法將再子線程中執(zhí)行
        [connection setDelegateQueue:[[NSOperationQueue alloc]init]];

        //2-5 創(chuàng)建當(dāng)前線程對(duì)應(yīng)的runloop,并開(kāi)啟
       [[NSRunLoop currentRunLoop]run];
    }];
}


2 NSURLSession的基本使用

(1)使用步驟

    使用NSURLSession創(chuàng)建task,然后執(zhí)行task

(2)關(guān)于task

    a.NSURLSessionTask是一個(gè)抽象類胁孙,本身不能使用,只能使用它的子類
    b.NSURLSessionDataTask\NSURLSessionUploadTask\NSURLSessionDownloadTask

(3)發(fā)送get請(qǐng)求

    //1.創(chuàng)建NSURLSession對(duì)象(可以獲取單例對(duì)象)
    NSURLSession *session = [NSURLSession sharedSession];

    //2.根據(jù)NSURLSession對(duì)象創(chuàng)建一個(gè)Task

    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=ss&pwd=ss&type=JSON"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    //方法參數(shù)說(shuō)明
    /*
    注意:該block是在子線程中調(diào)用的称鳞,如果拿到數(shù)據(jù)之后要做一些UI刷新操作涮较,那么需要回到主線程刷新
    第一個(gè)參數(shù):需要發(fā)送的請(qǐng)求對(duì)象
    block:當(dāng)請(qǐng)求結(jié)束拿到服務(wù)器響應(yīng)的數(shù)據(jù)時(shí)調(diào)用block
    block-NSData:該請(qǐng)求的響應(yīng)體
    block-NSURLResponse:存放本次請(qǐng)求的響應(yīng)信息,響應(yīng)頭冈止,真實(shí)類型為NSHTTPURLResponse
    block-NSErroe:請(qǐng)求錯(cuò)誤信息
     */
   NSURLSessionDataTask * dataTask =  [session dataTaskWithRequest:request completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error) {

        //拿到響應(yīng)頭信息
        NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;

        //4.解析拿到的響應(yīng)數(shù)據(jù)
        NSLog(@"%@\n%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],res.allHeaderFields);
    }];

    //3.執(zhí)行Task
    //注意:剛創(chuàng)建出來(lái)的task默認(rèn)是掛起狀態(tài)的狂票,需要調(diào)用該方法來(lái)啟動(dòng)任務(wù)(執(zhí)行任務(wù))
    [dataTask resume];

(4)發(fā)送get請(qǐng)求的第二種方式

  //注意:該方法內(nèi)部默認(rèn)會(huì)把URL對(duì)象包裝成一個(gè)NSURLRequest對(duì)象(默認(rèn)是GET請(qǐng)求)
    //方法參數(shù)說(shuō)明
    /*
    //第一個(gè)參數(shù):發(fā)送請(qǐng)求的URL地址
    //block:當(dāng)請(qǐng)求結(jié)束拿到服務(wù)器響應(yīng)的數(shù)據(jù)時(shí)調(diào)用block
    //block-NSData:該請(qǐng)求的響應(yīng)體
    //block-NSURLResponse:存放本次請(qǐng)求的響應(yīng)信息,響應(yīng)頭熙暴,真實(shí)類型為NSHTTPURLResponse
    //block-NSErroe:請(qǐng)求錯(cuò)誤信息
     */
- (nullable NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error))completionHandler;

(5)發(fā)送POST請(qǐng)求

        //1.創(chuàng)建NSURLSession對(duì)象(可以獲取單例對(duì)象)
    NSURLSession *session = [NSURLSession sharedSession];

    //2.根據(jù)NSURLSession對(duì)象創(chuàng)建一個(gè)Task

    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];

    //創(chuàng)建一個(gè)請(qǐng)求對(duì)象闺属,并這是請(qǐng)求方法為POST,把參數(shù)放在請(qǐng)求體中傳遞
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";
    request.HTTPBody = [@"username=520it&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];

    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error) {
        //拿到響應(yīng)頭信息
        NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;

        //解析拿到的響應(yīng)數(shù)據(jù)
        NSLog(@"%@\n%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],res.allHeaderFields);
    }];

    //3.執(zhí)行Task
    //注意:剛創(chuàng)建出來(lái)的task默認(rèn)是掛起狀態(tài)的周霉,需要調(diào)用該方法來(lái)啟動(dòng)任務(wù)(執(zhí)行任務(wù))
    [dataTask resume];

3 NSURLSession下載文件-代理

(1)創(chuàng)建NSURLSession對(duì)象掂器,設(shè)置代理(默認(rèn)配置)

 //1.創(chuàng)建NSURLSession,并設(shè)置代理
    /*
     第一個(gè)參數(shù):session對(duì)象的全局配置設(shè)置,一般使用默認(rèn)配置就可以
     第二個(gè)參數(shù):誰(shuí)成為session對(duì)象的代理
     第三個(gè)參數(shù):代理方法在哪個(gè)隊(duì)列中執(zhí)行(在哪個(gè)線程中調(diào)用),如果是主隊(duì)列那么在主線程中執(zhí)行俱箱,如果是非主隊(duì)列国瓮,那么在子線程中執(zhí)行
     */
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

(2)根據(jù)Session對(duì)象創(chuàng)建一個(gè)NSURLSessionDataTask任務(wù)(post和get選擇)

//創(chuàng)建task
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];

//注意:如果要發(fā)送POST請(qǐng)求,那么請(qǐng)使用dataTaskWithRequest,設(shè)置一些請(qǐng)求頭信息
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url];

(3)執(zhí)行任務(wù)(其它方法狞谱,如暫停巍膘、取消等)

    //啟動(dòng)task
    //[dataTask resume];
    //其它方法,如取消任務(wù)芋簿,暫停任務(wù)等
    //[dataTask cancel];
    //[dataTask suspend];

(4)遵守代理協(xié)議,實(shí)現(xiàn)代理方法(3個(gè)相關(guān)的代理方法)

/*
 1.當(dāng)接收到服務(wù)器響應(yīng)的時(shí)候調(diào)用
     session:發(fā)送請(qǐng)求的session對(duì)象
     dataTask:根據(jù)NSURLSession創(chuàng)建的task任務(wù)
     response:服務(wù)器響應(yīng)信息(響應(yīng)頭)
     completionHandler:通過(guò)該block回調(diào)璃饱,告訴服務(wù)器端是否接收返回的數(shù)據(jù)
 */
-(void)URLSession:(nonnull NSURLSession *)session dataTask:(nonnull NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler

/*
 2.當(dāng)接收到服務(wù)器返回的數(shù)據(jù)時(shí)調(diào)用
 該方法可能會(huì)被調(diào)用多次
 */
-(void)URLSession:(nonnull NSURLSession *)session dataTask:(nonnull NSURLSessionDataTask *)dataTask didReceiveData:(nonnull NSData *)data

/*
 3.當(dāng)請(qǐng)求完成之后調(diào)用該方法
 不論是請(qǐng)求成功還是請(qǐng)求失敗都調(diào)用該方法与斤,如果請(qǐng)求失敗,那么error對(duì)象有值,否則那么error對(duì)象為空
 */
-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error

(5)當(dāng)接收到服務(wù)器響應(yīng)的時(shí)候撩穿,告訴服務(wù)器接收數(shù)據(jù)(調(diào)用block)

//默認(rèn)情況下磷支,當(dāng)接收到服務(wù)器響應(yīng)之后,服務(wù)器認(rèn)為客戶端不需要接收數(shù)據(jù)食寡,所以后面的代理方法不會(huì)調(diào)用
    //如果需要繼續(xù)接收服務(wù)器返回的數(shù)據(jù)雾狈,那么需要調(diào)用block,并傳入對(duì)應(yīng)的策略

    /*
        NSURLSessionResponseCancel = 0, 取消任務(wù)
        NSURLSessionResponseAllow = 1,  接收任務(wù)
        NSURLSessionResponseBecomeDownload = 2, 轉(zhuǎn)變成下載
        NSURLSessionResponseBecomeStream NS_ENUM_AVAILABLE(10_11, 9_0) = 3, 轉(zhuǎn)變成流
    */

    completionHandler(NSURLSessionResponseAllow);

4 NSURLSessionDownloadTask實(shí)現(xiàn)大文件下載

(1)使用NSURLSession和NSURLSessionDownload可以很方便的實(shí)現(xiàn)文件下載操作

 /*
     第一個(gè)參數(shù):要下載文件的url路徑
     第二個(gè)參數(shù):當(dāng)接收完服務(wù)器返回的數(shù)據(jù)之后調(diào)用該block
     location:下載的文件的保存地址(默認(rèn)是存儲(chǔ)在沙盒中tmp文件夾下面,隨時(shí)會(huì)被刪除)
     response:服務(wù)器響應(yīng)信息抵皱,響應(yīng)頭
     error:該請(qǐng)求的錯(cuò)誤信息
     */
    //說(shuō)明:downloadTaskWithURL方法已經(jīng)實(shí)現(xiàn)了在下載文件數(shù)據(jù)的過(guò)程中邊下載文件數(shù)據(jù)善榛,邊寫(xiě)入到沙盒文件的操作
    NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url completionHandler:^(NSURL * __nullable location, NSURLResponse * __nullable response, NSError * __nullable error)

(2)downloadTaskWithURL內(nèi)部默認(rèn)已經(jīng)實(shí)現(xiàn)了變下載邊寫(xiě)入操作,所以不用開(kāi)發(fā)人員擔(dān)心內(nèi)存問(wèn)題

(3)文件下載后默認(rèn)保存在tmp文件目錄呻畸,需要開(kāi)發(fā)人員手動(dòng)的剪切到合適的沙盒目錄

(4)缺點(diǎn):沒(méi)有辦法監(jiān)控下載進(jìn)度


5 使用NSURLSessionDownloadTask實(shí)現(xiàn)大文件下載-監(jiān)聽(tīng)下載進(jìn)度

(1)創(chuàng)建NSURLSession并設(shè)置代理移盆,通過(guò)NSURLSessionDownloadTask并以代理的方式來(lái)完成大文件的下載

     //1.創(chuàng)建NSULRSession,設(shè)置代理
    self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    //2.創(chuàng)建task
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
    self.downloadTask = [self.session downloadTaskWithURL:url];

    //3.執(zhí)行task
    [self.downloadTask resume];

(2)常用代理方法的說(shuō)明

    /*
 1.當(dāng)接收到下載數(shù)據(jù)的時(shí)候調(diào)用,可以在該方法中監(jiān)聽(tīng)文件下載的進(jìn)度
 該方法會(huì)被調(diào)用多次
 totalBytesWritten:已經(jīng)寫(xiě)入到文件中的數(shù)據(jù)大小
 totalBytesExpectedToWrite:目前文件的總大小
 bytesWritten:本次下載的文件數(shù)據(jù)大小
 */
-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
/*
 2.恢復(fù)下載的時(shí)候調(diào)用該方法
 fileOffset:恢復(fù)之后,要從文件的什么地方開(kāi)發(fā)下載
 expectedTotalBytes:該文件數(shù)據(jù)的總大小
 */
-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
/*
 3.下載完成之后調(diào)用該方法
 */
-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location
/*
 4.請(qǐng)求完成之后調(diào)用
 如果請(qǐng)求失敗伤为,那么error有值
 */
-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error

(3)實(shí)現(xiàn)斷點(diǎn)下載相關(guān)代碼

    //如果任務(wù)咒循,取消了那么以后就不能恢復(fù)了
    //    [self.downloadTask cancel];

    //如果采取這種方式來(lái)取消任務(wù),那么該方法會(huì)通過(guò)resumeData保存當(dāng)前文件的下載信息
    //只要有了這份信息绞愚,以后就可以通過(guò)這些信息來(lái)恢復(fù)下載
    [self.downloadTask cancelByProducingResumeData:^(NSData * __nullable resumeData) {
        self.resumeData = resumeData;
    }];

    -----------
    //繼續(xù)下載
    //首先通過(guò)之前保存的resumeData信息叙甸,創(chuàng)建一個(gè)下載任務(wù)
    self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];

     [self.downloadTask resume];

(4)計(jì)算當(dāng)前下載進(jìn)度

    //獲取文件下載進(jìn)度
    self.progress.progress = 1.0 * totalBytesWritten/totalBytesExpectedToWrite;

(5)局限性

01 如果用戶點(diǎn)擊暫停之后退出程序,那么需要把恢復(fù)下載的數(shù)據(jù)寫(xiě)一份到沙盒位衩,代碼復(fù)雜度更
02 如果用戶在下載中途未保存恢復(fù)下載數(shù)據(jù)即退出程序裆蒸,則不具備可操作性

6 使用NSURLSessionDataTask實(shí)現(xiàn)大文件離線斷點(diǎn)下載(完整)

(1)關(guān)于NSOutputStream的使用

    //1. 創(chuàng)建一個(gè)輸入流,數(shù)據(jù)追加到文件的屁股上
    //把數(shù)據(jù)寫(xiě)入到指定的文件地址,如果當(dāng)前文件不存在蚂四,則會(huì)自動(dòng)創(chuàng)建
    NSOutputStream *stream = [[NSOutputStream alloc]initWithURL:[NSURL fileURLWithPath:[self fullPath]] append:YES];

    //2. 打開(kāi)流
    [stream open];

    //3. 寫(xiě)入流數(shù)據(jù)
    [stream write:data.bytes maxLength:data.length];

    //4.當(dāng)不需要的時(shí)候應(yīng)該關(guān)閉流
    [stream close];

(2)關(guān)于網(wǎng)絡(luò)請(qǐng)求請(qǐng)求頭的設(shè)置(可以設(shè)置請(qǐng)求下載文件的某一部分)

    //1. 設(shè)置請(qǐng)求對(duì)象
    //1.1 創(chuàng)建請(qǐng)求路徑
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];

    //1.2 創(chuàng)建可變請(qǐng)求對(duì)象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    //1.3 拿到當(dāng)前文件的殘留數(shù)據(jù)大小
    self.currentContentLength = [self FileSize];

    //1.4 告訴服務(wù)器從哪個(gè)地方開(kāi)始下載文件數(shù)據(jù)
    NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentContentLength];
    NSLog(@"%@",range);

    //1.5 設(shè)置請(qǐng)求頭
    [request setValue:range forHTTPHeaderField:@"Range"];

(3)NSURLSession對(duì)象的釋放

-(void)dealloc
{
    //在最后的時(shí)候應(yīng)該把session釋放光戈,以免造成內(nèi)存泄露
    //    NSURLSession設(shè)置過(guò)代理后,需要在最后(比如控制器銷毀的時(shí)候)調(diào)用session的invalidateAndCancel或者resetWithCompletionHandler遂赠,才不會(huì)有內(nèi)存泄露
    //    [self.session invalidateAndCancel];
    [self.session resetWithCompletionHandler:^{

        NSLog(@"釋放---");
    }];
}

(4)優(yōu)化部分

    01 關(guān)于文件下載進(jìn)度的實(shí)時(shí)更新
    02 方法的獨(dú)立與抽取

7 NSURLSession實(shí)現(xiàn)文件上傳

(1)實(shí)現(xiàn)文件上傳的方法

      /*
     第一個(gè)參數(shù):請(qǐng)求對(duì)象
     第二個(gè)參數(shù):請(qǐng)求體(要上傳的文件數(shù)據(jù))
     block回調(diào):
     NSData:響應(yīng)體
     NSURLResponse:響應(yīng)頭
     NSError:請(qǐng)求的錯(cuò)誤信息
     */
    NSURLSessionUploadTask *uploadTask =  [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error)

(2)設(shè)置代理久妆,在代理方法中監(jiān)聽(tīng)文件上傳進(jìn)度

/*
 調(diào)用該方法上傳文件數(shù)據(jù)
 如果文件數(shù)據(jù)很大,那么該方法會(huì)被調(diào)用多次
 參數(shù)說(shuō)明:
     totalBytesSent:已經(jīng)上傳的文件數(shù)據(jù)的大小
     totalBytesExpectedToSend:文件的總大小
 */
-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
    NSLog(@"%.2f",1.0 * totalBytesSent/totalBytesExpectedToSend);
}

(3)關(guān)于NSURLSessionConfiguration相關(guān)

01 作用:可以統(tǒng)一配置NSURLSession,如請(qǐng)求超時(shí)等
02 創(chuàng)建的方式和使用
//創(chuàng)建配置的三種方式
+ (NSURLSessionConfiguration *)defaultSessionConfiguration;
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0);

//統(tǒng)一配置NSURLSession
-(NSURLSession *)session
{
    if (_session == nil) {

        //創(chuàng)建NSURLSessionConfiguration
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

        //設(shè)置請(qǐng)求超時(shí)為10秒鐘
        config.timeoutIntervalForRequest = 10;

        //在蜂窩網(wǎng)絡(luò)情況下是否繼續(xù)請(qǐng)求(上傳或下載)
        config.allowsCellularAccess = NO;

        _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    }
    return _session;
}

8 WebView的基本使用
1 概念性知識(shí)
    01 webView是有缺點(diǎn)的跷睦,會(huì)導(dǎo)致內(nèi)存泄露筷弦,而且這個(gè)問(wèn)題是它系統(tǒng)本身的問(wèn)題。
    02 手機(jī)上面的safai其實(shí)就是用webView來(lái)實(shí)現(xiàn)的
    03 現(xiàn)在的開(kāi)發(fā)并不完全是原生的開(kāi)發(fā)抑诸,而更加傾向于原生+Html5的方式
    04 webView是OC代碼和html代碼之間進(jìn)行交互的橋梁

2 代碼相關(guān)
/*A*網(wǎng)頁(yè)操控相關(guān)方法**/
    [self.webView goBack];      回退
    [self.webView goForward];   前進(jìn)
    [self.webView reload];      刷新

    //設(shè)置是否能夠前進(jìn)和回退
    self.goBackBtn.enabled = webView.canGoBack;
    self.fowardBtn.enabled = webView.canGoForward;

/*B*常用的屬性設(shè)置**/
    self.webView.scalesPageToFit = YES; 設(shè)置網(wǎng)頁(yè)自動(dòng)適應(yīng)
    self.webView.dataDetectorTypes = UIDataDetectorTypeAll; 設(shè)置檢測(cè)網(wǎng)頁(yè)中的格式類型烂琴,all表示檢測(cè)所有類型包括超鏈接、電話號(hào)碼蜕乡、地址等奸绷。
    self.webView.scrollView.contentInset = UIEdgeInsetsMake(50, 0, 0, 0);

/*C*相關(guān)代理方法**/
    //每當(dāng)將加載請(qǐng)求的時(shí)候調(diào)用該方法,返回YES 表示加載該請(qǐng)求层玲,返回NO 表示不加載該請(qǐng)求
    //可以在該方法中攔截請(qǐng)求
    -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
        return ![request.URL.absoluteString containsString:@"dushu"];
    }

    //開(kāi)始加載網(wǎng)頁(yè)号醉,不僅監(jiān)聽(tīng)我們指定的請(qǐng)求反症,還會(huì)監(jiān)聽(tīng)內(nèi)部發(fā)送的請(qǐng)求
    -(void)webViewDidStartLoad:(UIWebView *)webView

    //網(wǎng)頁(yè)加載完畢之后會(huì)調(diào)用該方法
    -(void)webViewDidFinishLoad:(UIWebView *)webView

    //網(wǎng)頁(yè)加載失敗調(diào)用該方法
    -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error

/*D*其它知識(shí)點(diǎn)-加載本地資源**/
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"text.html" withExtension:nil];
    [self.webView loadRequest:[NSURLRequest requestWithURL:url]];
9 HTML
1.Html決定網(wǎng)頁(yè)的內(nèi)容,css決定網(wǎng)頁(yè)的樣式畔派,js決定網(wǎng)頁(yè)的事件
2.html學(xué)習(xí)網(wǎng)站:http://www.w3school.com.cn
10 NSURLSessionConfiguration
NSURLSessionConfiguration對(duì)象用于初始化NSURLSession對(duì)象铅碍。

展開(kāi)請(qǐng)求級(jí)別中與NSMutableURLRequest相關(guān)的可供選擇的方案,我們可以看到NSURLSessionConfiguration對(duì)于會(huì)話如何產(chǎn)生請(qǐng)求线椰,提供了相當(dāng)多的控制和靈活性胞谈。從網(wǎng)絡(luò)訪問(wèn)性能,到cookie憨愉,安全性烦绳,緩存策略,自定義協(xié)議莱衩,啟動(dòng)事件設(shè)置爵嗅,以及用于移動(dòng)設(shè)備優(yōu)化的幾個(gè)新屬性,你會(huì)發(fā)現(xiàn)你一直在尋找的笨蚁,正是NSURLSessionConfiguration睹晒。

會(huì)話在初始化時(shí)復(fù)制它們的配置,NSURLSession有一個(gè)只讀的配置屬性括细,使得該配置對(duì)象上的變化對(duì)這個(gè)會(huì)話的政策無(wú)效伪很。配置在初始化時(shí)被讀取一次,之后都是不會(huì)變化的奋单。

-構(gòu)造方法

NSURLSessionConfiguration有三個(gè)類構(gòu)造函數(shù)锉试,這很好地說(shuō)明了NSURLSession是為不同的用例而設(shè)計(jì)的。

+ "defaultSessionConfiguration"返回標(biāo)準(zhǔn)配置览濒,這實(shí)際上與NSURLConnection的網(wǎng)絡(luò)協(xié)議棧是一樣的呆盖,具有相同的共享NSHTTPCookieStorage,共享NSURLCache和共享NSURLCredentialStorage贷笛。
+ "ephemeralSessionConfiguration"返回一個(gè)預(yù)設(shè)配置应又,沒(méi)有持久性存儲(chǔ)的緩存,Cookie或證書(shū)乏苦。這對(duì)于實(shí)現(xiàn)像"秘密瀏覽"功能的功能來(lái)說(shuō)株扛,是很理想的。
+ "backgroundSessionConfiguration":獨(dú)特之處在于汇荐,它會(huì)創(chuàng)建一個(gè)后臺(tái)會(huì)話洞就。后臺(tái)會(huì)話不同于常規(guī)的,普通的會(huì)話掀淘,它甚至可以在應(yīng)用程序掛起旬蟋,退出,崩潰的情況下運(yùn)行上傳和下載任務(wù)革娄。初始化時(shí)指定的標(biāo)識(shí)符咖为,被用于向任何可能在進(jìn)程外恢復(fù)后臺(tái)傳輸?shù)氖刈o(hù)進(jìn)程提供上下文秕狰。

想要查看更多關(guān)于后臺(tái)會(huì)話的信息,可以查看WWDC Session 204: “What’s New with Multitasking”

-NSURLSessionConfiguration的屬性

NSURLSessionConfiguration擁有20個(gè)屬性躁染。熟練掌握這些屬性的用處,將使應(yīng)用程序充分利用其網(wǎng)絡(luò)環(huán)境架忌。

最重要的屬性:
# 替代 request 中的 forHTTPHeaderField 告訴服務(wù)器有關(guān)客戶端的附加信息
"HTTPAdditionalHeaders"指定了一組默認(rèn)的可以設(shè)置出站請(qǐng)求的數(shù)據(jù)頭吞彤。這對(duì)于跨會(huì)話共享信息,如內(nèi)容類型叹放,語(yǔ)言饰恕,用戶代理,身份認(rèn)證井仰,是很有用的埋嵌。

# WebDav的身份驗(yàn)證
NSString *userPasswordString = [NSString stringWithFormat:@"%@:%@", user, password];
NSData * userPasswordData = [userPasswordString dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64EncodedCredential = [userPasswordData base64EncodedStringWithOptions:0];
NSString *authString = [NSString stringWithFormat:@"Basic: %@", base64EncodedCredential];

# 設(shè)置客戶端類型
NSString *userAgentString = @"iPhone AppleWebKit";

configuration.HTTPAdditionalHeaders = @{@"Accept": @"application/json",
                                        @"Accept-Language": @"en",
                                        @"Authorization": authString,
                                        @"User-Agent": userAgentString};

"networkServiceType(網(wǎng)絡(luò)服務(wù)類型)"對(duì)標(biāo)準(zhǔn)的網(wǎng)絡(luò)流量,網(wǎng)絡(luò)電話俱恶,語(yǔ)音雹嗦,視頻,以及由一個(gè)后臺(tái)進(jìn)程使用的流量進(jìn)行了區(qū)分合是。大多數(shù)應(yīng)用程序都不需要設(shè)置這個(gè)

"allowsCellularAccess(允許蜂窩訪問(wèn))"和"discretionary(自行決定)"被用于節(jié)省通過(guò)蜂窩連接的帶寬了罪。建議在使用后臺(tái)傳輸?shù)臅r(shí)候,使用discretionary屬性聪全,而不是allowsCellularAccess屬性泊藕,因?yàn)樗鼤?huì)把WiFi和電源可用性考慮在內(nèi)

"timeoutIntervalForRequest"和"timeoutIntervalForResource"指定了請(qǐng)求以及該資源的超時(shí)時(shí)間間隔。許多開(kāi)發(fā)人員試圖使用timeoutInterval去限制發(fā)送請(qǐng)求的總時(shí)間难礼,但這誤會(huì)了timeoutInterval的意思:報(bào)文之間的時(shí)間娃圆。timeoutIntervalForResource實(shí)際上提供了整體超時(shí)的特性,這應(yīng)該只用于后臺(tái)傳輸蛾茉,而不是用戶實(shí)際上可能想要等待的任何東西

"HTTPMaximumConnectionsPerHost"是 Foundation 框架中URL加載系統(tǒng)的一個(gè)新的配置選項(xiàng)讼呢。它曾經(jīng)被用于NSURLConnection管理私人連接池。現(xiàn)在有了NSURLSession臀稚,開(kāi)發(fā)者可以在需要時(shí)限制連接到特定主機(jī)的數(shù)量

"HTTPShouldUsePipelining"也出現(xiàn)在NSMutableURLRequest吝岭,它可以被用于開(kāi)啟HTTP管道,這可以顯著降低請(qǐng)求的加載時(shí)間吧寺,但是由于沒(méi)有被服務(wù)器廣泛支持窜管,默認(rèn)是禁用的

"sessionSendsLaunchEvents" 是另一個(gè)新的屬性,該屬性指定該會(huì)話是否應(yīng)該從后臺(tái)啟動(dòng)

"connectionProxyDictionary"指定了會(huì)話連接中的代理服務(wù)器稚机。同樣地幕帆,大多數(shù)面向消費(fèi)者的應(yīng)用程序都不需要代理,所以基本上不需要配置這個(gè)屬性
關(guān)于連接代理的更多信息可以在 CFProxySupport Reference 找到赖条。

"Cookie Policies"
-"HTTPCookieStorage" 是被會(huì)話使用的cookie存儲(chǔ)失乾。默認(rèn)情況下常熙,NSHTTPCookieShorage的 + sharedHTTPCookieStorage會(huì)被使用,這與NSURLConnection是相同的
-"HTTPCookieAcceptPolicy" 決定了該會(huì)話應(yīng)該接受從服務(wù)器發(fā)出的cookie的條件
-"HTTPShouldSetCookies" 指定了請(qǐng)求是否應(yīng)該使用會(huì)話HTTPCookieStorage的cookie

"Security Policies"
  URLCredentialStorage 是會(huì)話使用的證書(shū)存儲(chǔ)碱茁。默認(rèn)情況下裸卫,NSURLCredentialStorage 的+ sharedCredentialStorage 會(huì)被使用使用,這與NSURLConnection是相同的

"TLSMaximumSupportedProtocol" 和 "TLSMinimumSupportedProtocol" 確定是否支持SSLProtocol版本的會(huì)話

"Caching Policies"
URLCache 是會(huì)話使用的緩存纽竣。默認(rèn)情況下墓贿,NSURLCache 的 + sharedURLCache 會(huì)被使用,這與NSURLConnection是相同的
requestCachePolicy 指定了一個(gè)請(qǐng)求的緩存響應(yīng)應(yīng)該在什么時(shí)候返回蜓氨。這相當(dāng)于NSURLRequest 的-cachePolicy方法

"Custom Protocols"
protocolClasses是注冊(cè)NSURLProtocol類的特定會(huì)話數(shù)組
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末聋袋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子穴吹,更是在濱河造成了極大的恐慌幽勒,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件港令,死亡現(xiàn)場(chǎng)離奇詭異啥容,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)缠借,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)干毅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人泼返,你說(shuō)我怎么就攤上這事硝逢。” “怎么了绅喉?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵渠鸽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我柴罐,道長(zhǎng)徽缚,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任革屠,我火速辦了婚禮凿试,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘似芝。我一直安慰自己那婉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布党瓮。 她就那樣靜靜地躺著详炬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪寞奸。 梳的紋絲不亂的頭發(fā)上呛谜,一...
    開(kāi)封第一講書(shū)人閱讀 51,488評(píng)論 1 302
  • 那天在跳,我揣著相機(jī)與錄音,去河邊找鬼隐岛。 笑死猫妙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的礼仗。 我是一名探鬼主播吐咳,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼元践!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起童谒,我...
    開(kāi)封第一講書(shū)人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤单旁,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后饥伊,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體象浑,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年琅豆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了愉豺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡茫因,死狀恐怖蚪拦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情冻押,我是刑警寧澤驰贷,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站洛巢,受9級(jí)特大地震影響括袒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜稿茉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一锹锰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧漓库,春花似錦恃慧、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蘸嘶,卻和暖如春良瞧,著一層夾襖步出監(jiān)牢的瞬間陪汽,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工褥蚯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挚冤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓赞庶,卻偏偏與公主長(zhǎng)得像训挡,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子歧强,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • iOS開(kāi)發(fā)系列--網(wǎng)絡(luò)開(kāi)發(fā) 概覽 大部分應(yīng)用程序都或多或少會(huì)牽扯到網(wǎng)絡(luò)開(kāi)發(fā)澜薄,例如說(shuō)新浪微博、微信等摊册,這些應(yīng)用本身可...
    lichengjin閱讀 3,661評(píng)論 2 7
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理肤京,服務(wù)發(fā)現(xiàn),斷路器茅特,智...
    卡卡羅2017閱讀 134,656評(píng)論 18 139
  • NSURLSession 使用步驟使用NSURLSession對(duì)象創(chuàng)建Task忘分,然后執(zhí)行Task -(void)g...
    BEYOND黃閱讀 904評(píng)論 0 0
  • 使用NSURLConnection實(shí)現(xiàn)下載 1. 小文件下載 第一種方式(NSData) 第二種方式(NSURLC...
    擱淺的青蛙閱讀 1,954評(píng)論 3 10
  • NSURLSession基本使用 簡(jiǎn)介 使用步驟使用NSURLSession會(huì)話對(duì)象創(chuàng)建Task,然后執(zhí)行Task...
    彼岸的黑色曼陀羅閱讀 995評(píng)論 0 3