iOS開發網絡篇—NSURLConnection基本使用

iOS開發網絡篇—NSURLConnection基本使用

一、NSURLConnection的常用類

(1)NSURL:請求地址

(2)NSURLRequest:封裝一個請求,保存發給服務器的全部數據,包括一個NSURL對象,請求方法、請求頭、請求體....

(3)NSMutableURLRequest:NSURLRequest的子類

(4)NSURLConnection:負責發送請求,建立客戶端和服務器的連接。發送NSURLRequest的數據給服務器,并收集來自服務器的響應數據

?

二、NSURLConnection的使用
1.簡單說明

使用NSURLConnection發送請求的步驟很簡單

(1)創建一個NSURL對象,設置請求路徑(設置請求路徑)

(2)傳入NSURL創建一個NSURLRequest對象,設置請求頭和請求體(創建請求對象)

(3)使用NSURLConnection發送NSURLRequest(發送請求)

2.代碼示例

(1)發送請求的三個步驟:

1.設置請求路徑
2.創建請求對象
3.發送請求
3.1發送同步請求(一直在等待服務器返回數據,這行代碼會卡住,如果服務器,沒有返回數據,那么在主線程UI會卡住不能繼續執行操作)有返回值
3.2發送異步請求:沒有返回值
說明:任何NSURLRequest默認都是get請求。
(2)發送同步請求代碼示例:
//
//  YYViewController.m
//  01-NSURLConnection的使用(GET)
//
//  Created by apple on 14-6-28.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"
#import "MBProgressHUD+MJ.h"@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UITextField *username;
@property (weak, nonatomic) IBOutlet UITextField *pwd;
- (IBAction)login;@end@implementation YYViewController- (IBAction)login {
//    1.提前的表單驗證if (self.username.text.length==0) {[MBProgressHUD showError:@"請輸入用戶名"];return;}if (self.pwd.text.length==0) {[MBProgressHUD showError:@"請輸入密碼"];return;}
//    2.發送請求給服務器(帶上賬號和密碼)//添加一個遮罩,禁止用戶操作
//    [MBProgressHUD showMessage:@"正在努力加載中...."];
//    GET請求:請求行\請求頭\請求體
//
//    1.設置請求路徑NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];NSURL *url=[NSURL URLWithString:urlStr];
//    2.創建請求對象NSURLRequest *request=[NSURLRequest requestWithURL:url];
//    3.發送請求//發送同步請求,在主線程執行NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];//(一直在等待服務器返回數據,這行代碼會卡住,如果服務器沒有返回數據,那么在主線程UI會卡住不能繼續執行操作)NSLog(@"--%d--",data.length);
}
@end

模擬器情況:

?

打印服務器返回的信息:

?

補充說明:
1.提前的表單驗證
2.發送請求給服務器(帶上賬號和密碼)
GET請求:請求行\請求頭\請求體
注意:GET請求中不存在請求體,因為所有的信息都寫在URL里面。在IOS里面,請求行和請求頭都不用寫。
(3)發送異步請求
發送異步請求有兩種方式:
1)使用block回調
2)代理
A.使用block回調方法發送異步請求
使用block回調代碼示例:
//
//  YYViewController.m
//  01-NSURLConnection的使用(GET)
//
//  Created by apple on 14-6-28.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"
#import "MBProgressHUD+MJ.h"@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UITextField *username;
@property (weak, nonatomic) IBOutlet UITextField *pwd;
- (IBAction)login;@end@implementation YYViewController- (IBAction)login {
//    1.提前的表單驗證if (self.username.text.length==0) {[MBProgressHUD showError:@"請輸入用戶名"];return;}if (self.pwd.text.length==0) {[MBProgressHUD showError:@"請輸入密碼"];return;}
//    2.發送請求給服務器(帶上賬號和密碼)//添加一個遮罩,禁止用戶操作[MBProgressHUD showMessage:@"正在努力加載中...."];//
//    1.設置請求路徑NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];NSURL *url=[NSURL URLWithString:urlStr];//    2.創建請求對象NSURLRequest *request=[NSURLRequest requestWithURL:url];//    3.發送請求//3.1發送同步請求,在主線程執行
//    NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];//(一直在等待服務器返回數據,這行代碼會卡住,如果服務器沒有返回數據,那么在主線程UI會卡住不能繼續執行操作)//3.1發送異步請求//創建一個隊列(默認添加到該隊列中的任務異步執行)
//    NSOperationQueue *queue=[[NSOperationQueue alloc]init];//獲取一個主隊列NSOperationQueue *queue=[NSOperationQueue mainQueue];[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {NSLog(@"--block回調數據--%@---%d", [NSThread currentThread],data.length);//隱藏HUD,刷新UI的操作一定要放在主線程執行
        [MBProgressHUD hideHUD];//解析data/*{"success":"登錄成功"}{"error":"用戶名不存在"}{"error":"密碼不正確"}*/NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];NSLog(@"%@",dict);//判斷后,在界面提示登錄信息NSString *error=dict[@"error"];if (error) {[MBProgressHUD showError:error];}else{NSString *success=dict[@"success"];[MBProgressHUD showSuccess:success];}}];NSLog(@"請求發送完畢");
}
@end

模擬器情況(注意這里使用了第三方框架):

?

打印查看:

?

代碼說明:
block代碼段:當服務器有返回數據的時候調用會開一條新的線程去發送請求,主線程繼續往下走,當拿到服務器的返回數據的數據的時候再回調block,執行block代碼段。這種情況不會卡住主線程。
隊列的作用:決定這個block操作放在哪個線程執行?
刷新UI界面的操作應該放在主線程執行,不能放在子線程,在子線程處理UI相關操作會出現一些莫名的問題。
提示:
(1)創建一個操作,放在NSOperation隊列中執行,默認是異步執行的。
(2)mainqueue ? 返回一個和主線程相關的隊列,即主隊列。
新的問題:如果向服務器發送請求,卻并沒有拿到數據,那么程序會崩潰(data不能為空)
改進代碼:
NSOperationQueue *queue=[NSOperationQueue mainQueue];[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {//當請求結束的時候調用(有兩種結果,一個是成功拿到數據,也可能沒有拿到數據,請求失敗)NSLog(@"--block回調數據--%@---%d", [NSThread currentThread],data.length);//隱藏HUD,刷新UI的操作一定要放在主線程執行
        [MBProgressHUD hideHUD];//解析data/*{"success":"登錄成功"}{"error":"用戶名不存在"}{"error":"密碼不正確"}*/if (data) {//請求成功NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];NSLog(@"%@",dict);//判斷后,在界面提示登錄信息NSString *error=dict[@"error"];if (error) {[MBProgressHUD showError:error];}else{NSString *success=dict[@"success"];[MBProgressHUD showSuccess:success];}}else   //請求失敗
        {[MBProgressHUD showError:@"網絡繁忙,請稍后重試!"];}}];

解析data

//解析data/*{"success":"登錄成功"}{"error":"用戶名不存在"}{"error":"密碼不正確"}*/
說明:使用NSJSONSerialization 返回的對象,取決于最外層是什么,如果是{}那就是字典,[]那就是數組等。
補充說明:
首先確定請求路徑,然后創建請求對象(默認發送的時get請求),使用異步方法(一調用這個方法,它會自動開啟一個子線程去發送請求,當請求成功,數據返回的時候自動調用內部的代碼段,這個代碼段在那個線程執行取決于隊列,如果是主隊列,那么在子線程發送請求成功拿到服務器的數據后,回到主線程中解析數據,刷新UI界面)。
B.使用代理方法發送異步請求

要監聽服務器返回的data,所以使用<NSURLConnectionDataDelegate>協議

常見大代理方法如下:

#pragma mark- NSURLConnectionDataDelegate代理方法//當接收到服務器的響應(連通了服務器)時會調用-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response//當接收到服務器的數據時會調用(可能會被調用多次,每次只傳遞部分數據)-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data//當服務器的數據加載完畢時就會調用-(void)connectionDidFinishLoading:(NSURLConnection *)connection//請求錯誤(失敗)的時候調用(請求超時\斷網\沒有網\,一般指客戶端錯誤)-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

使用異步方法發送get請求的代碼示例:

?

//
//  YYViewController.m
//  01-NSURLConnection的使用(GET)
//
//  Created by apple on 14-6-28.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"
#import "MBProgressHUD+MJ.h"@interface YYViewController ()<NSURLConnectionDataDelegate>
@property (weak, nonatomic) IBOutlet UITextField *username;
@property (weak, nonatomic) IBOutlet UITextField *pwd;
@property(nonatomic,strong)NSMutableData *responseData;
- (IBAction)login;@end@implementation YYViewController- (IBAction)login {
//    1.提前的表單驗證if (self.username.text.length==0) {[MBProgressHUD showError:@"請輸入用戶名"];return;}if (self.pwd.text.length==0) {[MBProgressHUD showError:@"請輸入密碼"];return;}
//    2.發送請求給服務器(帶上賬號和密碼)//添加一個遮罩,禁止用戶操作[MBProgressHUD showMessage:@"正在努力加載中...."];//
//   2.1設置請求路徑NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];NSURL *url=[NSURL URLWithString:urlStr];//   2.2創建請求對象
//    NSURLRequest *request=[NSURLRequest requestWithURL:url];//默認就是GET請求//設置請求超時NSMutableURLRequest *request=[NSMutableURLRequest  requestWithURL:url];request.timeoutInterval=5.0;//   2.3.發送請求//使用代理發送異步請求(通常應用于文件下載)NSURLConnection *conn=[NSURLConnection connectionWithRequest:request delegate:self];[conn start];NSLog(@"已經發出請求---");
}#pragma mark- NSURLConnectionDataDelegate代理方法
/**當接收到服務器的響應(連通了服務器)時會調用*/
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{NSLog(@"接收到服務器的響應");//初始化數據self.responseData=[NSMutableData data];
}/*
*當接收到服務器的數據時會調用(可能會被調用多次,每次只傳遞部分數據)
*/
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{NSLog(@"接收到服務器的數據");//拼接數據
    [self.responseData appendData:data];NSLog(@"%d---%@--",self.responseData.length,[NSThread currentThread]);
}/**當服務器的數據加載完畢時就會調用*/
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{NSLog(@"服務器的數據加載完畢");//隱藏HUD
    [MBProgressHUD hideHUD];//處理服務器返回的所有數據NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves error:nil];//判斷后,在界面提示登錄信息NSString *error=dict[@"error"];if (error) {[MBProgressHUD showError:error];}else{NSString *success=dict[@"success"];[MBProgressHUD showSuccess:success];}NSLog(@"%d---%@--",self.responseData.length,[NSThread currentThread]);
}
/**請求錯誤(失敗)的時候調用(請求超時\斷網\沒有網\,一般指客戶端錯誤)*/
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
//     NSLog(@"請求錯誤");//隱藏HUD
    [MBProgressHUD hideHUD];[MBProgressHUD showError:@"網絡繁忙,請稍后重試!"];
}
@end

?

打印查看:?

?

補充:

(1)數據的處理

在didReceiveData:方法中,拼接接收到的所有數據,等所有數據都拿到后,在connectionDidFinishLoading:方法中進行處理

(2)網絡延遲

在做網絡開發的時候,一定要考慮到網絡延遲情況的處理,可以在服務器的代碼設置一個斷點模擬。

在服務器代碼的登錄方法中設置斷點

?

設置請求的最大延遲

?

模擬器情況:

?

打印查看:

?

三、NSMutableURLRequest

NSMutableURLRequest是NSURLRequest的子類,常用方法有

設置請求超時等待時間(超過這個時間就算超時,請求失敗)- (void)setTimeoutInterval:(NSTimeInterval)seconds;

設置請求方法(比如GET和POST)- (void)setHTTPMethod:(NSString *)method;

設置請求體- (void)setHTTPBody:(NSData *)data;

設置請求頭- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;

轉載于:https://www.cnblogs.com/yipingios/p/5562394.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/257042.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/257042.shtml
英文地址,請注明出處:http://en.pswp.cn/news/257042.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何查看mysql連接相關參數

1.查看當前所有連接的詳細資料: mysqladmin -u root -ppassword processlist 這里password為數據庫用戶root的密碼 2.只查看當前連接數(Threads就是連接數.): mysqladmin -u root -ppassword status 這里password為數據庫用戶root的密碼 3.如何知道當前MySQL設置的并發連接數是…

學習筆記(19):Python網絡編程并發編程-互斥鎖

立即學習:https://edu.csdn.net/course/play/24458/296430?utm_sourceblogtoedu 1.互斥鎖&#xff1a; 多進程間的內存是相互隔離的&#xff0c;因此其數據也是相互隔離的&#xff0c;但是所有的進程都共享一個文件操作系統或者說共享文件處理器和打印端。而共享帶來的是競爭…

使用HTML5+CSS3制作圓角內發光按鈕----示例

<!doctype html> <html> <head> <meta charset"utf-8" /> <title>制作漂亮的圓角按鈕<title> <style type"text/css"> .loginBtnDiv { float:right; padding-right:50px; padding-top:10px; } .loginBtn, .Resg…

C++中的sort()函數的原形

1、sor(a,an,compare) {//前兩個是參數是待排序的數組首地址和尾地址 //最后一個參數是compare表示的比較類型 //可調用functional函數的less&#xff08;&#xff09;和greater&#xff08;&#xff09;函數比較大小}

鼠標放上超鏈接顯示背景效果

鼠標放上超鏈接顯示背景效果&#xff1a; <html> <head> <style type"text/css"> a.one:link {color: #ff0000} a.one:visited {color: #0000ff} a.one:hover {color: #ffcc00}a.two:link {color: #ff0000} a.two:visited {color: #0000ff} a.two:…

學習筆記(20):Python網絡編程并發編程-互斥鎖與join的區別

立即學習:https://edu.csdn.net/course/play/24458/296432?utm_sourceblogtoedu 互斥鎖與join的異同&#xff1a; 1.同&#xff1a;都是將多進程并發模式變成多進程串行&#xff0c;保證了數據的有序性 2.異&#xff1a; 互斥鎖只是對于進程的局部代碼實施串行執行變化&#x…

Kali滲透(二)之被動信息收集

被動信息收集 公開渠道可獲得的信息 與目標系統不產生直接交互 盡量避免留下一切痕跡 下面是兩個關于開源情報&#xff08;OSINT&#xff09;的書籍 美國軍方 北大西洋公約組織 信息收集內容 一.IP地址段與域名信息 二.郵件地址 三.文檔圖片數據 四.公司地址 五.公司組織…

ccBPM典型的樹形表單和多表頭表單的流程示例

ccBPM典型的樹形表單和多表頭表單的流程 關鍵字&#xff1a;樹形表單。ccBPM支持樹形表單&#xff0c;也可以稱之為樹結構的多表單或者多表頭表單。 應用場景&#xff1a;比如項目招標類流程&#xff0c;在填寫項目申請的環節&#xff0c;需要填寫公司簡介、公司業績、項目實施…

由strcat函數引發的對char *a和char a[]以及sizeof和strlen

/* http://www.cnblogs.com/kaituorensheng/archive/2012/10/23/2736069.html參考這篇文章* char *a "Hello";Hello存放在常量區&#xff0c;是無法修改的。 * 通過指針只可以訪問字符串常量&#xff0c;而不可以去改變它 * * * char a[] "Hello";…

for(;;)函數中判斷條件執行順序

for(i100;i>0&#xff1b;--i) { cout<<"i"<<i<<endl; } 它的執行過程如下&#xff1a; 1) 先求解表達式1。 2) 求解表達式2&#xff0c;若其值為真&#xff08;非0&#xff09;&#xff0c;則執行for語句中指定的內嵌語句&…

學習筆記(21):Python網絡編程并發編程-隊列的使用

立即學習:https://edu.csdn.net/course/play/24458/296433?utm_sourceblogtoedu 隊列和管道 1.存在的意義&#xff1a; 1&#xff09;在前面的筆記中&#xff0c;使用join和互斥鎖來保證了硬盤數據共享的數據安全性&#xff0c;但是降低了代碼的運行效率&#xff1b; 2&#x…

dbms_xplan之display_cursor函數的使用

文章來源&#xff1a;http://blog.csdn.net/leshami/article/details/6866925 DBMS_XPLAN包中display_cursor函數不同于display函數&#xff0c;display_cursor用于顯示SQL語句的真實的執行計劃&#xff0c;在大多數情況下&#xff0c;顯示真實 的執行計劃有助于更好的分析SQL語…

H5+JS實現《Just Do 8》游戲源碼分享

【界面效果圖】 【代碼結構】 【代碼結構解釋】 1、使用html語言實現數據 2、使用css3語言實現樣式 3、使用JS語言實現路基控制 【注意是想】 1、如需查看效果&#xff0c;請使用手機瀏覽器&#xff0c;或者使用appcan打包查看 2、如果使用瀏覽器&#xff0c;請選擇google的Chr…

windows下的結束標志

空格 ctrlz ctrlz 回車 int main() { stack<string> ss; //std::vector<int> ss; string str; cout<<"請輸入字符串"<<endl; while(cin>>str) { ss.push(str); //if(str[0]1) …

前端架構知識體系

0. 前端自動化(Workflow) 前端構建工具 Yeoman – a set of tools for automating development workflowgulp – The streaming build systemgrunt – the JavaScript Task RunnerF.I.S – 前端集成解決方案webpackNPM前端模塊管理器 Bower – A package manager for the webBr…

python數據結構_大O符號_學習筆記(1)

1.概念 &#xff1a;大O符號是用來表達一個算法的復雜程度的&#xff0c;是一個數量級 2.代碼 a 1 b 2 c 3 for i in range(n):for j in range(n):x i*iy j*jz i*jfor k in range(n):m a*k 5v k*kd 100*c e c*d3.分析 在上述代碼中&#xff0c;分配操作數分為四…

.NET簡談組件程序設計之(上下文與同步域)

我們繼續學習.NET多線程技術&#xff0c;這篇文章的內容可能有點復雜。在打破常理之后&#xff0c;換一種新的思考模型最為頭疼。這篇文章里面會涉及到一些不太常見的概念&#xff0c;比如&#xff1a;上下文、同步域等等。我也是最近才接觸這些關于組件編程方面的高深技術&…

string類的各種函數用法

標準c中string類函數介紹 注意不是CString 之所以拋棄char*的字符串而選用C標準程序庫中的string類&#xff0c;是因為他和前者比較起來&#xff0c;不必 擔心內存是否足夠、字符串長度等等&#xff0c;而且作為一個類出現&#xff0c;他集成的操作函數足以完成我們大多數情況…

調用圖片按鈕的img圖片

今天是我學前端的第12天。早上起床后活動筋骨時看了《JS的基本屬性操作》&#xff0c;作業是模擬手機發送短信。文字都能傳輸到<div>上&#xff0c;就是圖片不知道怎么傳。折騰了好久才弄清楚&#xff0c;多虧了某群的小伙伴們。 這一節課&#xff0c;我學會了如何調用圖…

利用api接口來實現web網頁登陸

因為公司的所有鏈接數據庫的都是用的api接口 最近做了一個用api接口登陸 function Login() { if (!Validate()) { return false; } var para {}; para.action "login_by_api"; para.login_name $.trim($("#txtLoginName").val()); para.password $.tr…