版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2018.03.05 |
前言
我們做APP發(fā)起網(wǎng)絡請求,一般都是使用框架锭弊,這些框架的底層也都是蘋果的API填硕,接下來幾篇就一起來看一下和網(wǎng)絡有關的幾個類。感興趣的可以看上面幾篇文章炼吴。
1. 詳細解析幾個和網(wǎng)絡請求有關的類 (一) —— NSURLSession
2. 詳細解析幾個和網(wǎng)絡請求有關的類(二) —— NSURLRequest和NSMutableURLRequest
回顧
上一篇主要介紹了NSURLRequest
和NSMutableURLRequest
的本類和分類的接口使用文檔本鸣。這一篇主要介紹NSURLConnection
。這個類雖然被NSURLSession替代硅蹦,但是還是拿出來說下吧荣德。
NSURLConnection類
應該不再使用NSURLConnection
類。 NSURLSession
是NSURLConnection
的替代童芹。
NSURLConnection
對象提供支持來執(zhí)行URL請求的異步加載涮瞻,向客戶端代理提供數(shù)據(jù)。
NSURLConnection
的接口非常稀疏假褪,只提供控制來啟動和取消URL請求的異步加載署咽。
NSURLConnection
可用于將資源數(shù)據(jù)直接加載到內(nèi)存,在這種情況下應提供NSURLConnectionDataDelegate
,或將資源數(shù)據(jù)直接下載到文件宁否,在這種情況下使用NSURLConnectionDownloadDelegate
窒升。 代理由NSURLConnection
保留,直到遇到終止條件慕匠。 這兩個委托在邏輯上是基本協(xié)議NSURLConnectionDelegate
的子類饱须。
下載器產(chǎn)生的終止條件將導致連接:didFailWithError:
出現(xiàn)錯誤或connectiondidFinishLoading:
或connectionDidFinishDownloading:
代理消息。
- cancel
消息提示加載器應該放棄資源加載台谊,但不能保證更多代理消息不會被傳遞蓉媳。 如果- cancel
確實會導致負載被放棄,那么代理將被釋放锅铅,而不會有進一步的消息酪呻。 一般來說,調(diào)用者應該做好準備盐须,使用方法- cancel号杠,防止產(chǎn)生影響,并在內(nèi)部忽略任何代理回調(diào)丰歌,直到代理被釋放姨蟋。
NSURLConnection
的調(diào)度指定了代理回調(diào)的上下文,但實際的IO可能發(fā)生在單獨的線程上立帖,應該被視為實現(xiàn)細節(jié)眼溶。
創(chuàng)建時,NSURLConnection
執(zhí)行NSURLRequest
的深拷貝晓勇。 該副本可通過- originalRequest
方法獲得堂飞。 當連接執(zhí)行加載時,該請求可能會因協(xié)議規(guī)范化或由于以下重定向而改變绑咱。 - currentRequest
可以用來檢索這個值绰筛。
使用+ connectionWithRequest:delegate:
或-initWithRequest:delegate:
方法創(chuàng)建的NSURLConnections
會立即安排在當前的runloop
上,并且不需要發(fā)送- start
消息來開始資源加載描融。
使用-initWithRequest:delegate:startImmediately
創(chuàng)建的NSURLConnections不會自動調(diào)度铝噩。 使用-scheduleWithRunLoop:forMode:
或-setDelegateQueue:
為委托回調(diào)指定上下文,并調(diào)用- start
開始加載窿克。 如果您在- start
之前沒有明確地安排連接骏庸,它將自動安排在當前的runloop和模式中。
NSURLConnectionSynchronousLoading
類別添加了+ sendSynchronousRequest:returningResponse:error
年叮,它會阻塞當前線程具被,直到資源數(shù)據(jù)可用或發(fā)生錯誤。 應該注意的是只损,在應用程序主運行循環(huán)中使用此方法可能會導致用戶界面中的延遲時間過長一姿,強烈建議不這么使用。
NSURLConnectionQueuedLoading
類實現(xiàn)了+ sendAsynchronousRequest:queue:completionHandler
,提供了類似的簡單性叮叹,但是提供了一種機制艾栋,當前的runloop
沒有被阻塞。
兩種即時加載類別都不提供對資源加載的定制衬横,并且不允許調(diào)用者響應例如認證挑戰(zhàn)裹粤。
1. NSURLConnection本類
下面我們就看一下NSURLConnection
類的API文檔终蒂。
@interface NSURLConnection : NSObject
{
@private
NSURLConnectionInternal *_internal;
}
/* Designated initializer */
// 這幾個都是初始化方法
- (nullable instancetype)initWithRequest:(NSURLRequest *)request delegate:(nullable id)delegate startImmediately:(BOOL)startImmediately API_DEPRECATED("Use NSURLSession (see NSURLSession.h)", macos(10.5,10.11), ios(2.0,9.0), tvos(9.0,9.0)) __WATCHOS_PROHIBITED;
- (nullable instancetype)initWithRequest:(NSURLRequest *)request delegate:(nullable id)delegate API_DEPRECATED("Use NSURLSession (see NSURLSession.h)", macos(10.3,10.11), ios(2.0,9.0), tvos(9.0,9.0)) __WATCHOS_PROHIBITED;
+ (nullable NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(nullable id)delegate API_DEPRECATED("Use NSURLSession (see NSURLSession.h)", macos(10.3,10.11), ios(2.0,9.0), tvos(9.0,9.0)) __WATCHOS_PROHIBITED;
@property (readonly, copy) NSURLRequest *originalRequest API_AVAILABLE(macos(10.8), ios(5.0), watchos(2.0), tvos(9.0));
@property (readonly, copy) NSURLRequest *currentRequest API_AVAILABLE(macos(10.8), ios(5.0), watchos(2.0), tvos(9.0));
// 開始和取消
- (void)start API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
- (void)cancel;
// 在運行循環(huán)上的調(diào)度
- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSRunLoopMode)mode API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
- (void)unscheduleFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSRunLoopMode)mode API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
- (void)setDelegateQueue:(nullable NSOperationQueue*) queue API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
/*!
@method canHandleRequest:
@abstract
Performs a "preflight" operation that performs
some speculative checks to see if a connection can
be initialized, and the associated I/O that is
started in the initializer methods can begin.
// 執(zhí)行“預檢”操作蜂林,執(zhí)行一些推測檢查以查看是否可以初始化連接,
并且可以開始在初始化程序方法中啟動的關聯(lián)I / O拇泣。
@discussion
The result of this method is valid only as long as
no protocols are registered or unregistered, and
as long as the request is not mutated (if the
request is mutable). Hence, clients should be
prepared to handle failures even if they have
performed request preflighting by calling this
method.
// 只有沒有協(xié)議被注冊或未注冊噪叙,并且只要請求沒有發(fā)生變化(如果請求是可變的),
此方法的結果也是有效的霉翔。 因此睁蕾,即使客戶通過調(diào)用此方法執(zhí)行請求預檢,
也應該準備好處理失敗债朵。
@param
request The request to preflight.
@result YES if it is likely that the given request can be used to
initialize a connection and the associated I/O can be
started, NO otherwise.
// YES子眶,如果可能使用給定的請求來初始化連接并且可以啟動關聯(lián)的I / O,否則返回NO序芦。
*/
+ (BOOL)canHandleRequest:(NSURLRequest *)request;
@end
2. NSURLConnection分類NSURLConnectionSynchronousLoading
@interface NSURLConnection (NSURLConnectionSynchronousLoading)
/*!
@method sendSynchronousRequest:returningResponse:error:
@abstract
Performs a synchronous load of the given request,
returning an NSURLResponse in the given out
parameter.
// NSURLConnection上的NSURLConnectionSynchronousLoading類別提供了執(zhí)行URL請求同步加載的接口臭杰。
執(zhí)行給定請求的同步加載,并返回給定輸出參數(shù)中的NSURLResponse
@discussion
A synchronous load for the given request is built on
top of the asynchronous loading code made available
by the class. The calling thread is blocked while
the asynchronous loading system performs the URL load
on a thread spawned specifically for this load
request. No special threading or run loop
configuration is necessary in the calling thread in
order to perform a synchronous load. For instance,
the calling thread need not be running its run loop.
// 給定請求的同步加載是建立在類提供的異步加載代碼之上的谚中。 調(diào)用線程在異步加載系統(tǒng)
// 對專門為此加載請求生成的線程執(zhí)行URL加載時被阻塞渴杆。 為了執(zhí)行同步加載,
// 在調(diào)用線程中不需要特殊的線程或運行循環(huán)配置宪塔。 例如磁奖,調(diào)用線程不需要運行它的運行循環(huán)。
@param
request The request to load. Note that the request is
deep-copied as part of the initialization
process. Changes made to the request argument after
this method returns do not affect the request that is
used for the loading process.
// 加載的請求某筐。 請注意比搭,該請求是作為初始化過程的一部分進行深度復制的。
// 此方法返回后對請求參數(shù)所做的更改不會影響用于加載過程的請求南誊。
@param
response An out parameter which is filled in with the
response generated by performing the load.
@param
error Out parameter (may be NULL) used if an error occurs
while processing the request. Will not be modified if the
load succeeds.
@result The content of the URL resulting from performing the load,
or nil if the load failed.
*/
+ (nullable NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse * _Nullable * _Nullable)response error:(NSError **)error API_DEPRECATED("Use [NSURLSession dataTaskWithRequest:completionHandler:] (see NSURLSession.h", macos(10.3,10.11), ios(2.0,9.0), tvos(9.0,9.0)) __WATCHOS_PROHIBITED;
@end
3. NSURLConnection分類NSURLConnectionQueuedLoading
@interface NSURLConnection (NSURLConnectionQueuedLoading)
/*!
@method sendAsynchronousRequest:queue:completionHandler:
@abstract
Performs an asynchronous load of the given
request. When the request has completed or failed,
the block will be executed from the context of the
specified NSOperationQueue.
// NSURLConnection上的NSURLConnectionQueuedLoading類別提供了一個接口敢辩,用于執(zhí)行URL請求的異步加載,請求的結果通過NSOperationQueue傳遞給塊的弟疆。
// 請注意戚长,此方法不能保證加載的順序。執(zhí)行給定請求的異步加載怠苔。 當請求完成或失敗時同廉,
// 塊將從指定的NSOperationQueue的上下文中執(zhí)行。
@discussion
This is a convenience routine that allows for
asynchronous loading of an url based resource. If
the resource load is successful, the data parameter
to the callback will contain the resource data and
the error parameter will be nil. If the resource
load fails, the data parameter will be nil and the
error will contain information about the failure.
// 這是一個便利的例程,它允許異步加載基于url的資源迫肖。 如果資源加載成功锅劝,
// 則回調(diào)的數(shù)據(jù)參數(shù)將包含資源數(shù)據(jù),錯誤參數(shù)將為nil蟆湖。 如果資源加載失敗故爵,
// 則數(shù)據(jù)參數(shù)將為nil,并且錯誤將包含有關失敗的信息隅津。
@param
request The request to load. Note that the request is
deep-copied as part of the initialization
process. Changes made to the request argument after
this method returns do not affect the request that
is used for the loading process.
@param
queue An NSOperationQueue upon which the handler block will
be dispatched.
@param
handler A block which receives the results of the resource load.
*/
+ (void)sendAsynchronousRequest:(NSURLRequest*) request
queue:(NSOperationQueue*) queue
completionHandler:(void (^)(NSURLResponse* _Nullable response, NSData* _Nullable data, NSError* _Nullable connectionError)) handler API_DEPRECATED("Use [NSURLSession dataTaskWithRequest:completionHandler:] (see NSURLSession.h", macos(10.7,10.11), ios(5.0,9.0), tvos(9.0,9.0)) __WATCHOS_PROHIBITED;
@end
形形色色的代理
1. NSURLConnectionDelegate
@protocol NSURLConnectionDelegate <NSObject>
@optional
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection;
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace API_DEPRECATED("Use -connection:willSendRequestForAuthenticationChallenge: instead.", macos(10.6,10.10), ios(3.0,8.0), watchos(2.0,2.0), tvos(9.0,9.0));
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge API_DEPRECATED("Use -connection:willSendRequestForAuthenticationChallenge: instead.", macos(10.2,10.10), ios(2.0,8.0), watchos(2.0,2.0), tvos(9.0,9.0));
- (void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge API_DEPRECATED("Use -connection:willSendRequestForAuthenticationChallenge: instead.", macos(10.2,10.10), ios(2.0,8.0), watchos(2.0,2.0), tvos(9.0,9.0));
@end
2. NSURLConnectionDataDelegate
@protocol NSURLConnectionDataDelegate <NSURLConnectionDelegate>
@optional
- (nullable NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(nullable NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (nullable NSInputStream *)connection:(NSURLConnection *)connection needNewBodyStream:(NSURLRequest *)request;
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
- (nullable NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
@end
3. NSURLConnectionDownloadDelegate
@protocol NSURLConnectionDownloadDelegate <NSURLConnectionDelegate>
@optional
- (void)connection:(NSURLConnection *)connection didWriteData:(long long)bytesWritten totalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long) expectedTotalBytes;
- (void)connectionDidResumeDownloading:(NSURLConnection *)connection totalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long) expectedTotalBytes;
@required
- (void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *) destinationURL;
@end
從這里就可以看出來三個代理方法的關系诬垂,NSURLConnectionDelegate
是父協(xié)議,NSURLConnectionDataDelegate
和NSURLConnectionDownloadDelegate
都繼承那個父協(xié)議伦仍。
后記
本篇講述了NSURLConnection及其相關的幾個代理
NSURLConnectionDelegate
结窘、NSURLConnectionDataDelegate
和NSURLConnectionDownloadDelegate
。