一培廓、URL
URL的全稱是Uniform Resource Locator(統(tǒng)一資源定位符),通過(guò)1個(gè)URL拷恨,能找到互聯(lián)網(wǎng)上唯一的1個(gè)資源,URL就是資源的地址、位置,互聯(lián)網(wǎng)上的每個(gè)資源都有一個(gè)唯一的URL
的基本格式 = 協(xié)議://主機(jī)地址/路徑,示例:
http://www.baidu.com/img/logo.png
http://111.111.111.111/img/bdlogo.gif協(xié)議坡氯、主機(jī)地址、路徑的含義:
協(xié)議:不同的協(xié)議都哭,代表著不同的資源查找方式详民、資源傳輸方式
主機(jī)地址:存放資源的主機(jī)(服務(wù)器)的IP地址(域名)
路徑:資源在主機(jī)(服務(wù)器)中的具體位置
二、HTTP協(xié)議
1.HTTP協(xié)議簡(jiǎn)介
- HTTP的全稱是Hypertext Transfer Protocol帚呼,超文本傳輸協(xié)議
- 規(guī)定客戶端和服務(wù)器之間的數(shù)據(jù)傳輸格式
- 讓客戶端和服務(wù)器能有效地進(jìn)行數(shù)據(jù)溝通
2.HTTP協(xié)議特點(diǎn)
- 簡(jiǎn)單快速:因?yàn)镠TTP協(xié)議簡(jiǎn)單掏缎,所以HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快
- 靈活:HTTP允許傳輸各種各樣的數(shù)據(jù)
- HTTP 0.9和1.0使用非持續(xù)連接:限制每次連接只處理一個(gè)請(qǐng)求煤杀,服務(wù)器對(duì)客戶端的請(qǐng)求做出響應(yīng)后眷蜈,馬上斷開(kāi)連接,這種方式可以節(jié)省傳輸時(shí)間
3.HTTP協(xié)議的請(qǐng)求方法
- 在HTTP/1.1協(xié)議中沈自,定義了8種發(fā)送http請(qǐng)求的方法:GET酌儒、POST、OPTIONS枯途、HEAD忌怎、PUT籍滴、DELETE、TRACE榴啸、CONNECT孽惰、PATCH
- PUT :增、DELETE :刪鸥印、POST:改勋功、GET:查
- 最常用的是GET和POST(實(shí)際上GET和POST都能辦到增刪改查)
4.GET和POST
4.1、GET
- 在請(qǐng)求URL后面以?的形式跟上發(fā)給服務(wù)器的參數(shù)库说,多個(gè)參數(shù)之間用&隔開(kāi)狂鞋,比如:http://ww.test.com/login?username=123&pwd=234&type=JSON
- 由于瀏覽器和服務(wù)器對(duì)URL長(zhǎng)度有限制,因此在URL后面附帶的參數(shù)是有限制的潜的,通常不能超過(guò)1KB
- 如果僅僅是索取數(shù)據(jù)(數(shù)據(jù)查詢)骚揍,建議使用GET
4.2、POST
- 發(fā)給服務(wù)器的參數(shù)全部放在請(qǐng)求體中
- 理論上啰挪,POST傳遞的數(shù)據(jù)量沒(méi)有限制(具體還得看服務(wù)器的處理能力)
- 如果要傳遞大量數(shù)據(jù)信不,比如文件上傳,只能用POST請(qǐng)求
- GET的安全性比POST要差些脐供,如果包含機(jī)密\敏感信息浑塞,建議用POST
- 如果是增加、修改政己、刪除數(shù)據(jù)酌壕,建議使用POST
5、iOS中發(fā)送HTTP請(qǐng)求的方案
5.1歇由、蘋果原生(自帶)
- NSURLConnection:用法簡(jiǎn)單卵牍,最古老最經(jīng)典最直接的一種方案【坑比較多】
- NSURLSession:功能比NSURLConnection更加強(qiáng)大,蘋果目前比較推薦使用這種技術(shù)【2013推出沦泌,iOS7開(kāi)始出的技術(shù)】
- CFNetwork:NSURL*的底層糊昙,純C語(yǔ)言
5.2、第三方框架
- ASIHttpRequest:外號(hào)“HTTP終結(jié)者”谢谦,功能極其強(qiáng)大释牺,可惜早已停止更新
- AFNetworking:簡(jiǎn)單易用,提供了基本夠用的常用功能回挽,維護(hù)和使用者多
- MKNetworkKit:簡(jiǎn)單易用没咙,維護(hù)和使用者少
6、HTTP通信過(guò)程
6.1千劈、請(qǐng)求
- HTTP協(xié)議規(guī)定:1個(gè)完整的由客戶端發(fā)給服務(wù)器的HTTP請(qǐng)求中包含以下內(nèi)容
- 請(qǐng)求頭:包含了對(duì)客戶端的環(huán)境描述祭刚、客戶端請(qǐng)求信息等
- GET /minion.png HTTP/1.1 // 包含了請(qǐng)求方法、請(qǐng)求資源路徑、HTTP協(xié)議版本
- Host: 120.25.226.186:32812 // 客戶端想訪問(wèn)的服務(wù)器主機(jī)地址
- User-Agent: Mozilla/5.0 // 客戶端的類型涡驮,客戶端的軟件環(huán)境
- Accept: text/html, / // 客戶端所能接收的數(shù)據(jù)類型
- Accept-Language: zh-cn // 客戶端的語(yǔ)言環(huán)境
- Accept-Encoding: gzip // 客戶端支持的數(shù)據(jù)壓縮格式
- 請(qǐng)求體:客戶端發(fā)給服務(wù)器的具體數(shù)據(jù)暗甥,比如文件數(shù)據(jù)(POST請(qǐng)求才會(huì)有)
6.2、響應(yīng)
- 客戶端向服務(wù)器發(fā)送請(qǐng)求捉捅,服務(wù)器應(yīng)當(dāng)做出響應(yīng)撤防,即返回?cái)?shù)據(jù)給客戶端
- HTTP協(xié)議規(guī)定:1個(gè)完整的HTTP響應(yīng)中包含以下內(nèi)容:
- 響應(yīng)頭:包含了對(duì)服務(wù)器的描述、對(duì)返回?cái)?shù)據(jù)的描述:
- HTTP/1.1 200 OK // 包含了HTTP協(xié)議版本锯梁、狀態(tài)碼即碗、狀態(tài)英文名稱
- Server: Apache-Coyote/1.1 // 服務(wù)器的類型
- Content-Type: image/jpeg // 返回?cái)?shù)據(jù)的類型
- Content-Length: 56811 // 返回?cái)?shù)據(jù)的長(zhǎng)度
- Date: Mon, 23 Jun 2014 12:54:52 GMT // 響應(yīng)的時(shí)間
- 響應(yīng)體:服務(wù)器返回給客戶端的具體數(shù)據(jù),比如文件數(shù)據(jù)
6.3陌凳、常見(jiàn)的響應(yīng)狀態(tài)碼
常見(jiàn)服務(wù)器響應(yīng)的狀態(tài)碼
三、NSURLConnection
1内舟、NSURLConnection的使用步驟
- 創(chuàng)建一個(gè)NSURL對(duì)象合敦,設(shè)置請(qǐng)求路徑
- 傳入NSURL創(chuàng)建一個(gè)NSURLRequest對(duì)象,設(shè)置請(qǐng)求頭和請(qǐng)求體(POST請(qǐng)求的時(shí)候使用NSMutableURLRequest設(shè)置請(qǐng)求體验游,GET和POST請(qǐng)求頭已經(jīng)默認(rèn)設(shè)置好了)
- 使用NSURLConnection發(fā)送請(qǐng)求
1.1充岛、NSURLConnection使用圖示
NSURLConnection使用圖示
2.NSURLConnection實(shí)際使用
2.1、NSURLConnection的基本使用
//發(fā)送異步請(qǐng)求:不會(huì)卡住當(dāng)前線程
- (void)async{
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", string);
//獲取響應(yīng)頭信息
NSHTTPURLResponse *r = (NSHTTPURLResponse *)response;
NSLog(@"%zd %@", r.statusCode, r.allHeaderFields);
}];
}
//發(fā)送同步請(qǐng)求:卡住當(dāng)前線程耕蝉,直到請(qǐng)求完成
- (void)sync{
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=123&pwd=345"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@ %@", string, response.allHeaderFields);
}
2.2崔梗、NSURLConnection的代理方式:拿到connection對(duì)象調(diào)用cancel方法可以取消請(qǐng)求
- (void)delegateAysnc{
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];//自動(dòng)請(qǐng)求
//[[NSURLConnection alloc] initWithRequest:request delegate:self];//自動(dòng)請(qǐng)求
//startImmediately:YES:立即自動(dòng)請(qǐng)求,NO:調(diào)用conn的start方法才會(huì)請(qǐng)求
//NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
}
//<NSURLConnectionDataDelegate>
// 接收到服務(wù)器的響應(yīng)
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
}
//接收到服務(wù)器的數(shù)據(jù)(如果數(shù)據(jù)量比較大,這個(gè)方法會(huì)被調(diào)用多次)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
}
//服務(wù)器的數(shù)據(jù)成功接收完畢
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
}
//請(qǐng)求失斃菰凇(比如請(qǐng)求超時(shí))
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
}
2.3蒜魄、NSMutableURLRequest簡(jiǎn)介
//設(shè)置請(qǐng)求超時(shí)等待時(shí)間(超過(guò)這個(gè)時(shí)間就算超時(shí),請(qǐng)求失敵∏)
- (void)setTimeoutInterval:(NSTimeInterval)seconds;
//設(shè)置請(qǐng)求方法(比如GET和POST)
- (void)setHTTPMethod:(NSString *)method;
//設(shè)置請(qǐng)求體
- (void)setHTTPBody:(NSData *)data;
//設(shè)置請(qǐng)求頭
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;
2.4谈为、NSURLConnection發(fā)送POST請(qǐng)求
- (void)sendPOSTRequest {
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=520it&pwd=520it" dataUsingEncoding:NSUTF8StringEncoding];
request.timeoutInterval = 5;
// 設(shè)置請(qǐng)求頭
//[request setValue:@"iOS 9.0" forHTTPHeaderField:@"User-Agent"];
// 3.發(fā)送請(qǐng)求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
}];
}
2.5、URL中文轉(zhuǎn)碼
//URL中包含中文的話需要進(jìn)行轉(zhuǎn)碼踢关,否則識(shí)別不了
- (nullable NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)enc;
四伞鲫、JSON&XML
1、JSON
- 第三方框架:JSONKit签舞、SBJson秕脓、TouchJSON(性能從左到右,越差)
- 蘋果原生(自帶):NSJSONSerialization(性能最好)
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
+ (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;
2儒搭、XML
- 全稱是Extensible Markup Language吠架,譯作“可擴(kuò)展標(biāo)記語(yǔ)言”,跟JSON一樣,也是常用的一種用于交互的數(shù)據(jù)格式,一般也叫XML文檔(XML Document)
- 一個(gè)常見(jiàn)的XML文檔一般由以下部分組成:
文檔聲明
元素(Element)
屬性(Attribute)
2.1师妙、文檔聲明
- 在XML文檔的最前面诵肛,必須編寫一個(gè)文檔聲明,用來(lái)聲明XML文檔的類型
- 最簡(jiǎn)單的聲明:
<?xml version="1.0" ?>- 用encoding屬性說(shuō)明文檔的字符編碼:
<?xml version="1.0" encoding="UTF-8" ?>
2.2、元素(Element)
- 一個(gè)元素包括了開(kāi)始標(biāo)簽和結(jié)束標(biāo)簽
- 擁有內(nèi)容的元素:<video>小黃人</video>
- 沒(méi)有內(nèi)容的元素:<video></video>
- 沒(méi)有內(nèi)容的元素簡(jiǎn)寫:<video/>
一個(gè)元素可以嵌套若干個(gè)子元素(不能出現(xiàn)交叉嵌套)
元素嵌套- 規(guī)范的XML文檔最多只有1個(gè)根元素怔檩,其他元素都是根元素的子孫元素
2.3褪秀、屬性(Attribute)
- 一個(gè)元素可以擁有多個(gè)屬性
<video name="小黃人 第01部" length="30" />- video元素?fù)碛衝ame和length兩個(gè)屬性
- 屬性值必須用 雙引號(hào)"" 或者 單引號(hào)'' 括住
3、XML的解析
3.1薛训、DOM&SAX
- DOM:一次性將整個(gè)XML文檔加載進(jìn)內(nèi)存媒吗,比較適合解析小文件
- SAX:從根元素開(kāi)始,按順序一個(gè)元素一個(gè)元素往下解析乙埃,比較適合解析大文件
3.2闸英、解析方式
- 蘋果原生
NSXMLParser:SAX方式解析,使用簡(jiǎn)單- 第三方框架
libxml2:純C語(yǔ)言介袜,默認(rèn)包含在iOS SDK中甫何,同時(shí)支持DOM和SAX方式解析
GDataXML:DOM方式解析,由Google開(kāi)發(fā)遇伞,基于libxml2- XML解析方式的選擇建議
大文件:NSXMLParser辙喂、libxml2
小文件:GDataXML、NSXMLParser鸠珠、libxml2
3.3巍耗、GDataXML的配置
3.3.1、GDataXML下載地址 密碼:hsfn
3.3.2渐排、導(dǎo)入libxml2庫(kù):
導(dǎo)入libxml2庫(kù)
3.3.3炬太、設(shè)置libxml2的頭文件搜索路徑(為了能找到libxml2庫(kù)的所有頭文件):
在Head Search Path中加入/usr/include/libxml2
3.3.4、設(shè)置鏈接參數(shù)(自動(dòng)鏈接libxml2庫(kù):
在Other Linker Flags中加入-lxml2
3.4驯耻、NSXMLParser解析示例:
//XML大致格式
<videos>
<video id="1" name="xxx" length="xxx" url="xxx" image= "xxx"/>
<video id="2" name="xxx" length="xxx" url="xxx" image= "xxx"/>
<video id="3" name="xxx" length="xxx" url="xxx" image= "xxx"/>
</videos>
- (void)NSXMLParserTest {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];//會(huì)阻塞當(dāng)前線程
}];
}
#pragma mark - <NSXMLParserDelegate>
//解析到某個(gè)元素的結(jié)尾(比如解析</videos>)
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
}
// 解析到某個(gè)元素的開(kāi)頭(比如解析<videos>)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
if ([elementName isEqualToString:@"videos"]) return;
VideoModel *video = [VideoModel objectWithKeyValues:attributeDict];
[self.videos addObject:video];
}
//開(kāi)始解析XML文檔
- (void)parserDidStartDocument:(NSXMLParser *)parser{
}
//解析完畢
- (void)parserDidEndDocument:(NSXMLParser *)parser{
}
3.5亲族、GDataXML解析示例:
//XML大致格式
<videos>
<video id="1" name="xxx" length="xxx" url="xxx" image= "xxx"/>
<video id="2" name="xxx" length="xxx" url="xxx" image= "xxx"/>
<video id="3" name="xxx" length="xxx" url="xxx" image= "xxx"/>
</videos>
- (void)GDataXMLTest {
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 加載整個(gè)文檔
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil];
// 獲得所有video元素
NSArray *elements = [doc.rootElement elementsForName:@"video"];
for (GDataXMLElement *ele in elements) {
VideoModel *video = [[VideoModel alloc] init];
video.name = [ele attributeForName:@"name"].stringValue;
video.url = [ele attributeForName:@"url"].stringValue;
video.image = [ele attributeForName:@"image"].stringValue;
video.length = [ele attributeForName:@"length"].stringValue.integerValue;
[self.videos addObject:video];
}
}];
}