網(wǎng)絡篇-NSURLConnection

NSURLConnection是蘋果提供的原生網(wǎng)絡訪問類。下面這段話來自Objc對它的理解。

iOS 7 和 Mac OS X 10.9 Mavericks 中一個顯著的變化就是對 Foundation URL 加載系統(tǒng)的徹底重構(gòu)。

NSURLConnection 作為 Core Foundation / CFNetwork 框架的 API 之上的一個抽象,在 2003 年,隨著第一版的 Safari 的發(fā)布就發(fā)布了。NSURLConnection 這個名字,實際上是指代的 Foundation 框架的 URL 加載系統(tǒng)中一系列有關聯(lián)的組件:NSURLRequest、NSURLResponse、NSURLProtocol、 NSURLCache、 NSHTTPCookieStorage、NSURLCredentialStorage 以及同名類 NSURLConnection。

NSURLRequest 被傳遞給 NSURLConnection。被委托對象(遵守以前的非正式協(xié)議 <NSURLConnectionDelegate> 和 <NSURLConnectionDataDelegate>)異步地返回一個 NSURLResponse 以及包含服務器返回信息的 NSData。

在一個請求被發(fā)送到服務器之前,系統(tǒng)會先查詢共享的緩存信息,然后根據(jù)策略(policy)以及可用性(availability)的不同,一個已經(jīng)被緩存的響應可能會被立即返回。如果沒有緩存的響應可用,則這個請求將根據(jù)我們指定的策略來緩存它的響應以便將來的請求可以使用。

在把請求發(fā)送給服務器的過程中,服務器可能會發(fā)出鑒權查詢(authentication challenge),這可以由共享的 cookie 或機密存儲(credential storage)來自動響應,或者由被委托對象來響應。發(fā)送中的請求也可以被注冊的 NSURLProtocol 對象所攔截,以便在必要的時候無縫地改變其加載行為。

不管怎樣,NSURLConnection 作為網(wǎng)絡基礎架構(gòu),已經(jīng)服務了成千上萬的 iOS 和 Mac OS 程序,并且做的還算相當不錯。但是這些年,一些用例——尤其是在 iPhone 和 iPad 上面——已經(jīng)對 NSURLConnection 的幾個核心概念提出了挑戰(zhàn),讓蘋果有理由對它進行重構(gòu)。

在 2013 的 WWDC 上,蘋果推出了 NSURLConnection 的繼任者:NSURLSession。

創(chuàng)建請求

NSURL *msgURL = [NSURL URLWithString:@"http://freezing-cloud-6077.herokuapp.com/messages.json"];
NSURLRequest *msgRequest = [NSURLRequest requestWithURL:msgURL cachePolicy:(NSURLRequestUseProtocolCachePolicy) timeoutInterval:60];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:msgRequest delegate:self];//默認自動開啟start
if (theConnection) {
    NSMutableData *connData = [[NSMutableData alloc] init];
    [self setConnectionData:connData];
}else {
    NSLog(@"Connection failed...");
}
要接收來自網(wǎng)絡連接的數(shù)據(jù),需要實現(xiàn)以下代理方法。
// 收到服務器響應
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(nonnull NSURLResponse *)response {
    [self.connectionData setLength:0];
}
// 將收到的數(shù)據(jù)附加到一個本地數(shù)據(jù)對象末尾
- (void)connection:(NSURLConnection *)connection didReceiveData:(nonnull NSData *)data {
    [self.connectionData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    connection = nil;
    self.connectionData = nil;
    NSLog(@"Connection failed. Error - %@ %@",[error localizedDescription],[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSString *retString = [NSString stringWithUTF8String:[self.connectionData bytes]];
    NSLog(@"json data: %@", retString);
    NSError *parseError = nil;
    NSArray *jsonArray =
    [NSJSONSerialization JSONObjectWithData:self.connectionData
                                    options:0
                                      error:&parseError];
    
    if (!parseError) {
        NSLog(@"json array is %@", jsonArray);
    } else {
        NSString *err = [parseError localizedDescription];
        NSLog(@"Encountered error parsing: %@", err);
    }
    
    connection = nil;
    self.connectionData = nil;
}

發(fā)送請求

NSURLConnection默認發(fā)送異步請求,使用步驟大致是:
1.創(chuàng)建NSURL對象。
2.傳入NSURL創(chuàng)建一個NSURLRequest對象,設置請求頭和請求體。
3.使用NSURLConnection發(fā)送NSURLRequest。
發(fā)送請求分為同步請求和異步請求:

異步請求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:messageBoardURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
[request setHTTPMethod:@"POST"];//請求方法
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];//設置請求頭和請求體
[request setValue:[NSString stringWithFormat:@"%lu",
                           (unsigned long)[jsonData length]] forHTTPHeaderField:@"Content-Length"]; //3
[request setHTTPBody: jsonData];
//異步請求
[NSURLConnection  sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {

}];
同步請求
//1.確定請求路徑
NSURL *url = [NSURL URLWithString:@""];
//2.創(chuàng)建一個請求對象(提供默認請求頭信息,默認GET請求)
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.把請求發(fā)送給服務器
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
//4.解析服務器返回的信息
NSString *jsonData = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

與RunLoop關系

設置代理:
1.[[NSURLConnection alloc]initWithRequest:request delegate:self];
默認自動發(fā)送請求。
2.NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
當startImmediately是NO的時候不會發(fā)生請求,需要手動調(diào)用[connect start];
線程:
默認情況下代理方法在主線程進行,也可以手動設置隊列
[connect setDelegateQueue:[[NSOperationQueue alloc]init]];
3.子線程中網(wǎng)絡請求
//創(chuàng)建OperationQueue
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperationWithBlock:^{
     .....
     //此方法內(nèi)部會自動創(chuàng)建一個當前線程的runloop
     [connection start];
     //或者手動設置當前隊列
     [connection setDelegateQueue:[[NSOperationQueue alloc]init]];
     [[NSRunLoop currentRunLoop]run];
}];
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容