diff --git a/Framework/ROADCore/ROADCore.xcodeproj/project.pbxproj b/Framework/ROADCore/ROADCore.xcodeproj/project.pbxproj index 1b37fbc2..fce02bb9 100644 --- a/Framework/ROADCore/ROADCore.xcodeproj/project.pbxproj +++ b/Framework/ROADCore/ROADCore.xcodeproj/project.pbxproj @@ -22,6 +22,8 @@ /* Begin PBXBuildFile section */ 1176413D18E4700500B1688B /* libUtilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1176413C18E4700500B1688B /* libUtilities.a */; }; + 117BD9231997A84E001CA6C5 /* NSArray+RFClassSearch.m in Sources */ = {isa = PBXBuildFile; fileRef = 117BD9221997A84E001CA6C5 /* NSArray+RFClassSearch.m */; }; + 117BD9241997B248001CA6C5 /* NSArray+RFClassSearch.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 117BD9211997A84E001CA6C5 /* NSArray+RFClassSearch.h */; }; 46AA65574E8B424882F7485B /* ROADGeneratedAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = E9BC2CF400F040A48EDF4B23 /* ROADGeneratedAttribute.m */; }; 5BA3059C198FC1AB00F02E46 /* RFStringFormatterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BA3059B198FC1AB00F02E46 /* RFStringFormatterTests.m */; }; 78180F0816C3D0A300B4AA31 /* ROADCore.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 78B8E72216C3CD4A0049E36B /* ROADCore.h */; }; @@ -63,6 +65,7 @@ dstPath = include/ROAD; dstSubfolderSpec = 16; files = ( + 117BD9241997B248001CA6C5 /* NSArray+RFClassSearch.h in CopyFiles */, 83E0CDE918D0833900B25689 /* RFLog.h in CopyFiles */, 78180F0816C3D0A300B4AA31 /* ROADCore.h in CopyFiles */, 78180F0916C3D0A800B4AA31 /* NSArray+RFEmptyArrayChecks.h in CopyFiles */, @@ -79,6 +82,8 @@ /* Begin PBXFileReference section */ 1176413618E4635400B1688B /* libUtilities.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libUtilities.a; path = "../Utilities/build/Debug-iphoneos/libUtilities.a"; sourceTree = ""; }; 1176413C18E4700500B1688B /* libUtilities.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libUtilities.a; path = "../Utilities/build/Debug-iphoneos/libUtilities.a"; sourceTree = ""; }; + 117BD9211997A84E001CA6C5 /* NSArray+RFClassSearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+RFClassSearch.h"; sourceTree = ""; }; + 117BD9221997A84E001CA6C5 /* NSArray+RFClassSearch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+RFClassSearch.m"; sourceTree = ""; }; 5BA3059B198FC1AB00F02E46 /* RFStringFormatterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RFStringFormatterTests.m; sourceTree = ""; }; 634461C3604B4DB58DF380FC /* Pods-ROADCore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ROADCore.xcconfig"; path = "../Pods/Pods-ROADCore.xcconfig"; sourceTree = ""; }; 78B8E68E16C3CC3E0049E36B /* libROADCore.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libROADCore.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -210,6 +215,8 @@ 78B8E70116C3CD320049E36B /* NSDictionary+RFKeyedSubscript.m */, 78B8E70216C3CD320049E36B /* NSMutableDictionary+RFKeyedSubscript.h */, 78B8E70316C3CD320049E36B /* NSMutableDictionary+RFKeyedSubscript.m */, + 117BD9211997A84E001CA6C5 /* NSArray+RFClassSearch.h */, + 117BD9221997A84E001CA6C5 /* NSArray+RFClassSearch.m */, ); name = CollectionCategories; sourceTree = ""; @@ -390,6 +397,7 @@ buildActionMask = 2147483647; files = ( 78B8E6DC16C3CCE60049E36B /* RFDynamicObject.m in Sources */, + 117BD9231997A84E001CA6C5 /* NSArray+RFClassSearch.m in Sources */, 78B8E6E016C3CCE60049E36B /* RFObjectPool.m in Sources */, 78B8E70716C3CD320049E36B /* NSArray+RFEmptyArrayChecks.m in Sources */, 78B8E71716C3CD320049E36B /* NSDictionary+RFKeyedSubscript.m in Sources */, diff --git a/Framework/ROADCore/ROADCore/Categories/NSArray+RFClassSearch.h b/Framework/ROADCore/ROADCore/Categories/NSArray+RFClassSearch.h new file mode 100644 index 00000000..40e8cbf7 --- /dev/null +++ b/Framework/ROADCore/ROADCore/Categories/NSArray+RFClassSearch.h @@ -0,0 +1,38 @@ +// +// NSArray+RFClassSearch.h +// ROADCore +// +// Copyright (c) 2014 EPAM Systems, Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// Redistributions in binary form must reproduce the above copyright notice, this +// list of conditions and the following disclaimer in the documentation and/or +// other materials provided with the distribution. +// Neither the name of the EPAM Systems, Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// See the NOTICE file and the LICENSE file distributed with this work +// for additional information regarding copyright ownership and licensing + + +@interface NSArray (RFClassSearch) + +- (id)RF_firstObjectWithClass:(__unsafe_unretained Class)objectClass; + +@end diff --git a/Framework/ROADCore/ROADCore/Categories/NSArray+RFClassSearch.m b/Framework/ROADCore/ROADCore/Categories/NSArray+RFClassSearch.m new file mode 100644 index 00000000..7897dbf6 --- /dev/null +++ b/Framework/ROADCore/ROADCore/Categories/NSArray+RFClassSearch.m @@ -0,0 +1,49 @@ +// +// NSArray+RFClassSearch.m +// ROADCore +// +// Copyright (c) 2014 EPAM Systems, Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// Redistributions in binary form must reproduce the above copyright notice, this +// list of conditions and the following disclaimer in the documentation and/or +// other materials provided with the distribution. +// Neither the name of the EPAM Systems, Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// See the NOTICE file and the LICENSE file distributed with this work +// for additional information regarding copyright ownership and licensing + + +#import "NSArray+RFClassSearch.h" + + +@implementation NSArray (RFClassSearch) + +- (id)RF_firstObjectWithClass:(__unsafe_unretained Class)objectClass { + for (id object in self) { + if ([object class] == objectClass) { + return object; + } + } + + return nil; +} + +@end diff --git a/Framework/ROADCore/ROADCore/ROADCore.h b/Framework/ROADCore/ROADCore/ROADCore.h index 51055dfb..f8ae1eb5 100644 --- a/Framework/ROADCore/ROADCore/ROADCore.h +++ b/Framework/ROADCore/ROADCore/ROADCore.h @@ -36,6 +36,7 @@ #import "NSMutableString+RFStringFormatter.h" #import "NSArray+RFEmptyArrayChecks.h" +#import "NSArray+RFClassSearch.h" #import "RFDynamicObject.h" #import "RFObjectPool.h" diff --git a/Framework/ROADWebService/ROADWebService.xcodeproj/project.pbxproj b/Framework/ROADWebService/ROADWebService.xcodeproj/project.pbxproj index e3ba3299..e71b0266 100644 --- a/Framework/ROADWebService/ROADWebService.xcodeproj/project.pbxproj +++ b/Framework/ROADWebService/ROADWebService.xcodeproj/project.pbxproj @@ -766,7 +766,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/libObjCAttr/tools/binaries/ROADAttributesCodeGenerator\" -src=\"${SRCROOT}\" -src=\"${PODS_ROOT}\" -dst=\"${SRCROOT}/${TARGET_NAME}/ROADGeneratedAttributes/\""; + shellScript = "\"${PODS_ROOT}/libObjCAttr/tools/binaries/ROADAttributesCodeGenerator\" -src=\"${SRCROOT}\" -dst=\"${SRCROOT}/${TARGET_NAME}/ROADGeneratedAttributes/\""; }; /* End PBXShellScriptBuildPhase section */ diff --git a/Framework/ROADWebService/ROADWebService/Private/Downloader/RFDownloader+ConnectionDelegate.m b/Framework/ROADWebService/ROADWebService/Private/Downloader/RFDownloader+ConnectionDelegate.m index e3e2fabe..13cd36c4 100644 --- a/Framework/ROADWebService/ROADWebService/Private/Downloader/RFDownloader+ConnectionDelegate.m +++ b/Framework/ROADWebService/ROADWebService/Private/Downloader/RFDownloader+ConnectionDelegate.m @@ -32,6 +32,7 @@ #import "RFDownloader+ConnectionDelegate.h" +#import #import "RFWebServiceLog.h" #import "NSError+RFWebService.h" @@ -88,7 +89,7 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)aConnection { // Checking response with error handler RFWebServiceErrorHandler *errorHandlerAttribute = [[self.webServiceClient class] RF_attributeForClassWithAttributeType:[RFWebServiceErrorHandler class]]; if (!errorHandlerAttribute) { - errorHandlerAttribute = [[self.webServiceClient class] RF_attributeForMethod:self.methodName withAttributeType:[RFWebServiceErrorHandler class]]; + errorHandlerAttribute = [self.attributes RF_firstObjectWithClass:[RFWebServiceErrorHandler class]]; } if (errorHandlerAttribute.handlerClass) { diff --git a/Framework/ROADWebService/ROADWebService/Private/Downloader/RFDownloader.h b/Framework/ROADWebService/ROADWebService/Private/Downloader/RFDownloader.h index 41b43ba0..aad06588 100644 --- a/Framework/ROADWebService/ROADWebService/Private/Downloader/RFDownloader.h +++ b/Framework/ROADWebService/ROADWebService/Private/Downloader/RFDownloader.h @@ -49,10 +49,16 @@ */ @property (assign, nonatomic, getter = isMultipartData) BOOL multipartData; +/** + * Web service client responsible for performing request. + */ @property (nonatomic, strong, readonly) RFWebServiceClient *webServiceClient; -@property (nonatomic, strong, readonly) NSString *methodName; /** - The serialized data from the request, + * Web service call attributes. + */ +@property (nonatomic, copy, readonly) NSArray *attributes; +/** + The serialized data from the request. */ @property (strong, nonatomic) id serializedData; /** @@ -68,7 +74,7 @@ */ @property (atomic, assign, readonly, getter = isRequestCancelled) BOOL requestCancelled; -- (id)initWithClient:(RFWebServiceClient *)webServiceClient methodName:(NSString *)methodName authenticationProvider:(id)authenticaitonProvider; +- (id)initWithClient:(RFWebServiceClient *)client attributes:(NSArray *)attributes authenticationProvider:(id)authenticationProvider; - (void)configureRequestForUrl:(NSURL * const)anUrl body:(NSData *)httpBody sharedHeaders:(NSDictionary *)sharedHeaders values:(NSDictionary *)values; diff --git a/Framework/ROADWebService/ROADWebService/Private/Downloader/RFDownloader.m b/Framework/ROADWebService/ROADWebService/Private/Downloader/RFDownloader.m index 2d640eaf..88c7d74d 100644 --- a/Framework/ROADWebService/ROADWebService/Private/Downloader/RFDownloader.m +++ b/Framework/ROADWebService/ROADWebService/Private/Downloader/RFDownloader.m @@ -73,15 +73,15 @@ - (void)stop; @implementation RFDownloader -- (id)initWithClient:(RFWebServiceClient *)webServiceClient methodName:(NSString *)methodName authenticationProvider:(id)authenticaitonProvider { +- (id)initWithClient:(RFWebServiceClient *)client attributes:(NSArray *)attributes authenticationProvider:(id)authenticationProvider { self = [super init]; if (self) { - _webServiceClient = webServiceClient; - _methodName = methodName; - _authenticationProvider = authenticaitonProvider; + _webServiceClient = client; + _attributes = attributes; + _authenticationProvider = authenticationProvider; _successCodes = [NSMutableArray arrayWithObjects:[NSValue valueWithRange:NSMakeRange(200, 100)], nil]; - _callAttribute = [[_webServiceClient class] RF_attributeForMethod:_methodName withAttributeType:[RFWebServiceCall class]]; + _callAttribute = [attributes RF_firstObjectWithClass:[RFWebServiceCall class]]; } return self; @@ -100,7 +100,7 @@ - (void)configureRequestForUrl:(NSURL * const)anUrl body:(NSData * const)httpBod // For multipart form data we have to add specific header if (_multipartData) { NSString *boundary; - RFMultipartData *multipartDataAttribute = [[_webServiceClient class] RF_attributeForMethod:_methodName withAttributeType:[RFMultipartData class]]; + RFMultipartData *multipartDataAttribute = [self.attributes RF_firstObjectWithClass:[RFMultipartData class]]; boundary = multipartDataAttribute.boundary; if (!boundary.length) { // Some random default boundary @@ -111,7 +111,7 @@ - (void)configureRequestForUrl:(NSURL * const)anUrl body:(NSData * const)httpBod [_request addValue:contentType forHTTPHeaderField:@"Content-Type"]; } - RFWebServiceHeader * const headerAttribute = [[_webServiceClient class] RF_attributeForMethod:_methodName withAttributeType:[RFWebServiceHeader class]]; + RFWebServiceHeader * const headerAttribute = [self.attributes RF_firstObjectWithClass:[RFWebServiceHeader class]]; // Adding shared headers to request NSMutableDictionary *headerFields = [sharedHeaders mutableCopy]; @@ -128,7 +128,7 @@ - (void)configureRequestForUrl:(NSURL * const)anUrl body:(NSData * const)httpBod [self.successCodes removeAllObjects]; [self.successCodes addObjectsFromArray:_callAttribute.successCodes]; } else { - RFWebServiceClientStatusCodes* wsca = [[self.webServiceClient class] RF_attributeForClassWithAttributeType:[RFWebServiceClientStatusCodes class]]; + RFWebServiceClientStatusCodes* wsca = [self.attributes RF_firstObjectWithClass:[RFWebServiceClientStatusCodes class]]; if ([wsca.successCodes count] > 0) { [self.successCodes removeAllObjects]; @@ -143,10 +143,9 @@ - (void)checkCacheAndStart { return; } - RFWebServiceCache *cacheAttribute = [[_webServiceClient class] RF_attributeForMethod:_methodName withAttributeType:[RFWebServiceCache class]]; id cacheManager = [RFServiceProvider webServiceCacheManager]; RFWebResponse *cachedResponse; - if (!cacheAttribute.cacheDisabled) { + if (!self.cacheAttribute.cacheDisabled) { cachedResponse = [cacheManager cacheWithRequest:_request]; } @@ -168,8 +167,7 @@ - (void)start { _looper = [[RFLooper alloc] init]; _data = [NSMutableData data]; - RFWebServiceCall *callAttribute = [[_webServiceClient class] RF_attributeForMethod:_methodName withAttributeType:[RFWebServiceCall class]]; - if (!callAttribute.syncCall) { + if (!_callAttribute.syncCall) { _connection = [[NSURLConnection alloc] initWithRequest:_request delegate:self startImmediately:NO]; [_connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [_connection start]; @@ -237,7 +235,7 @@ - (void)downloaderFinishedWithResult:(NSData *)result response:(NSHTTPURLRespons } - (id)serializationDelegate { - RFWebServiceSerializer *serializerAttribute = [[self.webServiceClient class] RF_attributeForMethod:self.methodName withAttributeType:[RFWebServiceSerializer class]]; + RFWebServiceSerializer *serializerAttribute = [self.attributes RF_firstObjectWithClass:[RFWebServiceSerializer class]]; id serializationDelegate; if (serializerAttribute.serializerClass) { serializationDelegate = [[serializerAttribute.serializerClass alloc] init]; @@ -314,14 +312,24 @@ -(void)performSuccessBlockOnSpecificThread { if (self.successBlock) { self.successBlock(_serializedData); } + + [self freeCompletionBlocks]; } -(void)performFailureBlockOnSpecificThread { if (self.failureBlock) { self.failureBlock(_downloadError); } + + [self freeCompletionBlocks]; } +- (void)freeCompletionBlocks { + self.successBlock = nil; + self.failureBlock = nil; +} + + #pragma mark - Utitlity NSString * const RFAttributeTemplateEscape = @"%%"; @@ -377,7 +385,7 @@ - (void)cancelWithReason:(id)reason { - (RFWebServiceCache *)cacheAttribute { if (!_cacheAttribute) { - _cacheAttribute = [[_webServiceClient class] RF_attributeForMethod:_methodName withAttributeType:[RFWebServiceCache class]]; + _cacheAttribute = [self.attributes RF_firstObjectWithClass:[RFWebServiceCache class]]; } return _cacheAttribute; diff --git a/Framework/ROADWebService/ROADWebService/Webservice/Private/RFWebServiceCallParameterEncoder.h b/Framework/ROADWebService/ROADWebService/Webservice/Private/RFWebServiceCallParameterEncoder.h index 29a0d0c6..10d48b6e 100644 --- a/Framework/ROADWebService/ROADWebService/Webservice/Private/RFWebServiceCallParameterEncoder.h +++ b/Framework/ROADWebService/ROADWebService/Webservice/Private/RFWebServiceCallParameterEncoder.h @@ -39,18 +39,18 @@ static NSString * const kRFBoundaryDefaultString; /** - Parameter encoder to create parameters for the webservice. + *Parameter encoder to create parameters for the webservice. */ @interface RFWebServiceCallParameterEncoder : NSObject /** - It will create a parameter dictionary based on the parameter list array. If it needs to be serialized, the serializator object will be used. If one object is NSData, it will be sent back as a post data. - @param parameterList The list of parameters - @param webClient The web client which handle service request - @param methodName The method name is selector name which was invoked - @param serializator The serializator object - @param callbackBlock The callback block which will be called. + * It will create a parameter dictionary based on the parameter list array. + * If it needs to be serialized, the serializator object will be used. + * If one object is NSData, it will be sent back as a post data. + * @param parameterList The list of parameters + * @param attributes The attributes that determine current web service call + * @param serializator The serializator object + * @param callbackBlock The callback block which will be called. */ -+ (void)encodeParameters:(NSArray *)parameterList forClient:(RFWebServiceClient *)webClient methodName:(NSString *)methodName withSerializator:(id)serializator callbackBlock:(void(^)(NSDictionary *parameters, NSData *postData, BOOL isMultipartData))callbackBlock; - ++ (void)encodeParameters:(NSArray *)parameterList attributes:(NSArray *)attributes withSerializator:(id)serializator callbackBlock:(void(^)(NSDictionary *parameters, NSData *postData, BOOL isMultipartData))callbackBlock; @end diff --git a/Framework/ROADWebService/ROADWebService/Webservice/Private/RFWebServiceCallParameterEncoder.m b/Framework/ROADWebService/ROADWebService/Webservice/Private/RFWebServiceCallParameterEncoder.m index 7691c5c5..84110b51 100644 --- a/Framework/ROADWebService/ROADWebService/Webservice/Private/RFWebServiceCallParameterEncoder.m +++ b/Framework/ROADWebService/ROADWebService/Webservice/Private/RFWebServiceCallParameterEncoder.m @@ -32,6 +32,8 @@ #import "RFWebServiceCallParameterEncoder.h" +#import + #import "RFSerializationDelegate.h" #import "RFWebServiceURLBuilderParameter.h" #import "RFFormData.h" @@ -44,7 +46,7 @@ @implementation RFWebServiceCallParameterEncoder -+ (void)encodeParameters:(NSArray *)parameterList forClient:(RFWebServiceClient *)webClient methodName:(NSString *)methodName withSerializator:(id)serializator callbackBlock:(void(^)(NSDictionary *parameters, NSData *postData, BOOL isMultipartData))callbackBlock { ++ (void)encodeParameters:(NSArray *)parameterList attributes:(NSArray *)attributes withSerializator:(id)serializator callbackBlock:(void (^)(NSDictionary *, NSData *, BOOL))callbackBlock { NSMutableDictionary *result = [[NSMutableDictionary alloc] initWithCapacity:[parameterList count]]; NSMutableData *bodyData; @@ -75,7 +77,7 @@ + (void)encodeParameters:(NSArray *)parameterList forClient:(RFWebServiceClient bodyData = [[NSMutableData alloc] init]; } - boundary = [self boundaryFromWebServiceClient:webClient withMethodName:methodName]; + boundary = [self boundaryFromAttributes:attributes]; isMultipartData = YES; [self addAttachment:object toBodyData:bodyData boundary:boundary]; } @@ -88,7 +90,7 @@ + (void)encodeParameters:(NSArray *)parameterList forClient:(RFWebServiceClient bodyData = [[NSMutableData alloc] init]; } - boundary = [self boundaryFromWebServiceClient:webClient withMethodName:methodName]; + boundary = [self boundaryFromAttributes:attributes]; isMultipartData = YES; [self addAttachments:object toBodyData:bodyData boundary:boundary]; } @@ -139,8 +141,8 @@ + (void)addAttachment:(RFFormData *)attachment toBodyData:(NSMutableData *)bodyD [bodyData appendData:nextAttachment]; } -+ (NSString *)boundaryFromWebServiceClient:(id)webServiceClient withMethodName:(NSString *)methodName { - RFMultipartData *multipartDataAttribute = [[webServiceClient class] RF_attributeForMethod:methodName withAttributeType:[RFMultipartData class]]; ++ (NSString *)boundaryFromAttributes:(NSArray *)attributes { + RFMultipartData *multipartDataAttribute = [attributes RF_firstObjectWithClass:[RFMultipartData class]]; NSString *boundary; if (!multipartDataAttribute.boundary) { // Default boundary diff --git a/Framework/ROADWebService/ROADWebService/Webservice/Private/RFWebServiceClient+DynamicMethod.m b/Framework/ROADWebService/ROADWebService/Webservice/Private/RFWebServiceClient+DynamicMethod.m index b9ea3698..296791fc 100644 --- a/Framework/ROADWebService/ROADWebService/Webservice/Private/RFWebServiceClient+DynamicMethod.m +++ b/Framework/ROADWebService/ROADWebService/Webservice/Private/RFWebServiceClient+DynamicMethod.m @@ -31,9 +31,11 @@ // for additional information regarding copyright ownership and licensing +#import "RFWebServiceClient+DynamicMethod.h" #import +#import + #import "RFWebServiceCall.h" -#import "RFWebServiceClient+DynamicMethod.h" #import #import #import "RFWebServiceCancellable.h" @@ -124,15 +126,33 @@ - (void)dynamicWebServiceCallWithArguments:(NSMutableArray *)parameterList forIn success:(id)successBlock failure:(id)failureBlock { NSString *methodName = NSStringFromSelector(selector); + NSArray *attributes = [[self class] RF_attributesForMethod:methodName]; - __block RFDownloader *downloader = [[RFDownloader alloc] initWithClient:self methodName:methodName authenticationProvider:self.authenticationProvider]; + __block RFDownloader *downloader = [[RFDownloader alloc] initWithClient:self attributes:attributes authenticationProvider:self.authenticationProvider]; downloader.successBlock = successBlock; downloader.failureBlock = failureBlock; + RFWebServiceCall *callAttribute = [attributes RF_firstObjectWithClass:[RFWebServiceCall class]]; + if (callAttribute.syncCall) { + [self prepareRequestParameterForCallWithAttributes:attributes parameters:parameterList downloader:downloader prepareForSendRequestBlock:prepareToLoadBlock]; + } + else { + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); + dispatch_async(queue, ^{ + [self prepareRequestParameterForCallWithAttributes:attributes parameters:parameterList downloader:downloader prepareForSendRequestBlock:prepareToLoadBlock]; + }); + } + + + return downloader; +} + +- (void)prepareRequestParameterForCallWithAttributes:(NSArray *)attributes parameters:(NSArray *)parameterList downloader:(RFDownloader *)downloader prepareForSendRequestBlock:(RFWebServiceClientPrepareForSendRequestBlock)prepareForSendRequestBlock { + __block NSData *bodyData; __block NSDictionary *parametersDictionary; - RFWebServiceSerializer *serializerAttribute = [[self class] RF_attributeForMethod:methodName withAttributeType:[RFWebServiceSerializer class]]; + RFWebServiceSerializer *serializerAttribute = [attributes RF_firstObjectWithClass:[RFWebServiceSerializer class]]; id serializationDelegate; if (serializerAttribute.serializerClass) { serializationDelegate = [[serializerAttribute.serializerClass alloc] init]; @@ -141,43 +161,23 @@ - (void)dynamicWebServiceCallWithArguments:(NSMutableArray *)parameterList forIn serializationDelegate = self.serializationDelegate; } - [RFWebServiceCallParameterEncoder encodeParameters:parameterList forClient:self methodName:methodName withSerializator:serializationDelegate callbackBlock:^(NSDictionary *parameters, NSData *postData, BOOL isMultipartData) { + [RFWebServiceCallParameterEncoder encodeParameters:parameterList attributes:attributes withSerializator:serializationDelegate callbackBlock:^(NSDictionary *parameters, NSData *postData, BOOL isMultipartData) { parametersDictionary = parameters; bodyData = postData; downloader.multipartData = isMultipartData; }]; - RFWebServiceCall *callAttribute = [[self class] RF_attributeForMethod:methodName withAttributeType:[RFWebServiceCall class]]; - - dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); - - if (callAttribute.syncCall) { - dispatch_sync(queue, ^{ - [self performCall:selector values:parametersDictionary body:bodyData request:downloader processingQueue:queue prepareForSendRequestBlock:prepareToLoadBlock]; - }); - } - else { - dispatch_async(queue, ^{ - [self performCall:selector values:parametersDictionary body:bodyData request:downloader processingQueue:queue prepareForSendRequestBlock:prepareToLoadBlock]; - }); - } - - return downloader; + [self performCallWithAttributes:attributes values:parametersDictionary body:bodyData request:downloader prepareForSendRequestBlock:prepareForSendRequestBlock]; } -- (void)performCall:(SEL)selector +- (void)performCallWithAttributes:(NSArray *)attributes values:(NSDictionary *const)values body:(NSData *const)httpBody request:(RFDownloader *)downloader - processingQueue:(dispatch_queue_t)processingQueue prepareForSendRequestBlock:(RFWebServiceClientPrepareForSendRequestBlock)prepareForSendRequestBlock { - NSString *methodName = NSStringFromSelector(selector); - - RFWebServiceCall *callAttribute = [[self class] RF_attributeForMethod:methodName withAttributeType:[RFWebServiceCall class]]; - // Getting url parser from attribute or using default one - RFWebServiceURLBuilder *urlParserAttribute = [[self class] RF_attributeForMethod:methodName withAttributeType:[RFWebServiceURLBuilder class]]; + RFWebServiceURLBuilder *urlParserAttribute = [attributes RF_firstObjectWithClass:[RFWebServiceURLBuilder class]]; Class urlParserClass = urlParserAttribute.builderClass; if (urlParserClass == nil) { urlParserClass = [RFWebServiceBasicURLBuilder class]; @@ -185,6 +185,7 @@ - (void)performCall:(SEL)selector NSURL *apiUrl = nil; if ([urlParserClass conformsToProtocol:@protocol(RFWebServiceURLBuilding)]) { + RFWebServiceCall *callAttribute = [attributes RF_firstObjectWithClass:[RFWebServiceCall class]]; apiUrl = [urlParserClass urlFromTemplate:callAttribute.relativePath withServiceRoot:self.serviceRoot values:values urlBuilderAttribute:urlParserAttribute]; } @@ -192,7 +193,7 @@ - (void)performCall:(SEL)selector [downloader configureRequestForUrl:apiUrl body:httpBody sharedHeaders:self.sharedHeaders values:values]; // Pass the request and any attribute on the method to a request processor. - [self.requestProcessor processRequest:downloader.request attributesOnMethod:[[self class] RF_attributesForMethod:methodName]]; + [self.requestProcessor processRequest:downloader.request attributesOnMethod:attributes]; if (prepareForSendRequestBlock != nil) { prepareForSendRequestBlock(downloader.request);