diff --git a/AFNetworking.podspec b/AFNetworking.podspec index 8a87e42134..66ae38be76 100644 --- a/AFNetworking.podspec +++ b/AFNetworking.podspec @@ -64,8 +64,8 @@ EOS ss.tvos.dependency 'AFNetworking/Reachability' ss.dependency 'AFNetworking/Security' - ss.source_files = 'AFNetworking/AF{URL,HTTP}SessionManager.{h,m}' - ss.public_header_files = 'AFNetworking/AF{URL,HTTP}SessionManager.h' + ss.source_files = 'AFNetworking/AF{URL,HTTP,HTTPOperation}SessionManager.{h,m}' + ss.public_header_files = 'AFNetworking/AF{URL,HTTP,HTTPOperation}SessionManager.h' end s.subspec 'UIKit' do |ss| diff --git a/AFNetworking.xcodeproj/project.pbxproj b/AFNetworking.xcodeproj/project.pbxproj index b04cb4e2b6..c90850e713 100644 --- a/AFNetworking.xcodeproj/project.pbxproj +++ b/AFNetworking.xcodeproj/project.pbxproj @@ -7,6 +7,14 @@ objects = { /* Begin PBXBuildFile section */ + 1B7822B21D6644ED00799188 /* AFHTTPOperationSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B7822B01D6644ED00799188 /* AFHTTPOperationSessionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1B7822B31D6644ED00799188 /* AFHTTPOperationSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B7822B11D6644ED00799188 /* AFHTTPOperationSessionManager.m */; }; + 1B7822B41D66488B00799188 /* AFHTTPOperationSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B7822B01D6644ED00799188 /* AFHTTPOperationSessionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1B7822B51D66488C00799188 /* AFHTTPOperationSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B7822B01D6644ED00799188 /* AFHTTPOperationSessionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1B7822B61D66488D00799188 /* AFHTTPOperationSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B7822B01D6644ED00799188 /* AFHTTPOperationSessionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1B7822B71D6648A800799188 /* AFHTTPOperationSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B7822B11D6644ED00799188 /* AFHTTPOperationSessionManager.m */; }; + 1B7822B81D6648A900799188 /* AFHTTPOperationSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B7822B11D6644ED00799188 /* AFHTTPOperationSessionManager.m */; }; + 1B7822B91D6648A900799188 /* AFHTTPOperationSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B7822B11D6644ED00799188 /* AFHTTPOperationSessionManager.m */; }; 1BF9F9601C87832B00F1F35A /* AFImageResponseSerializerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BF9F95F1C87832B00F1F35A /* AFImageResponseSerializerTests.m */; }; 1BF9F9611C87843200F1F35A /* AFImageResponseSerializerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BF9F95F1C87832B00F1F35A /* AFImageResponseSerializerTests.m */; }; 1BF9F9621C87843300F1F35A /* AFImageResponseSerializerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BF9F95F1C87832B00F1F35A /* AFImageResponseSerializerTests.m */; }; @@ -224,6 +232,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 1B7822B01D6644ED00799188 /* AFHTTPOperationSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPOperationSessionManager.h; sourceTree = ""; }; + 1B7822B11D6644ED00799188 /* AFHTTPOperationSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPOperationSessionManager.m; sourceTree = ""; }; 1BF9F95F1C87832B00F1F35A /* AFImageResponseSerializerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFImageResponseSerializerTests.m; sourceTree = ""; }; 1FE783001C58579D00A73B7C /* httpbinorg_01192017.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = httpbinorg_01192017.cer; sourceTree = ""; }; 2960BAC21C1B2F1A00BA02F0 /* AFUIButtonTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFUIButtonTests.m; sourceTree = ""; }; @@ -503,6 +513,8 @@ children = ( 299522461BBF125A00859F49 /* AFHTTPSessionManager.h */, 299522471BBF125A00859F49 /* AFHTTPSessionManager.m */, + 1B7822B01D6644ED00799188 /* AFHTTPOperationSessionManager.h */, + 1B7822B11D6644ED00799188 /* AFHTTPOperationSessionManager.m */, 299522491BBF125A00859F49 /* AFNetworkReachabilityManager.h */, 2995224A1BBF125A00859F49 /* AFNetworkReachabilityManager.m */, 2995224B1BBF125A00859F49 /* AFSecurityPolicy.h */, @@ -579,6 +591,7 @@ 29D96E991BCC406B00F571A5 /* UIImageView+AFNetworking.h in Headers */, 29D96E9A1BCC406B00F571A5 /* UIProgressView+AFNetworking.h in Headers */, 29D96E8E1BCC3D7D00F571A5 /* AFNetworking.h in Headers */, + 1B7822B61D66488D00799188 /* AFHTTPOperationSessionManager.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -600,6 +613,7 @@ 2995223D1BBF104D00859F49 /* AFNetworking.h in Headers */, 299522B01BBF13C700859F49 /* UIWebView+AFNetworking.h in Headers */, 299522AC1BBF13C700859F49 /* UIProgressView+AFNetworking.h in Headers */, + 1B7822B21D6644ED00799188 /* AFHTTPOperationSessionManager.h in Headers */, 299522A61BBF13C700859F49 /* UIButton+AFNetworking.h in Headers */, 299522A01BBF13C700859F49 /* AFNetworkActivityIndicatorManager.h in Headers */, 299522AE1BBF13C700859F49 /* UIRefreshControl+AFNetworking.h in Headers */, @@ -610,6 +624,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 1B7822B41D66488B00799188 /* AFHTTPOperationSessionManager.h in Headers */, 29D96E7A1BCC3D6000F571A5 /* AFHTTPSessionManager.h in Headers */, 29D96E7C1BCC3D6000F571A5 /* AFSecurityPolicy.h in Headers */, 29D96E7D1BCC3D6000F571A5 /* AFURLRequestSerialization.h in Headers */, @@ -627,6 +642,7 @@ 29D96E821BCC3D7200F571A5 /* AFNetworkReachabilityManager.h in Headers */, 29D96E831BCC3D7200F571A5 /* AFSecurityPolicy.h in Headers */, 29D96E841BCC3D7200F571A5 /* AFURLRequestSerialization.h in Headers */, + 1B7822B51D66488C00799188 /* AFHTTPOperationSessionManager.h in Headers */, 29D96E851BCC3D7200F571A5 /* AFURLResponseSerialization.h in Headers */, 29D96E861BCC3D7200F571A5 /* AFURLSessionManager.h in Headers */, 29D96E871BCC3D7200F571A5 /* AFNetworking.h in Headers */, @@ -937,6 +953,7 @@ 2987B0BD1BC408D900179A4C /* AFNetworkReachabilityManager.m in Sources */, 2987B0BE1BC408D900179A4C /* AFSecurityPolicy.m in Sources */, 2987B0BC1BC408D900179A4C /* AFHTTPSessionManager.m in Sources */, + 1B7822B91D6648A900799188 /* AFHTTPOperationSessionManager.m in Sources */, 2987B0C11BC408D900179A4C /* AFURLSessionManager.m in Sources */, 2987B0C71BC408F900179A4C /* UIProgressView+AFNetworking.m in Sources */, 2987B0BF1BC408D900179A4C /* AFURLRequestSerialization.m in Sources */, @@ -1020,6 +1037,7 @@ buildActionMask = 2147483647; files = ( 299522AD1BBF13C700859F49 /* UIProgressView+AFNetworking.m in Sources */, + 1B7822B31D6644ED00799188 /* AFHTTPOperationSessionManager.m in Sources */, 299522571BBF125A00859F49 /* AFNetworkReachabilityManager.m in Sources */, 299522AF1BBF13C700859F49 /* UIRefreshControl+AFNetworking.m in Sources */, 299522AA1BBF13C700859F49 /* UIImageView+AFNetworking.m in Sources */, @@ -1046,6 +1064,7 @@ 2995226E1BBF133400859F49 /* AFSecurityPolicy.m in Sources */, 299522701BBF133400859F49 /* AFURLResponseSerialization.m in Sources */, 2995226D1BBF133400859F49 /* AFHTTPSessionManager.m in Sources */, + 1B7822B71D6648A800799188 /* AFHTTPOperationSessionManager.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1054,6 +1073,7 @@ buildActionMask = 2147483647; files = ( 299522801BBF13A100859F49 /* AFNetworkReachabilityManager.m in Sources */, + 1B7822B81D6648A900799188 /* AFHTTPOperationSessionManager.m in Sources */, 299522811BBF13A100859F49 /* AFSecurityPolicy.m in Sources */, 2995227F1BBF13A100859F49 /* AFHTTPSessionManager.m in Sources */, 299522841BBF13A100859F49 /* AFURLSessionManager.m in Sources */, diff --git a/AFNetworking/AFHTTPOperationSessionManager.h b/AFNetworking/AFHTTPOperationSessionManager.h new file mode 100644 index 0000000000..2811c98d49 --- /dev/null +++ b/AFNetworking/AFHTTPOperationSessionManager.h @@ -0,0 +1,227 @@ +// AFHTTPOperationSessionManager.h +// Copyright (c) 2016 Leszek S +// +// 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: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// 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 "AFHTTPSessionManager.h" + +/** + `AFHTTPOperationSessionManager` is a subclass of `AFHTTPSessionManager` with convenience methods for making HTTP requests. Requests are scheduled and run on NSOperationQueue requestsOperationQueue. + */ + +NS_ASSUME_NONNULL_BEGIN + +@interface AFHTTPOperationSessionManager : AFHTTPSessionManager + +/** + The operation queue on which request operations are scheduled and run. + */ +@property (readonly, nonatomic, strong) NSOperationQueue *requestsOperationQueue; + +/** + Creates and runs an `NSOperation` with a `GET` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (nullable NSOperation *)GET:(NSString *)URLString + parameters:(nullable id)parameters + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE; + +/** + Creates and runs an `NSOperation` with a `GET` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param downloadProgress A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: + */ +- (nullable NSOperation *)GET:(NSString *)URLString + parameters:(nullable id)parameters + progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; + +/** + Creates and runs an `NSOperation` with a `HEAD` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes a single arguments: the data task. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (nullable NSOperation *)HEAD:(NSString *)URLString + parameters:(nullable id)parameters + success:(nullable void (^)(NSURLSessionDataTask *task))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; + +/** + Creates and runs an `NSOperation` with a `POST` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (nullable NSOperation *)POST:(NSString *)URLString + parameters:(nullable id)parameters + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE; + +/** + Creates and runs an `NSOperation` with a `POST` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: + */ +- (nullable NSOperation *)POST:(NSString *)URLString + parameters:(nullable id)parameters + progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; + +/** + Creates and runs an `NSOperation` with a multipart `POST` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (nullable NSOperation *)POST:(NSString *)URLString + parameters:(nullable id)parameters + constructingBodyWithBlock:(nullable void (^)(id formData))block + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE; + +/** + Creates and runs an `NSOperation` with a multipart `POST` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. + @param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: + */ +- (nullable NSOperation *)POST:(NSString *)URLString + parameters:(nullable id)parameters + constructingBodyWithBlock:(nullable void (^)(id formData))block + progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; + +/** + Creates and runs an `NSOperation` with a `PUT` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (nullable NSOperation *)PUT:(NSString *)URLString + parameters:(nullable id)parameters + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; + +/** + Creates and runs an `NSOperation` with a `PATCH` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (nullable NSOperation *)PATCH:(NSString *)URLString + parameters:(nullable id)parameters + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; + +/** + Creates and runs an `NSOperation` with a `DELETE` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (nullable NSOperation *)DELETE:(NSString *)URLString + parameters:(nullable id)parameters + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; + +/** + Creates and runs an `NSOperation` with a `downloadTaskWithRequest` request. + + @param request The HTTP request for the request. + @param downloadProgressBlock A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue. + @param destination A block object to be executed in order to determine the destination of the downloaded file. This block takes two arguments, the target path & the server response, and returns the desired file URL of the resulting download. The temporary file used during the download will be automatically deleted after being moved to the returned URL. + @param completionHandler A block to be executed when a task finishes. This block has no return value and takes three arguments: the server response, the path of the downloaded file, and the error describing the network or parsing error that occurred, if any. + + @see -downloadTaskWithRequest:progress:destination:completionHandler: + */ +- (nullable NSOperation *)downloadOperationWithRequest:(NSURLRequest *)request + progress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock + destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination + completionHandler:(nullable void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler; + +/** + Creates and runs an `NSOperation` with a `dataTaskWithRequest` request. + + @param request The HTTP request for the request. + @param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. + @param downloadProgressBlock A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue. + @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. + */ +- (nullable NSOperation *)dataOperationWithRequest:(NSURLRequest *)request + uploadProgress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock + downloadProgress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock + completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/AFNetworking/AFHTTPOperationSessionManager.m b/AFNetworking/AFHTTPOperationSessionManager.m new file mode 100644 index 0000000000..28abe9b78b --- /dev/null +++ b/AFNetworking/AFHTTPOperationSessionManager.m @@ -0,0 +1,308 @@ +// AFHTTPOperationSessionManager.m +// Copyright (c) 2016 Leszek S +// +// 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: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// 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 "AFHTTPOperationSessionManager.h" + +@interface AFHTTPOperationSessionManager () +@property (readwrite, nonatomic, strong) NSOperationQueue *requestsOperationQueue; +@end + +@implementation AFHTTPOperationSessionManager + +- (instancetype)initWithBaseURL:(NSURL *)url + sessionConfiguration:(NSURLSessionConfiguration *)configuration +{ + self = [super initWithBaseURL:url sessionConfiguration:configuration]; + + if (!self) { + return nil; + } + + self.requestsOperationQueue = [[NSOperationQueue alloc] init]; + self.requestsOperationQueue.maxConcurrentOperationCount = 4; + + return self; +} + +- (nullable NSOperation *)GET:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure +{ + return [self GET:URLString parameters:parameters progress:nil success:success failure:failure]; +} + +- (nullable NSOperation *)GET:(NSString *)URLString + parameters:(id)parameters + progress:(void (^)(NSProgress * _Nonnull))downloadProgress + success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success + failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure +{ + NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ + dispatch_group_t dispatchGroup = dispatch_group_create(); + dispatch_group_enter(dispatchGroup); + [super GET:URLString parameters:parameters progress:downloadProgress success:^(NSURLSessionDataTask *task, id responseObject) { + if (success) { + success(task, responseObject); + } + dispatch_group_leave(dispatchGroup); + } failure:^(NSURLSessionDataTask *task, NSError *error) { + if (failure) { + failure(task, error); + } + dispatch_group_leave(dispatchGroup); + }]; + dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER); + }]; + + [self.requestsOperationQueue addOperation:operation]; + + return operation; +} + +- (nullable NSOperation *)HEAD:(NSString *)URLString + parameters:(nullable id)parameters + success:(nullable void (^)(NSURLSessionDataTask *task))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure +{ + NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ + dispatch_group_t dispatchGroup = dispatch_group_create(); + dispatch_group_enter(dispatchGroup); + [super HEAD:URLString parameters:parameters success:^(NSURLSessionDataTask *task) { + if (success) { + success(task); + } + dispatch_group_leave(dispatchGroup); + } failure:^(NSURLSessionDataTask *task, NSError *error) { + if (failure) { + failure(task, error); + } + dispatch_group_leave(dispatchGroup); + }]; + dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER); + }]; + + [self.requestsOperationQueue addOperation:operation]; + + return operation; +} + +- (nullable NSOperation *)POST:(NSString *)URLString + parameters:(nullable id)parameters + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE +{ + return [self POST:URLString parameters:parameters progress:nil success:success failure:failure]; +} + +- (nullable NSOperation *)POST:(NSString *)URLString + parameters:(nullable id)parameters + progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure +{ + NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ + dispatch_group_t dispatchGroup = dispatch_group_create(); + dispatch_group_enter(dispatchGroup); + [super POST:URLString parameters:parameters progress:uploadProgress success:^(NSURLSessionDataTask *task, id responseObject) { + if (success) { + success(task, responseObject); + } + dispatch_group_leave(dispatchGroup); + } failure:^(NSURLSessionDataTask *task, NSError *error) { + if (failure) { + failure(task, error); + } + dispatch_group_leave(dispatchGroup); + }]; + dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER); + }]; + + [self.requestsOperationQueue addOperation:operation]; + + return operation; +} + +- (nullable NSOperation *)POST:(NSString *)URLString + parameters:(nullable id)parameters + constructingBodyWithBlock:(nullable void (^)(id formData))block + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE +{ + return [self POST:URLString parameters:parameters constructingBodyWithBlock:block progress:nil success:success failure:failure]; +} + +- (nullable NSOperation *)POST:(NSString *)URLString + parameters:(nullable id)parameters + constructingBodyWithBlock:(nullable void (^)(id formData))block + progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure +{ + NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ + dispatch_group_t dispatchGroup = dispatch_group_create(); + dispatch_group_enter(dispatchGroup); + [super POST:URLString parameters:parameters constructingBodyWithBlock:block progress:uploadProgress success:^(NSURLSessionDataTask *task, id responseObject) { + if (success) { + success(task, responseObject); + } + dispatch_group_leave(dispatchGroup); + } failure:^(NSURLSessionDataTask *task, NSError *error) { + if (failure) { + failure(task, error); + } + dispatch_group_leave(dispatchGroup); + }]; + dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER); + }]; + + [self.requestsOperationQueue addOperation:operation]; + + return operation; +} + +- (nullable NSOperation *)PUT:(NSString *)URLString + parameters:(nullable id)parameters + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure +{ + NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ + dispatch_group_t dispatchGroup = dispatch_group_create(); + dispatch_group_enter(dispatchGroup); + [super PUT:URLString parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) { + if (success) { + success(task, responseObject); + } + dispatch_group_leave(dispatchGroup); + } failure:^(NSURLSessionDataTask *task, NSError *error) { + if (failure) { + failure(task, error); + } + dispatch_group_leave(dispatchGroup); + }]; + dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER); + }]; + + [self.requestsOperationQueue addOperation:operation]; + + return operation; +} + +- (nullable NSOperation *)PATCH:(NSString *)URLString + parameters:(nullable id)parameters + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure +{ + NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ + dispatch_group_t dispatchGroup = dispatch_group_create(); + dispatch_group_enter(dispatchGroup); + [super PATCH:URLString parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) { + if (success) { + success(task, responseObject); + } + dispatch_group_leave(dispatchGroup); + } failure:^(NSURLSessionDataTask *task, NSError *error) { + if (failure) { + failure(task, error); + } + dispatch_group_leave(dispatchGroup); + }]; + dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER); + }]; + + [self.requestsOperationQueue addOperation:operation]; + + return operation; +} + +- (nullable NSOperation *)DELETE:(NSString *)URLString + parameters:(nullable id)parameters + success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success + failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure +{ + NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ + dispatch_group_t dispatchGroup = dispatch_group_create(); + dispatch_group_enter(dispatchGroup); + [super DELETE:URLString parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) { + if (success) { + success(task, responseObject); + } + dispatch_group_leave(dispatchGroup); + } failure:^(NSURLSessionDataTask *task, NSError *error) { + if (failure) { + failure(task, error); + } + dispatch_group_leave(dispatchGroup); + }]; + dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER); + }]; + + [self.requestsOperationQueue addOperation:operation]; + + return operation; +} + +- (nullable NSOperation *)downloadOperationWithRequest:(NSURLRequest *)request + progress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock + destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination + completionHandler:(nullable void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler +{ + NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ + dispatch_group_t dispatchGroup = dispatch_group_create(); + dispatch_group_enter(dispatchGroup); + [[super downloadTaskWithRequest:request progress:downloadProgressBlock destination:destination + completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { + dispatch_group_leave(dispatchGroup); + if (completionHandler) { + completionHandler(response, filePath, error); + } + }] resume]; + dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER); + }]; + + [self.requestsOperationQueue addOperation:operation]; + + return operation; +} + +- (nullable NSOperation *)dataOperationWithRequest:(NSURLRequest *)request + uploadProgress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock + downloadProgress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock + completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler +{ + NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ + dispatch_group_t dispatchGroup = dispatch_group_create(); + dispatch_group_enter(dispatchGroup); + [[super dataTaskWithRequest:request uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { + dispatch_group_leave(dispatchGroup); + if (completionHandler) { + completionHandler(response, responseObject, error); + } + }] resume]; + dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER); + }]; + + [self.requestsOperationQueue addOperation:operation]; + + return operation; +} + +@end diff --git a/AFNetworking/AFNetworking.h b/AFNetworking/AFNetworking.h index e2fb2f44e6..29db42a748 100644 --- a/AFNetworking/AFNetworking.h +++ b/AFNetworking/AFNetworking.h @@ -37,5 +37,6 @@ #import "AFURLSessionManager.h" #import "AFHTTPSessionManager.h" + #import "AFHTTPOperationSessionManager.h" #endif /* _AFNETWORKING_ */ diff --git a/AFNetworking/AFURLRequestSerialization.m b/AFNetworking/AFURLRequestSerialization.m index 6ce24fafdd..f7fffb69db 100644 --- a/AFNetworking/AFURLRequestSerialization.m +++ b/AFNetworking/AFURLRequestSerialization.m @@ -592,7 +592,7 @@ - (instancetype)copyWithZone:(NSZone *)zone { #pragma mark - static NSString * AFCreateMultipartFormBoundary() { - return [NSString stringWithFormat:@"Boundary+%08X%08X", arc4random(), arc4random()]; + return [NSString stringWithFormat:@"Boundary%08X%08X", arc4random(), arc4random()]; } static NSString * const kAFMultipartFormCRLF = @"\r\n"; diff --git a/Framework/AFNetworking.h b/Framework/AFNetworking.h index 468fd72d8e..291c098e6b 100644 --- a/Framework/AFNetworking.h +++ b/Framework/AFNetworking.h @@ -45,6 +45,7 @@ FOUNDATION_EXPORT const unsigned char AFNetworkingVersionString[]; #import #import +#import #if TARGET_OS_IOS || TARGET_OS_TV #import