iOS-原生網(wǎng)絡(luò)請求(詳細說明)

技 術(shù) 文 章 / 超 人


GET,POST基本帶參數(shù)網(wǎng)絡(luò)請求

   //請求地址
    NSURL *url = [NSURL URLWithString:URLString];
    
    //設(shè)置請求地址
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    //設(shè)置請求方式
    request.HTTPMethod = @"POST";
    
    //設(shè)置請求參數(shù)
    request.HTTPBody = [parameters dataUsingEncoding:NSUTF8StringEncoding];
  //關(guān)于parameters是NSDictionary拼接后的NSString.關(guān)于拼接看后面拼接方法說明
    
    
    //設(shè)置請求session
    NSURLSession *session = [NSURLSession sharedSession];
    
    //設(shè)置網(wǎng)絡(luò)請求的返回接收器
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (error) {
                if (failure) {
                    failure(error);
                }
            }else
            {
                NSError *error;
                NSMutableDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
                if (error) {
                    if (failure) {
                        failure(error);
                    }
                }else
                {
                    if (success) {
                        success(responseObject);
                    }
                }
            } 
        });
    }];
//開始請求
    [dataTask resume];

拼接parameters 參數(shù)

/**
 拼接字典數(shù)據(jù)

 @param parameters 參數(shù)
 @return 拼接后的字符串
 */
-(NSString *)parameters:(NSDictionary *)parameters
{
    //創(chuàng)建可變字符串來承載拼接后的參數(shù)
    NSMutableString *parameterString = [NSMutableString new];
    //獲取parameters中所有的key
    NSArray *parameterArray = parameters.allKeys;
    for (int i = 0;i < parameterArray.count;i++) {
    //根據(jù)key取出所有的value
        id value = parameters[parameterArray[i]];
    //把parameters的key 和 value進行拼接
        NSString *keyValue = [NSString stringWithFormat:@"%@=%@",parameterArray[i],value];
        if (i == parameterArray.count || i == 0) {
        //如果當(dāng)前參數(shù)是最后或者第一個參數(shù)就直接拼接到字符串后面,因為第一個參數(shù)和最后一個參數(shù)不需要加 “&”符號來標識拼接的參數(shù)
            [parameterString appendString:keyValue];
        }else
        {
        //拼接參數(shù)修赞, &表示與前面的參數(shù)拼接
            [parameterString appendString:[NSString stringWithFormat:@"&%@",keyValue]];
        }
    }
    return parameterString;
}

上傳文件原生請求

NSURLRequestCachePolicy 緩存枚舉說明

//指定緩存邏輯婶恼。URL加載系統(tǒng)提供了一個磁盤和內(nèi)存混合的緩存,來相應(yīng)網(wǎng)絡(luò)請求柏副。這個緩存允許一個應(yīng)用減少對網(wǎng)絡(luò)連接的依賴勾邦,并且增加性能。使用緩存的目的是為了使用的應(yīng)用程序能更快速的響應(yīng)用戶輸入割择,是程序高效的運行眷篇。有時候我們需要將遠程web服務(wù)器獲取的數(shù)據(jù)緩存起來,減少對同一個url多次請求荔泳。
typedef NS_ENUM(NSUInteger, NSURLRequestCachePolicy)
{
    NSURLRequestUseProtocolCachePolicy = 0,//默認緩存策略铅歼。具體工作:如果一個NSCachedURLResponse對于請求并不存在,數(shù)據(jù)將會從源端獲取换可。如果請求擁有一個緩存的響應(yīng)椎椰,那么URL加載系統(tǒng)會檢查這個響應(yīng)來決定,如果它指定內(nèi)容必須重新生效的話沾鳄。假如內(nèi)容必須重新生效慨飘,將建立一個連向源端的連接來查看內(nèi)容是否發(fā)生變化。假如內(nèi)容沒有變化译荞,那么響應(yīng)就從本地緩存返回數(shù)據(jù)瓤的。如果內(nèi)容變化了,那么數(shù)據(jù)將從源端獲取

    NSURLRequestReloadIgnoringLocalCacheData = 1,// URL應(yīng)該加載源端數(shù)據(jù)吞歼,不使用本地緩存數(shù)據(jù)

    NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // 本地緩存數(shù)據(jù)圈膏、代理和其他中介都要忽視他們的緩存,直接加載源數(shù)據(jù)

    NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,//兩個的設(shè)置相同

    NSURLRequestReturnCacheDataElseLoad = 2,//使用緩存數(shù)據(jù)篙骡,忽略其過期時間稽坤;只有在沒有緩存版本的時候才從源端加載數(shù)據(jù)。
    NSURLRequestReturnCacheDataDontLoad = 3,//只使用cache數(shù)據(jù)糯俗,如果不存在cache尿褪,請求失敗得湘;用于沒有建立網(wǎng)絡(luò)連接離線模式

    NSURLRequestReloadRevalidatingCacheData = 5, //指定如果已存的緩存數(shù)據(jù)被提供它的源段確認為有效則允許使用緩存數(shù)據(jù)響應(yīng)請求杖玲,否則從源段加載數(shù)據(jù)。
};
//只有響應(yīng)http和https的請求會被緩存淘正。ftp和文件協(xié)議當(dāng)被緩存策略允許的時候嘗試接入源段摆马。自定義的NSURLProtocol類能夠保護緩存臼闻,如果它們被選擇使用的話。

mimeType 文件類型

image.png

上傳文件請求

//指定NSMutableURLRequest的 url請求地址囤采、緩存機制述呐、超時時長
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URLString]
                                                           cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                                       timeoutInterval: self.timeoutInterval];

    //指定加載進度的回調(diào)
    self.progressBlock = upProgress;
    
    /*
      multipart/from-data 編碼類型,以提高二進制文件的傳輸效率斑唬。是一種進行表單提交時的消息格式市埋。表單提交數(shù)據(jù)的時候,默認類型是application/x-www-form-urlencoded恕刘,也就是key=value的鍵值對格式缤谎,提交文件的時候使用multipart/from-data。因為是表單提交褐着,所以http請求方式是POST坷澡。然后在請求頭里設(shè)置Content-Type為multipart/from-data指定請求的格式
      charset=utf-8 編碼格式
      boundary 分隔符,分隔多個文件含蓉、表單項频敛。確保整個分隔符不會在文件或表單項的內(nèi)容中出現(xiàn)。
    */
    //設(shè)置HTTPHeader中Content-Type的值
    [request setValue:[[NSString alloc] initWithFormat:@"multipart/form-data; charset=utf-8; boundary=%@",self.boundary] forHTTPHeaderField:@"Content-Type"];

    //請求方式
    request.HTTPMethod = @"POST";
    
    /*
     parameters 請求參數(shù)
     fileData 上傳的文件 NSData類型
     name 文件名馅扣,一般隨意取或與服務(wù)器協(xié)商
     fileName 文件加后綴名斟赚,例如傳圖片  就取  test.jpg 一般隨意取或與服務(wù)器協(xié)商
      mimeType 文件類型
    */
   //該方法拼接上傳文件的 Data數(shù)據(jù)
    NSData * payloadData = [self setBodydataWithParameters:parameters fileData:fileData name:name fileName:fileName mimeType:mimeType];

    /* 1、defaultSessionConfiguration"返回標準配置差油,這實際上與NSURLConnection的網(wǎng)絡(luò)協(xié)議棧是一樣的拗军,具有相同的共享NSHTTPCookieStorage,共享NSURLCache和共享NSURLCredentialStorage蓄喇。
  2发侵、 "ephemeralSessionConfiguration"返回一個預(yù)設(shè)配置,沒有持久性存儲的緩存妆偏,Cookie或證書刃鳄。這對于實現(xiàn)像"秘密瀏覽"功能的功能來說,是很理想的钱骂。
  3叔锐、 "backgroundSessionConfiguration":獨特之處在于,它會創(chuàng)建一個后臺會話罐柳。后臺會話不同于常規(guī)的掌腰,普通的會話,它甚至可以在應(yīng)用程序掛起张吉,退出,崩潰的情況下運行上傳和下載任務(wù)催植。初始化時指定的標識符肮蛹,被用于向任何可能在進程外恢復(fù)后臺傳輸?shù)氖刈o進程提供上下文勺择。
    * /
    //NSURLSessionConfiguration對象用于初始化NSURLSession對象
    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];

    //如果要使用代理方法,需要設(shè)置代理,但從NSURLSession的頭文件發(fā)現(xiàn)session的delegate屬性是只讀的.因此設(shè)置代理要通過session的初始化方法賦,delegateQueue參數(shù)表示協(xié)議方法將會在哪個隊列(NSOperationQueue)里面執(zhí)行.
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
    
    
    
    NSURLSessionUploadTask * uploadtask = [session uploadTaskWithRequest:request fromData:payloadData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (!error) {
                NSError *jserror = nil;
                NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jserror];
                if (jserror) {
                    if (failure){
                        failure(jserror);
                    }
                }else if (success) {
                    success(dic);
                }
            }else if (failure){
                failure(error);
            }
        });
        
    }];
    //開始請求
    [uploadtask resume];

上傳文件Data拼接方法

/**
 文件Data拼接

 @param parameter 上傳參數(shù)
 @param data 文件源
 @param name 文件名
 @param fileName 文件加后綴的具體名稱
 @param mimeType 文件類型
 @return 拼接后的Data
 */
- (NSData *)setBodydataWithParameters:(NSDictionary *)parameter
                             fileData:(NSData *)data
                                 name:(NSString *)name
                             fileName:(NSString *)fileName
                             mimeType:(NSString *)mimeType
{
    
    NSData * imageData = data;
    //1.構(gòu)造body string
    NSMutableString *bodyString = [[NSMutableString alloc] init];
    
    //2.拼接body string
    NSMutableData *bodyData = [NSMutableData data];
    [parameter enumerateKeysAndObjectsUsingBlock:^(NSString *  _Nonnull key, NSString *  _Nonnull obj, BOOL * _Nonnull stop) {
        [bodyString appendFormat:@"--%@\r\n", self.boundary];
        [bodyString appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
        [bodyString appendFormat:@"%@\r\n",obj];
    }];
    
    [bodyString appendFormat:@"--%@\r\n", self.boundary];
    [bodyString appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n",name,fileName];
    [bodyString appendFormat:@"Content-Type: %@\r\n\r\n",mimeType];
    
    //拼接的過程
    //前面的bodyString, 其他參數(shù)
    [bodyData appendData:[bodyString dataUsingEncoding:NSUTF8StringEncoding]];
    //圖片數(shù)據(jù)
    [bodyData appendData:imageData];
    
    //4.結(jié)束的分隔線
    NSString *endStr = [NSString stringWithFormat:@"\r\n--%@--\r\n",self.boundary];
    //拼接到bodyData最后面
    [bodyData appendData:[endStr dataUsingEncoding:NSUTF8StringEncoding]];
    
    return bodyData;
}

關(guān)于NSURLSessionDelegate

上傳進度獲取

/*
 調(diào)用該方法上傳文件數(shù)據(jù)
 如果文件數(shù)據(jù)很大伦忠,那么該方法會被調(diào)用多次
 參數(shù)說明:
     totalBytesSent:已經(jīng)上傳的文件數(shù)據(jù)的大小
     totalBytesExpectedToSend:文件的總大小
 */
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend{
    
    self.uploadProgress.totalUnitCount = totalBytesExpectedToSend;
    self.uploadProgress.completedUnitCount = totalBytesSent;
    //這里的progressBlock省核、uploadProgress都是自己定義的回調(diào)。上面上傳文件中也有設(shè)置
    self.progressBlock(self.uploadProgress) ;
}

參考資料:
1.NSURLSession使用說明及后臺工作流程分析
2.iOS開發(fā)之網(wǎng)絡(luò)編程--6昆码、NSURLSessionConfiguration筆記
3.使用NSURLSession

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末气忠,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子赋咽,更是在濱河造成了極大的恐慌旧噪,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脓匿,死亡現(xiàn)場離奇詭異淘钟,居然都是意外死亡,警方通過查閱死者的電腦和手機陪毡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門米母,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人毡琉,你說我怎么就攤上這事铁瞒。” “怎么了桅滋?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵慧耍,是天一觀的道長。 經(jīng)常有香客問我虱歪,道長蜂绎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任笋鄙,我火速辦了婚禮师枣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘萧落。我一直安慰自己践美,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布找岖。 她就那樣靜靜地躺著陨倡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪许布。 梳的紋絲不亂的頭發(fā)上兴革,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音,去河邊找鬼杂曲。 笑死庶艾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的擎勘。 我是一名探鬼主播咱揍,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼棚饵!你這毒婦竟也來了煤裙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤噪漾,失蹤者是張志新(化名)和其女友劉穎硼砰,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怪与,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡夺刑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了分别。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片遍愿。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖耘斩,靈堂內(nèi)的尸體忽然破棺而出沼填,到底是詐尸還是另有隱情,我是刑警寧澤括授,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布坞笙,位于F島的核電站,受9級特大地震影響荚虚,放射性物質(zhì)發(fā)生泄漏薛夜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一版述、第九天 我趴在偏房一處隱蔽的房頂上張望梯澜。 院中可真熱鬧,春花似錦渴析、人聲如沸晚伙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咆疗。三九已至,卻和暖如春母债,著一層夾襖步出監(jiān)牢的瞬間午磁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留漓踢,地道東北人牵署。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓漏隐,卻偏偏與公主長得像喧半,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子青责,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

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