HTTP協(xié)議POST、GET
訪問網(wǎng)絡(luò)數(shù)據(jù)大部分都要用到HTTP協(xié)議,通過HTTP協(xié)議向服務(wù)器請求數(shù)據(jù),再通過HTTP協(xié)議獲得服務(wù)器的響應(yīng)數(shù)據(jù),常見的操作主要是POST與GET,這兩個操作可以滿足絕大部分的應(yīng)用需求了。
GET操作主要使用場景是請求網(wǎng)絡(luò)資源,例如在瀏覽器中訪問網(wǎng)頁就發(fā)起了很多GET請求,GET請求的缺點在于安全性不夠,參數(shù)都在URL中了,并且不同的瀏覽器對URL長度有不同長度的限制,一些復(fù)雜的請求就不適用了。這時候需要用POST請求,POST請求的所有參數(shù)都放在請求體中,安全性更好,并且理論上沒有數(shù)據(jù)量的限制,文件上傳、賬號登陸等都用POST請求。 一般GET請求只適合于簡單的查詢請求,增刪改一般都用POST請求。
簡單的網(wǎng)絡(luò)請求 dataWithContentsOfURL
NSURL *url = [NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1634654-d8b4a14ae77aa685.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSURLConnection 基本使用
同步請求
// 1.設(shè)置請求路徑
NSURL *url=[NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1634654-d8b4a14ae77aa685.jpg"];
// 2.創(chuàng)建請求對象 **(任何NSURLRequest默認都是GET請求)**
NSURLRequest *request=[NSURLRequest requestWithURL:url];
// 3.發(fā)送請求
// 發(fā)送同步請求,在主線程執(zhí)行
NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
//(一直在等待服務(wù)器返回數(shù)據(jù),這行代碼會卡住,如果服務(wù)器沒有返回數(shù)據(jù),那么在主線程UI會卡住不能繼續(xù)執(zhí)行操作)
異步請求
發(fā)送異步請求有兩種方式:使用block回調(diào)和代理
首先確定請求路徑,然后創(chuàng)建請求對象(默認發(fā)送的時GET請求),使用異步方法(一調(diào)用這個方法,它會自動開啟一個子線程去發(fā)送請求,當(dāng)請求成功,數(shù)據(jù)返回的時候自動調(diào)用內(nèi)部的代碼段,這個代碼段在那個線程執(zhí)行取決于隊列,如果是主隊列,那么在子線程發(fā)送請求成功拿到服務(wù)器的數(shù)據(jù)后,回到主線程中解析數(shù)據(jù),刷新UI界面)
// 1.設(shè)置請求路徑
NSURL *url=[NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1634654-d8b4a14ae77aa685.jpg"];
// 2.創(chuàng)建請求對象 **(任何NSURLRequest默認都是GET請求)**
NSURLRequest *request=[NSURLRequest requestWithURL:url];
// 3.獲取一個主隊列
NSOperationQueue *queue=[NSOperationQueue mainQueue];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
//當(dāng)請求結(jié)束的時候調(diào)用(有兩種結(jié)果,一個是成功拿到數(shù)據(jù),也可能沒有拿到數(shù)據(jù),請求失?。? if (data) {//請求成功
NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSLog(@"%@",dict);
}else { //請求失敗
NSLog(@"請求失敗");
}
}];
使用代理發(fā)送異步請求
要監(jiān)聽服務(wù)器返回的data,所以使用 <NSURLConnectionDataDelegate> 協(xié)議
//當(dāng)接收到服務(wù)器的響應(yīng)(連通了服務(wù)器)時會調(diào)用
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
//當(dāng)接收到服務(wù)器的數(shù)據(jù)時會調(diào)用(可能會被調(diào)用多次,每次只傳遞部分數(shù)據(jù))
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
//當(dāng)服務(wù)器的數(shù)據(jù)加載完畢時就會調(diào)用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
//請求錯誤(失敗)的時候調(diào)用(請求超時\斷網(wǎng)\沒有網(wǎng)\,一般指客戶端錯誤)
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
發(fā)送請求
NSMutableURLRequest 是 NSURLRequest 的子類,常用方法有
設(shè)置請求超時等待時間(超過這個時間就算超時,請求失?。? (void)setTimeoutInterval:(NSTimeInterval)seconds;
設(shè)置請求方法(比如GET和POST)- (void)setHTTPMethod:(NSString *)method;
設(shè)置請求體 - (void)setHTTPBody:(NSData *)data;
設(shè)置請求頭 - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;
// 1.設(shè)置請求路徑
NSURL *url=[NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1634654-d8b4a14ae77aa685.jpg"];
// 2.創(chuàng)建請求對象 **(任何NSURLRequest默認都是GET請求)**
NSMutableURLRequest *request=[NSURLRequest requestWithURL:url];
// 設(shè)置請求超時
request.timeoutInterval=5.0;
// .3.發(fā)送請求
//使用代理發(fā)送異步請求(通常應(yīng)用于文件下載)
NSURLConnection *conn=[NSURLConnection connectionWithRequest:request delegate:self];
[conn start];
NSURLSession
NSURLConnection,在iOS 9被宣布棄用,取而代之是NSURLSession的崛起
//**GET請求**
// 1.設(shè)置請求路徑
NSURL *url=[NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1634654-d8b4a14ae77aa685.jpg"];
// 2.創(chuàng)建請求對象 **(任何NSURLRequest默認都是GET請求)**
NSURLRequest *request=[NSURLRequest requestWithURL:url];
// 3.獲取會話的對象
NSURLSession *session = [NSURLSession sharedSession];
// 4.根據(jù)會話對象,創(chuàng)建一個Task任務(wù)
NSURLSessionDataTask *sessionDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//對從服務(wù)器獲取到的數(shù)據(jù)data進行相應(yīng)的處理
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableLeaves) error:nil];
}];
// 5.執(zhí)行任務(wù)
[sessionDataTask resume];
//**POST請求**,POST和GET的區(qū)別就在于request,所以使用session的POST請求和GET過程是一樣的,區(qū)別就在于對request的處理
// 1.設(shè)置請求路徑
NSURL *url=[NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1634654-d8b4a14ae77aa685.jpg"];
// 2.創(chuàng)建請求對象,設(shè)置請求方法、請求參數(shù)
NSURLRequest *request=[NSURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=xx&pwd=xx" dataUsingEncoding:NSUTF8StringEncoding];
// 3.獲取會話的對象
NSURLSession *session = [NSURLSession sharedSession];
// 4.根據(jù)會話對象,創(chuàng)建一個Task任務(wù)
NSURLSessionDataTask *sessionDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//對從服務(wù)器獲取到的數(shù)據(jù)data進行相應(yīng)的處理
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableLeaves) error:nil];
}];
// 5.執(zhí)行任務(wù)
[sessionDataTask resume];
NSURLSessionDataDelegate代理方法
NSURLSession提供了block方式處理返回數(shù)據(jù)的簡便方式,但如果想要在接收數(shù)據(jù)過程中做進一步的處理,仍然可以調(diào)用相關(guān)的協(xié)議方法.NSURLSession的代理方法和NSURLConnection有些類似,都是分為接收響應(yīng)、接收數(shù)據(jù)、請求完成幾個階段
// 使用代理方法需要設(shè)置代理,但是session的delegate屬性是只讀的,要想設(shè)置代理只能通過這種方式創(chuàng)建session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
// 創(chuàng)建任務(wù)(因為要使用代理方法,就不需要block方式的初始化了)
NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.daka.com/login?userName=daka&pwd=123"]]];
// 啟動任務(wù)
[task resume];
// 1.接收到服務(wù)器的響應(yīng)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
// 允許處理服務(wù)器的響應(yīng),才會繼續(xù)接收服務(wù)器返回的數(shù)據(jù)
completionHandler(NSURLSessionResponseAllow);
}
// 2.接收到服務(wù)器的數(shù)據(jù)(可能調(diào)用多次)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
// 處理每次接收的數(shù)據(jù)
}
// 3.請求成功或者失敗(如果失敗,error有值)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
// 請求完成,成功或者失敗的處理
}