2012-07-18 12:17:55 -07:00
// AFURLConnectionOperation.h
2015-09-18 15:02:15 -07:00
// Copyright (c) 2011– 2015 Alamofire Software Foundation (http://alamofire.org/)
2013-09-25 17:43:00 -07:00
//
2012-07-18 12:17:55 -07:00
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
2013-09-25 17:43:00 -07:00
//
2012-07-18 12:17:55 -07:00
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
2013-09-25 17:43:00 -07:00
//
2012-07-18 12:17:55 -07:00
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
# import <Foundation / Foundation.h>
2013-09-25 17:43:00 -07:00
# import <Availability.h>
2015-09-18 15:02:15 -07:00
# import "AFURLRequestSerialization.h"
# import "AFURLResponseSerialization.h"
# import "AFSecurityPolicy.h"
# ifndef NS_DESIGNATED_INITIALIZER
# if __has_attribute(objc_designated_initializer)
# define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
# else
# define NS_DESIGNATED_INITIALIZER
# endif
# endif
2012-07-18 12:17:55 -07:00
/**
2013-09-25 17:43:00 -07:00
` AFURLConnectionOperation ` is a subclass of ` NSOperation ` that implements ` NSURLConnection ` delegate methods .
2012-07-18 12:17:55 -07:00
# # Subclassing Notes
2013-09-25 17:43:00 -07:00
2012-07-18 12:17:55 -07:00
This is the base class of all network request operations . You may wish to create your own subclass in order to implement additional ` NSURLConnection ` delegate methods ( see " `NSURLConnection` Delegate Methods " below ) , or to provide additional properties and / or class constructors .
2013-09-25 17:43:00 -07:00
2012-07-18 12:17:55 -07:00
If you are creating a subclass that communicates over the HTTP or HTTPS protocols , you may want to consider subclassing ` AFHTTPRequestOperation ` instead , as it supports specifying acceptable content types or status codes .
2013-09-25 17:43:00 -07:00
2012-07-18 12:17:55 -07:00
# # NSURLConnection Delegate Methods
2013-09-25 17:43:00 -07:00
2012-07-18 12:17:55 -07:00
` AFURLConnectionOperation ` implements the following ` NSURLConnection ` delegate methods :
2013-09-25 17:43:00 -07:00
2012-07-18 12:17:55 -07:00
- ` connection : didReceiveResponse : `
- ` connection : didReceiveData : `
- ` connectionDidFinishLoading : `
- ` connection : didFailWithError : `
- ` connection : didSendBodyData : totalBytesWritten : totalBytesExpectedToWrite : `
- ` connection : willCacheResponse : `
2013-09-25 17:43:00 -07:00
- ` connectionShouldUseCredentialStorage : `
- ` connection : needNewBodyStream : `
- ` connection : willSendRequestForAuthenticationChallenge : `
If any of these methods are overridden in a subclass , they _must_ call the ` super ` implementation first .
2012-07-18 12:17:55 -07:00
# # Callbacks and Completion Blocks
2013-09-25 17:43:00 -07:00
The built - in ` completionBlock ` provided by ` NSOperation ` allows for custom behavior to be executed after the request finishes . It is a common pattern for class constructors in subclasses to take callback block parameters , and execute them conditionally in the body of its ` completionBlock ` . Make sure to handle cancelled operations appropriately when setting a ` completionBlock ` ( i . e . returning early before parsing response data ) . See the implementation of any of the ` AFHTTPRequestOperation ` subclasses for an example of this .
Subclasses are strongly discouraged from overriding ` setCompletionBlock : ` , as ` AFURLConnectionOperation ` ' s implementation includes a workaround to mitigate retain cycles , and what Apple rather ominously refers to as [ " The Deallocation Problem " ] ( http : //developer.apple.com/library/ios/#technotes/tn2109/).
2015-09-18 15:02:15 -07:00
2013-09-25 17:43:00 -07:00
# # SSL Pinning
2015-09-18 15:02:15 -07:00
2013-09-25 17:43:00 -07:00
Relying on the CA trust model to validate SSL certificates exposes your app to security vulnerabilities , such as man - in - the - middle attacks . For applications that connect to known servers , SSL certificate pinning provides an increased level of security , by checking server certificate validity against those specified in the app bundle .
2015-09-18 15:02:15 -07:00
2013-09-25 17:43:00 -07:00
SSL with certificate pinning is strongly recommended for any application that transmits sensitive information to an external webservice .
2015-09-18 15:02:15 -07:00
Connections will be validated on all matching certificates with a ` . cer ` extension in the bundle root .
2013-09-25 17:43:00 -07:00
# # NSCoding & NSCopying Conformance
` AFURLConnectionOperation ` conforms to the ` NSCoding ` and ` NSCopying ` protocols , allowing operations to be archived to disk , and copied in memory , respectively . However , because of the intrinsic limitations of capturing the exact state of an operation at a particular moment , there are some important caveats to keep in mind :
# ## NSCoding Caveats
- Encoded operations do not include any block or stream properties . Be sure to set ` completionBlock ` , ` outputStream ` , and any callback blocks as necessary when using ` - initWithCoder : ` or ` NSKeyedUnarchiver ` .
- Operations are paused on ` encodeWithCoder : ` . If the operation was encoded while paused or still executing , its archived state will return ` YES ` for ` isReady ` . Otherwise , the state of an operation when encoding will remain unchanged .
# ## NSCopying Caveats
- ` - copy ` and ` - copyWithZone : ` return a new operation with the ` NSURLRequest ` of the original . So rather than an exact copy of the operation at that particular instant , the copying mechanism returns a completely new instance , which can be useful for retrying operations .
- A copy of an operation will not include the ` outputStream ` of the original .
2015-09-18 15:02:15 -07:00
- Operation copies do not include ` completionBlock ` , as it often strongly captures a reference to ` self ` , which would otherwise have the unintuitive side - effect of pointing to the _original_ operation when copied .
2012-07-18 12:17:55 -07:00
*/
2013-09-25 17:43:00 -07:00
2015-09-18 15:02:15 -07:00
NS_ASSUME_NONNULL_BEGIN
2013-09-25 17:43:00 -07:00
2015-09-18 15:02:15 -07:00
@ interface AFURLConnectionOperation : NSOperation < NSURLConnectionDelegate , NSURLConnectionDataDelegate , NSSecureCoding , NSCopying >
2012-07-18 12:17:55 -07:00
///-------------------------------
/// @name Accessing Run Loop Modes
///-------------------------------
/**
The run loop modes in which the operation will run on the network thread . By default , this is a single - member set containing ` NSRunLoopCommonModes ` .
*/
2013-09-25 17:43:00 -07:00
@ property ( nonatomic , strong ) NSSet * runLoopModes ;
2012-07-18 12:17:55 -07:00
///-----------------------------------------
/// @name Getting URL Connection Information
///-----------------------------------------
/**
The request used by the operation ' s connection .
*/
2013-09-25 17:43:00 -07:00
@ property ( readonly , nonatomic , strong ) NSURLRequest * request ;
2012-07-18 12:17:55 -07:00
/**
The last response received by the operation ' s connection .
*/
2015-09-18 15:02:15 -07:00
@ property ( readonly , nonatomic , strong , nullable ) NSURLResponse * response ;
2013-09-25 17:43:00 -07:00
/**
The error , if any , that occurred in the lifecycle of the request .
*/
2015-09-18 15:02:15 -07:00
@ property ( readonly , nonatomic , strong , nullable ) NSError * error ;
2012-07-18 12:17:55 -07:00
///----------------------------
/// @name Getting Response Data
///----------------------------
/**
2013-09-25 17:43:00 -07:00
The data received during the request .
2012-07-18 12:17:55 -07:00
*/
2015-09-18 15:02:15 -07:00
@ property ( readonly , nonatomic , strong , nullable ) NSData * responseData ;
2012-07-18 12:17:55 -07:00
/**
The string representation of the response data .
*/
2015-09-18 15:02:15 -07:00
@ property ( readonly , nonatomic , copy , nullable ) NSString * responseString ;
2012-07-18 12:17:55 -07:00
2013-09-25 17:43:00 -07:00
/**
The string encoding of the response .
If the response does not specify a valid string encoding , ` responseStringEncoding ` will return ` NSUTF8StringEncoding ` .
*/
@ property ( readonly , nonatomic , assign ) NSStringEncoding responseStringEncoding ;
///-------------------------------
/// @name Managing URL Credentials
///-------------------------------
/**
Whether the URL connection should consult the credential storage for authenticating the connection . ` YES ` by default .
This is the value that is returned in the ` NSURLConnectionDelegate ` method ` - connectionShouldUseCredentialStorage : ` .
*/
@ property ( nonatomic , assign ) BOOL shouldUseCredentialStorage ;
/**
The credential used for authentication challenges in ` - connection : didReceiveAuthenticationChallenge : ` .
This will be overridden by any shared credentials that exist for the username or password of the request URL , if present .
*/
2015-09-18 15:02:15 -07:00
@ property ( nonatomic , strong , nullable ) NSURLCredential * credential ;
///-------------------------------
/// @name Managing Security Policy
///-------------------------------
2013-09-25 17:43:00 -07:00
/**
2015-09-18 15:02:15 -07:00
The security policy used to evaluate server trust for secure connections .
2013-09-25 17:43:00 -07:00
*/
2015-09-18 15:02:15 -07:00
@ property ( nonatomic , strong ) AFSecurityPolicy * securityPolicy ;
2013-09-25 17:43:00 -07:00
2012-07-18 12:17:55 -07:00
///------------------------
/// @name Accessing Streams
///------------------------
/**
2013-09-25 17:43:00 -07:00
The input stream used to read data to be sent during the request .
This property acts as a proxy to the ` HTTPBodyStream ` property of ` request ` .
2012-07-18 12:17:55 -07:00
*/
2013-09-25 17:43:00 -07:00
@ property ( nonatomic , strong ) NSInputStream * inputStream ;
2012-07-18 12:17:55 -07:00
/**
The output stream that is used to write data received until the request is finished .
2013-09-25 17:43:00 -07:00
2015-09-18 15:02:15 -07:00
By default , data is accumulated into a buffer that is stored into ` responseData ` upon completion of the request , with the intermediary ` outputStream ` property set to ` nil ` . When ` outputStream ` is set , the data will not be accumulated into an internal buffer , and as a result , the ` responseData ` property of the completed request will be ` nil ` . The output stream will be scheduled in the network thread runloop upon being set .
*/
@ property ( nonatomic , strong , nullable ) NSOutputStream * outputStream ;
///---------------------------------
/// @name Managing Callback Queues
///---------------------------------
/**
The dispatch queue for ` completionBlock ` . If ` NULL ` ( default ) , the main queue is used .
*/
# if OS_OBJECT_HAVE_OBJC_SUPPORT
@ property ( nonatomic , strong , nullable ) dispatch_queue_t completionQueue ;
# else
@ property ( nonatomic , assign , nullable ) dispatch_queue_t completionQueue ;
# endif
/**
The dispatch group for ` completionBlock ` . If ` NULL ` ( default ) , a private dispatch group is used .
2012-07-18 12:17:55 -07:00
*/
2015-09-18 15:02:15 -07:00
# if OS_OBJECT_HAVE_OBJC_SUPPORT
@ property ( nonatomic , strong , nullable ) dispatch_group_t completionGroup ;
# else
@ property ( nonatomic , assign , nullable ) dispatch_group_t completionGroup ;
# endif
2013-09-25 17:43:00 -07:00
///---------------------------------------------
/// @name Managing Request Operation Information
///---------------------------------------------
/**
The user info dictionary for the receiver .
*/
@ property ( nonatomic , strong ) NSDictionary * userInfo ;
2015-09-18 15:02:15 -07:00
// FIXME: It doesn't seem that this userInfo is used anywhere in the implementation.
2012-07-18 12:17:55 -07:00
///------------------------------------------------------
/// @name Initializing an AFURLConnectionOperation Object
///------------------------------------------------------
/**
Initializes and returns a newly allocated operation object with a url connection configured with the specified url request .
2015-09-18 15:02:15 -07:00
2013-09-25 17:43:00 -07:00
This is the designated initializer .
2015-09-18 15:02:15 -07:00
2013-09-25 17:43:00 -07:00
@ param urlRequest The request object to be used by the operation connection .
2012-07-18 12:17:55 -07:00
*/
2015-09-18 15:02:15 -07:00
- ( instancetype ) initWithRequest : ( NSURLRequest * ) urlRequest NS_DESIGNATED_INITIALIZER ;
2012-07-18 12:17:55 -07:00
///----------------------------------
/// @name Pausing / Resuming Requests
///----------------------------------
/**
Pauses the execution of the request operation .
2013-09-25 17:43:00 -07:00
A paused operation returns ` NO ` for ` - isReady ` , ` - isExecuting ` , and ` - isFinished ` . As such , it will remain in an ` NSOperationQueue ` until it is either cancelled or resumed . Pausing a finished , cancelled , or paused operation has no effect .
2012-07-18 12:17:55 -07:00
*/
- ( void ) pause ;
/**
Whether the request operation is currently paused .
2013-09-25 17:43:00 -07:00
2012-07-18 12:17:55 -07:00
@ return ` YES ` if the operation is currently paused , otherwise ` NO ` .
*/
- ( BOOL ) isPaused ;
/**
Resumes the execution of the paused request operation .
2013-09-25 17:43:00 -07:00
Pause / Resume behavior varies depending on the underlying implementation for the operation class . In its base implementation , resuming a paused requests restarts the original request . However , since HTTP defines a specification for how to request a specific content range , ` AFHTTPRequestOperation ` will resume downloading the request from where it left off , instead of restarting the original request .
2012-07-18 12:17:55 -07:00
*/
- ( void ) resume ;
///----------------------------------------------
/// @name Configuring Backgrounding Task Behavior
///----------------------------------------------
/**
Specifies that the operation should continue execution after the app has entered the background , and the expiration handler for that background task .
2013-09-25 17:43:00 -07:00
@ param handler A handler to be called shortly before the application ’ s remaining background time reaches 0. The handler is wrapped in a block that cancels the operation , and cleans up and marks the end of execution , unlike the ` handler ` parameter in ` UIApplication - beginBackgroundTaskWithExpirationHandler : ` , which expects this to be done in the handler itself . The handler is called synchronously on the main thread , thus blocking the application ’ s suspension momentarily while the application is notified .
2015-09-18 15:02:15 -07:00
*/
2013-09-25 17:43:00 -07:00
# if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
2015-09-18 15:02:15 -07:00
- ( void ) setShouldExecuteAsBackgroundTaskWithExpirationHandler : ( nullable void ( ^ ) ( void ) ) handler NS_EXTENSION_UNAVAILABLE_IOS ( " Not available in app extensions. " ) ;
2012-07-18 12:17:55 -07:00
# endif
///---------------------------------
/// @name Setting Progress Callbacks
///---------------------------------
/**
Sets a callback to be called when an undetermined number of bytes have been uploaded to the server .
2013-09-25 17:43:00 -07:00
@ param block A block object to be called when an undetermined number of bytes have been uploaded to the server . This block has no return value and takes three arguments : the number of bytes written since the last time the upload progress block was called , the total bytes written , and the total bytes expected to be written during the request , as initially determined by the length of the HTTP body . This block may be called multiple times , and will execute on the main thread .
2012-07-18 12:17:55 -07:00
*/
2015-09-18 15:02:15 -07:00
- ( void ) setUploadProgressBlock : ( nullable void ( ^ ) ( NSUInteger bytesWritten , long long totalBytesWritten , long long totalBytesExpectedToWrite ) ) block ;
2012-07-18 12:17:55 -07:00
/**
Sets a callback to be called when an undetermined number of bytes have been downloaded from the server .
2013-09-25 17:43:00 -07:00
@ param block A block object to be called when an undetermined number of bytes have been downloaded from the server . This block has no return value and takes three arguments : the number of bytes read since the last time the download progress block was called , the total bytes read , and the total bytes expected to be read during the request , as initially determined by the expected content size of the ` NSHTTPURLResponse ` object . This block may be called multiple times , and will execute on the main thread .
2012-07-18 12:17:55 -07:00
*/
2015-09-18 15:02:15 -07:00
- ( void ) setDownloadProgressBlock : ( nullable void ( ^ ) ( NSUInteger bytesRead , long long totalBytesRead , long long totalBytesExpectedToRead ) ) block ;
2012-07-18 12:17:55 -07:00
///-------------------------------------------------
/// @name Setting NSURLConnection Delegate Callbacks
///-------------------------------------------------
/**
2013-09-25 17:43:00 -07:00
Sets a block to be executed when the connection will authenticate a challenge in order to download its request , as handled by the ` NSURLConnectionDelegate ` method ` connection : willSendRequestForAuthenticationChallenge : ` .
2015-09-18 15:02:15 -07:00
2013-09-25 17:43:00 -07:00
@ param block A block object to be executed when the connection will authenticate a challenge in order to download its request . The block has no return type and takes two arguments : the URL connection object , and the challenge that must be authenticated . This block must invoke one of the challenge - responder methods ( NSURLAuthenticationChallengeSender protocol ) .
2015-09-18 15:02:15 -07:00
2013-09-25 17:43:00 -07:00
If ` allowsInvalidSSLCertificate ` is set to YES , ` connection : willSendRequestForAuthenticationChallenge : ` will attempt to have the challenge sender use credentials with invalid SSL certificates .
2012-07-18 12:17:55 -07:00
*/
2015-09-18 15:02:15 -07:00
- ( void ) setWillSendRequestForAuthenticationChallengeBlock : ( nullable void ( ^ ) ( NSURLConnection * connection , NSURLAuthenticationChallenge * challenge ) ) block ;
2012-07-18 12:17:55 -07:00
/**
2015-09-18 15:02:15 -07:00
Sets a block to be executed when the server redirects the request from one URL to another URL , or when the request URL changed by the ` NSURLProtocol ` subclass handling the request in order to standardize its format , as handled by the ` NSURLConnectionDataDelegate ` method ` connection : willSendRequest : redirectResponse : ` .
2013-09-25 17:43:00 -07:00
2012-07-18 12:17:55 -07:00
@ param block A block object to be executed when the request URL was changed . The block returns an ` NSURLRequest ` object , the URL request to redirect , and takes three arguments : the URL connection object , the the proposed redirected request , and the URL response that caused the redirect .
*/
2015-09-18 15:02:15 -07:00
- ( void ) setRedirectResponseBlock : ( nullable NSURLRequest * ( ^ ) ( NSURLConnection * connection , NSURLRequest * request , NSURLResponse * redirectResponse ) ) block ;
2012-07-18 12:17:55 -07:00
/**
Sets a block to be executed to modify the response a connection will cache , if any , as handled by the ` NSURLConnectionDelegate ` method ` connection : willCacheResponse : ` .
2013-09-25 17:43:00 -07:00
2012-07-18 12:17:55 -07:00
@ param block A block object to be executed to determine what response a connection will cache , if any . The block returns an ` NSCachedURLResponse ` object , the cached response to store in memory or ` nil ` to prevent the response from being cached , and takes two arguments : the URL connection object , and the cached response provided for the request .
*/
2015-09-18 15:02:15 -07:00
- ( void ) setCacheResponseBlock : ( nullable NSCachedURLResponse * ( ^ ) ( NSURLConnection * connection , NSCachedURLResponse * cachedResponse ) ) block ;
2012-07-18 12:17:55 -07:00
2015-09-18 15:02:15 -07:00
///
2013-09-25 17:43:00 -07:00
/**
*/
2015-09-18 15:02:15 -07:00
+ ( NSArray * ) batchOfRequestOperations : ( nullable NSArray * ) operations
progressBlock : ( nullable void ( ^ ) ( NSUInteger numberOfFinishedOperations , NSUInteger totalNumberOfOperations ) ) progressBlock
completionBlock : ( nullable void ( ^ ) ( NSArray * operations ) ) completionBlock ;
@ end
2013-09-25 17:43:00 -07:00
///--------------------
/// @name Notifications
///--------------------
/**
Posted when an operation begins executing .
*/
extern NSString * const AFNetworkingOperationDidStartNotification ;
/**
Posted when an operation finishes .
*/
extern NSString * const AFNetworkingOperationDidFinishNotification ;
2015-09-18 15:02:15 -07:00
NS_ASSUME_NONNULL_END