From c63a33aa5cfe8d1d150672a2d17251dfa7cdc955 Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Fri, 6 Dec 2019 15:03:01 +0530 Subject: [PATCH 01/11] initial infrastructure changes for Cancel Implementation --- MASFoundation.xcodeproj/project.pbxproj | 16 ++ MASFoundation/Classes/MAS.h | 2 +- MASFoundation/Classes/MAS.m | 75 +++++++++ MASFoundation/Classes/MASConstants.h | 6 + MASFoundation/Classes/MASDataTask.h | 25 +++ MASFoundation/Classes/MASDataTask.m | 36 +++++ .../services/network/MASNetworkingService.h | 2 + .../services/network/MASNetworkingService.m | 153 +++++++++++++++++- .../network/internal/MASDataTask+MASPrivate.h | 25 +++ .../network/internal/MASDataTask+MASPrivate.m | 37 +++++ .../internal/MASSessionDataTaskOperation.h | 1 + .../internal/MASSessionDataTaskOperation.m | 2 + MASFoundation/MASFoundation.h | 1 + 13 files changed, 379 insertions(+), 2 deletions(-) create mode 100644 MASFoundation/Classes/MASDataTask.h create mode 100644 MASFoundation/Classes/MASDataTask.m create mode 100644 MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h create mode 100644 MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m diff --git a/MASFoundation.xcodeproj/project.pbxproj b/MASFoundation.xcodeproj/project.pbxproj index f77cc0e4..d245747e 100644 --- a/MASFoundation.xcodeproj/project.pbxproj +++ b/MASFoundation.xcodeproj/project.pbxproj @@ -187,6 +187,10 @@ C81CC3CD1FC2EA190058718E /* MASBrowserBasedAuthentication.m in Sources */ = {isa = PBXBuildFile; fileRef = C81CC3CB1FC2EA190058718E /* MASBrowserBasedAuthentication.m */; }; C81CC3D01FC2EFBB0058718E /* UIAlertController+MAS.h in Headers */ = {isa = PBXBuildFile; fileRef = C81CC3CE1FC2EFBB0058718E /* UIAlertController+MAS.h */; }; C81CC3D11FC2EFBB0058718E /* UIAlertController+MAS.m in Sources */ = {isa = PBXBuildFile; fileRef = C81CC3CF1FC2EFBB0058718E /* UIAlertController+MAS.m */; }; + C858D6B52398FC5400963763 /* MASDataTask+MASPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = C858D6B32398FC5400963763 /* MASDataTask+MASPrivate.h */; }; + C858D6B62398FC5400963763 /* MASDataTask+MASPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = C858D6B42398FC5400963763 /* MASDataTask+MASPrivate.m */; }; + C8B1700B238FD1A7007BB903 /* MASDataTask.h in Headers */ = {isa = PBXBuildFile; fileRef = C8B17009238FD1A7007BB903 /* MASDataTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C8B1700C238FD1A7007BB903 /* MASDataTask.m in Sources */ = {isa = PBXBuildFile; fileRef = C8B1700A238FD1A7007BB903 /* MASDataTask.m */; }; C8C32B0D22D706B900D64DF0 /* MASMultiPartFormData.h in Headers */ = {isa = PBXBuildFile; fileRef = C8C32B0C22D706B900D64DF0 /* MASMultiPartFormData.h */; settings = {ATTRIBUTES = (Public, ); }; }; C8C32B1022D7163100D64DF0 /* MASMultiPartRequestSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = C8C32B0E22D7163100D64DF0 /* MASMultiPartRequestSerializer.h */; }; C8C32B1122D7163100D64DF0 /* MASMultiPartRequestSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = C8C32B0F22D7163100D64DF0 /* MASMultiPartRequestSerializer.m */; }; @@ -569,6 +573,10 @@ C81CC3CB1FC2EA190058718E /* MASBrowserBasedAuthentication.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MASBrowserBasedAuthentication.m; sourceTree = ""; }; C81CC3CE1FC2EFBB0058718E /* UIAlertController+MAS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertController+MAS.h"; sourceTree = ""; }; C81CC3CF1FC2EFBB0058718E /* UIAlertController+MAS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertController+MAS.m"; sourceTree = ""; }; + C858D6B32398FC5400963763 /* MASDataTask+MASPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MASDataTask+MASPrivate.h"; sourceTree = ""; }; + C858D6B42398FC5400963763 /* MASDataTask+MASPrivate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "MASDataTask+MASPrivate.m"; sourceTree = ""; }; + C8B17009238FD1A7007BB903 /* MASDataTask.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MASDataTask.h; sourceTree = ""; }; + C8B1700A238FD1A7007BB903 /* MASDataTask.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MASDataTask.m; sourceTree = ""; }; C8C32B0C22D706B900D64DF0 /* MASMultiPartFormData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MASMultiPartFormData.h; sourceTree = ""; }; C8C32B0E22D7163100D64DF0 /* MASMultiPartRequestSerializer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MASMultiPartRequestSerializer.h; sourceTree = ""; }; C8C32B0F22D7163100D64DF0 /* MASMultiPartRequestSerializer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MASMultiPartRequestSerializer.m; sourceTree = ""; }; @@ -1112,6 +1120,8 @@ 699570E52062FF1300017244 /* MASError.m */, 699570E02060650400017244 /* MASNotifications.h */, 699570E12060650400017244 /* MASNotifications.m */, + C8B17009238FD1A7007BB903 /* MASDataTask.h */, + C8B1700A238FD1A7007BB903 /* MASDataTask.m */, 107389F21C7118F800B7E87E /* MQTT */, A419B39A1C17622E008DC88C /* categories */, A4831A9A1BD1A551007B4AE6 /* models */, @@ -1267,6 +1277,8 @@ CB3173DF1F1FFF2C00C85E47 /* MASNetworkMonitor.m */, CBBA9A7E20742BA800BB307F /* MASNetworkReachability.h */, CBBA9A7F20742BA800BB307F /* MASNetworkReachability.m */, + C858D6B32398FC5400963763 /* MASDataTask+MASPrivate.h */, + C858D6B42398FC5400963763 /* MASDataTask+MASPrivate.m */, ); path = internal; sourceTree = ""; @@ -1551,6 +1563,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + C8B1700B238FD1A7007BB903 /* MASDataTask.h in Headers */, C8C32B0D22D706B900D64DF0 /* MASMultiPartFormData.h in Headers */, CB2A4048209A341A00F988AA /* MASMultiFactorHandler.h in Headers */, CB1FD14B1FB23701000AFA25 /* MASSharedStorage.h in Headers */, @@ -1631,6 +1644,7 @@ A46F49D31C2F5FC500A4C370 /* MASIURLRequestSerialization.h in Headers */, A4831AB11BD1A551007B4AE6 /* MASFile.h in Headers */, 699570E22060650400017244 /* MASNotifications.h in Headers */, + C858D6B52398FC5400963763 /* MASDataTask+MASPrivate.h in Headers */, 1059D3761B61AA3800223267 /* MASFoundation.h in Headers */, A898EF6B2182D3DF00CF291B /* NSURLSession+MASPrivate.h in Headers */, A46F49CD1C2F5FC500A4C370 /* MASINetworkReachabilityManager.h in Headers */, @@ -1955,6 +1969,7 @@ CB9975471EDF5799006CEBB1 /* MASAuthCredentials+MASPrivate.m in Sources */, CB273F011DF8C5BF00AF2BDB /* L7SBrowserURLProtocol.m in Sources */, CB9975531EDF591C006CEBB1 /* MASAuthCredentialsJWT.m in Sources */, + C858D6B62398FC5400963763 /* MASDataTask+MASPrivate.m in Sources */, CBD25B041E78C47C00DFB47F /* JWTCoding+VersionOne.m in Sources */, CB9B1208210949D5008A2075 /* NSMutableData+MASASN1Helper.m in Sources */, CB99754B1EDF57D6006CEBB1 /* MASAuthCredentialsPassword.m in Sources */, @@ -1979,6 +1994,7 @@ CB6491FA1FE9DAF300281288 /* MQTTSessionSynchron.m in Sources */, A4831AB01BD1A551007B4AE6 /* MASDevice.m in Sources */, CBD25B001E78C47C00DFB47F /* JWTClaimsSetVerifier.m in Sources */, + C8B1700C238FD1A7007BB903 /* MASDataTask.m in Sources */, A46F49E31C2F5FC500A4C370 /* UIImageView+MASINetworking.m in Sources */, A421571C1BF863480034BDC9 /* MASServiceRegistry.m in Sources */, CBD25AEB1E78C47C00DFB47F /* JWTAlgorithmDataHolder.m in Sources */, diff --git a/MASFoundation/Classes/MAS.h b/MASFoundation/Classes/MAS.h index 1c4e6e3c..3ad83c32 100644 --- a/MASFoundation/Classes/MAS.h +++ b/MASFoundation/Classes/MAS.h @@ -1058,7 +1058,7 @@ withParameters:(NSDictionary *_Nullable)parameterInfo */ + (void)invoke:(nonnull MASRequest *)request completion:(nullable MASResponseObjectErrorBlock)completion; - ++ (void)invoke:(nonnull MASRequest *)request taskBlock:(nullable MASDataTaskBlock)dataTask completion:(nullable MASResponseObjectErrorBlock)completion; # pragma mark - FILE Requests diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index 0521c675..b5cd15de 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -1139,6 +1139,34 @@ + (void)invoke:(nonnull MASRequest *)request completion:(nullable MASResponseObj } ++ (void)invoke:(nonnull MASRequest *)request taskBlock:(nullable MASDataTaskBlock)dataTask completion:(nullable MASResponseObjectErrorBlock)completion +{ + __block MASResponseObjectErrorBlock blockCompletion = completion; + + + + [MAS checkAndValidateRequestScope:request.endPoint headerInfo:request.header isPublic:request.isPublic completion:^(BOOL completed, NSError *error) { + + if(!completed){ + completion(nil,nil,error); + return; + } + + // If default timeoutInterval override to NetworkConfiguration timeoutInterval. + NSTimeInterval timeoutInterval = + (request.timeoutInterval == MASDefaultNetworkTimeoutConfiguration) ? + [self timeoutIntervalForEndpoint:request.endPoint] : request.timeoutInterval; + + [MAS httpRouterMethod:request taskBlock:dataTask completion:^(NSDictionary * _Nullable responseInfo, NSError * _Nullable error) { + if (blockCompletion) + { + blockCompletion([responseInfo objectForKey:MASNSHTTPURLResponseObjectKey], [responseInfo objectForKey:MASResponseInfoBodyInfoKey], error); + } + }]; + + }]; +} + + (void)postMultiPartForm:(nonnull MASRequest *)request constructingBodyWithBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:( MASFileRequestProgressBlock _Nullable )progressBlock completion:(nullable MASResponseObjectErrorBlock)completion { if(![request.httpMethod isEqualToString:@"POST"] || request.requestType != MASRequestResponseTypeFormData) @@ -1317,6 +1345,53 @@ + (void)httpMethod:(NSString *)httpMethod }]; } + ++ (void)httpRouterMethod:(MASRequest*)request taskBlock:(_Nullable MASDataTaskBlock)taskBlock completion:(MASResponseInfoErrorBlock)completion +{ + // + // Check for endpoint + // + if (!request.endPoint) + { + if (completion) + { + completion(nil, [NSError errorInvalidEndpoint]); + + return; + } + } + + // + // Check if MAS has been started. + // + if ([MAS MASState] != MASStateDidStart) + { + if (completion) + { + completion(nil, [NSError errorMASIsNotStarted]); + + return; + } + } + + // + // Validate if new scope has been requested in header + // Validation will be ignored if the request is being made as public + // + NSDictionary *blockHeaderInfo = request.header ? request.header : [NSDictionary dictionary]; + + [MAS validateScopeForRequest:blockHeaderInfo isPublic:request.isPublic completion:^(BOOL completed, NSError *error) { + + if(!completed && error) + { + completion(nil,error); + return; + } + + [[MASNetworkingService sharedService] httpRequestWithCancel:request taskBlock:taskBlock completion:completion]; + }]; +} + + (MASResponseInfoErrorBlock)parseToEjectURLResponseForCompletionBlock:(MASResponseInfoErrorBlock)completionBlock { MASResponseInfoErrorBlock responseCompletionBlock = ^(NSDictionary *responseInfo, NSError *error) { diff --git a/MASFoundation/Classes/MASConstants.h b/MASFoundation/Classes/MASConstants.h index 1dcec58f..33aa4464 100644 --- a/MASFoundation/Classes/MASConstants.h +++ b/MASFoundation/Classes/MASConstants.h @@ -13,6 +13,7 @@ @class CLLocation; @class MASAuthCredentials; @class MASUser; +@class MASDataTask; @protocol MASMultiPartFormData; @@ -109,6 +110,11 @@ typedef void (^MASResponseInfoErrorBlock)(NSDictionary *_Nullabl typedef void (^MASResponseObjectErrorBlock)(NSHTTPURLResponse *_Nullable response, id _Nullable responseObject, NSError *_Nullable error); +/** +* The MASDataTaskBlock which contains the dataTask object that is being invoked. Users can typically call cancel on the request using this callback. +*/ +typedef void (^MASDataTaskBlock)(MASDataTask* _Nullable dataTask,NSError* _Nullable error); + /** * The MASUser specific (MASUser *user, NSError *error) block. */ diff --git a/MASFoundation/Classes/MASDataTask.h b/MASFoundation/Classes/MASDataTask.h new file mode 100644 index 00000000..8842b848 --- /dev/null +++ b/MASFoundation/Classes/MASDataTask.h @@ -0,0 +1,25 @@ +// +// MASDataTask.h +// MASFoundation +// +// Created by nimma01 on 28/11/19. +// Copyright © 2019 CA Technologies. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MASDataTask : NSObject +{ + +} + +@property(readonly)NSString* taskID; + + +- (void)cancel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MASFoundation/Classes/MASDataTask.m b/MASFoundation/Classes/MASDataTask.m new file mode 100644 index 00000000..a7274c78 --- /dev/null +++ b/MASFoundation/Classes/MASDataTask.m @@ -0,0 +1,36 @@ +// +// MASDataTask.m +// MASFoundation +// +// Created by nimma01 on 28/11/19. +// Copyright © 2019 CA Technologies. All rights reserved. +// + +#import "MASDataTask.h" +#import "MASSessionDataTaskOperation.h" + +@interface MASDataTask() +{ + +} +@property(nonatomic,readwrite)MASSessionDataTaskOperation* operation; +@property(readwrite)NSString* taskID; +@end + + +@implementation MASDataTask + +- (id)init +{ + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:@"Cannot create instances of this class, Object can only be used from taskBlock" userInfo:nil]; + + return nil; +} + +- (void)cancel +{ + [self.operation cancel]; +} + +@end diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h index ecca1591..4201714e 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h @@ -847,6 +847,8 @@ timeoutInterval:(NSTimeInterval)timeoutInterval +- (void)httpRequestWithCancel:(MASRequest*)request taskBlock:(MASDataTaskBlock)taskBlock completion:(MASResponseInfoErrorBlock)completion; + # pragma mark - HTTP File Requests - (void)postMultiPartForm:(NSString*)endPoint withParameters:(NSDictionary *)parameterInfo andHeaders:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic timeoutInterval:(NSTimeInterval)timeoutInterval constructingBodyBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:(MASFileRequestProgressBlock)progress completion:(MASResponseObjectErrorBlock)completion; diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m index d3e6ffc8..56f08a75 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m @@ -30,7 +30,7 @@ #import "MASNetworkReachability.h" #import "MASMultiFactorHandler+MASPrivate.h" #import "MASMultiPartRequestSerializer.h" - +#import "MASDataTask+MASPrivate.h" # pragma mark - Configuration Constants @@ -461,6 +461,7 @@ - (MASSessionDataTaskCompletionBlock)sessionDataTaskCompletionBlockWithEndPoint: // Response header info // NSDictionary *headerInfo = [httpResponse allHeaderFields]; + NSLog(@"Response headers : %@",headerInfo); // // If the error exists from the server, inject http status code in error userInfo @@ -1409,6 +1410,24 @@ - (void)httpPostTo:(NSString *)endPoint [self httpRequest:@"POST" endPoint:endPoint parameters:parameterInfo headers:headerInfo requestType:requestType responseType:responseType isPublic:isPublic timeoutInterval:timeoutInterval completion:completion]; } +- (void)httpPostTo:(MASRequest*)request taskBlock:(MASDataTaskBlock)taskBlock completion:(MASResponseInfoErrorBlock)completion +{ + // + // endPoint cannot be nil + // + if (!request.endPoint) + { + // + // Notify + // + if(completion) completion(nil, [NSError errorInvalidEndpoint]); + + return; + } + + +} + - (void)putTo:(NSString *)endPoint withParameters:(NSDictionary *)parameterInfo @@ -1569,6 +1588,7 @@ - (void)httpFileUploadRequest:(NSString *)endPoint parameters:(NSDictionary *)pa } }]]; + if (![self isMAGEndpoint:endPoint]) { // @@ -1609,6 +1629,7 @@ - (void)httpFileUploadRequest:(NSString *)endPoint parameters:(NSDictionary *)pa } + - (void)httpRequest:(NSString *)httpMethod endPoint:(NSString *)endPoint parameters:(NSDictionary *)parameterInfo headers:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic timeoutInterval:(NSTimeInterval)timeoutInterval completion:(MASResponseInfoErrorBlock)completion { @@ -1709,4 +1730,134 @@ - (void)httpRequest:(NSString *)httpMethod endPoint:(NSString *)endPoint paramet } } + +- (void)httpRequestWithCancel:(MASRequest*)request taskBlock:(MASDataTaskBlock)taskBlock completion:(MASResponseInfoErrorBlock)completion +{ + NSMutableDictionary *mutableHeaderInfo; + // + // Update the header + // + if(request.header){ + mutableHeaderInfo = [request.header mutableCopy]; + } + else{ + mutableHeaderInfo = [NSMutableDictionary mutableCopy]; + } + + + MASURLRequest* urlRequest = [self getURLRequest:request.httpMethod endPoint:request.endPoint parameters:request.body headers:[NSDictionary dictionary] requestType:request.requestType responseType:request.responseType isPublic:request.isPublic timeoutInterval:request.timeoutInterval]; + + // + // if location was successfully retrieved + // + if ([MASLocationService sharedService].lastKnownLocation != nil) + { + mutableHeaderInfo[MASGeoLocationRequestResponseKey] = [[MASLocationService sharedService].lastKnownLocation locationAsGeoCoordinates]; + } + + if(self.httpRedirectionBlock) + { + [_sessionManager setSessionDidReceiveHTTPRedirectBlock:self.httpRedirectionBlock]; + } + + MASSessionDataTaskOperation *operation = [_sessionManager dataOperationWithRequest:urlRequest + completionHandler:[self sessionDataTaskCompletionBlockWithEndPoint:request.endPoint + parameters:request.body + headers:request.header + httpMethod:urlRequest.HTTPMethod + requestType:request.requestType + responseType:request.responseType + isPublic:request.isPublic + completionBlock:completion]]; + + MASDataTask* newDataTask = [[MASDataTask alloc] initWithTask:operation]; + + + if (![self isMAGEndpoint:request.endPoint]) + { + // + // if the request is being made to system endpoint, and is not a public request which requires user credentials (tokens) + // then, add dependency on shared validation operation which will validate current session + // sharedOperation will only exist one at any given time as long as sharedOperation is being executed + // + if (!request.isPublic) + { + // + // add dependency + // + [operation addDependency:self.sharedOperation]; + + // + // to make sure SDK to not enqueue sharedOperation that is already enqueue and being executed + // + if (!self.sharedOperation.isFinished && !self.sharedOperation.isExecuting && ![_sessionManager.internalOperationQueue.operations containsObject:self.sharedOperation]) + { + // + // add sharedOperation into internal operation queue + // + [_sessionManager.internalOperationQueue addOperation:self.sharedOperation]; + } + } + + // + // add current request into normal operation queue + // + [_sessionManager.operationQueue addOperation:operation]; + } + else { + // + // if the request is being made to any one of system endpoints (registration, and/or authentication), then, add the operation into internal operation queue + // + [_sessionManager.internalOperationQueue addOperation:operation]; + } + + taskBlock(newDataTask,nil); +} + + +- (MASURLRequest*)getURLRequest:(NSString *)httpMethod endPoint:(NSString *)endPoint parameters:(NSDictionary *)parameterInfo headers:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic +timeoutInterval:(NSTimeInterval)timeoutInterval +{ + // + // Update the header + // + NSMutableDictionary *mutableHeaderInfo = [headerInfo mutableCopy]; + + MASURLRequest *request = nil; + + // + // if location was successfully retrieved + // + if ([MASLocationService sharedService].lastKnownLocation != nil) + { + mutableHeaderInfo[MASGeoLocationRequestResponseKey] = [[MASLocationService sharedService].lastKnownLocation locationAsGeoCoordinates]; + } + + // + // Construct MASURLRequest object per HTTP method + // + if ([httpMethod isEqualToString:@"DELETE"]) + { + request = [MASDeleteURLRequest requestForEndpoint:request.endPoint withParameters:parameterInfo andHeaders:mutableHeaderInfo requestType:requestType responseType:responseType isPublic:isPublic timeoutInterval:timeoutInterval]; + } + else if ([httpMethod isEqualToString:@"GET"]) + { + request = [MASGetURLRequest requestForEndpoint:endPoint withParameters:parameterInfo andHeaders:mutableHeaderInfo requestType:requestType responseType:responseType isPublic:isPublic timeoutInterval:timeoutInterval]; + } + else if ([httpMethod isEqualToString:@"PATCH"]) + { + request = [MASPatchURLRequest requestForEndpoint:endPoint withParameters:parameterInfo andHeaders:mutableHeaderInfo requestType:requestType responseType:responseType isPublic:isPublic timeoutInterval:timeoutInterval]; + } + else if ([httpMethod isEqualToString:@"POST"]) + { + request = [MASPostURLRequest requestForEndpoint:endPoint withParameters:parameterInfo andHeaders:mutableHeaderInfo requestType:requestType responseType:responseType isPublic:isPublic timeoutInterval:timeoutInterval]; + } + else if ([httpMethod isEqualToString:@"PUT"]) + { + request = [MASPutURLRequest requestForEndpoint:endPoint withParameters:parameterInfo andHeaders:mutableHeaderInfo requestType:requestType responseType:responseType isPublic:isPublic timeoutInterval:timeoutInterval]; + } + + return request; +} + @end diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h new file mode 100644 index 00000000..06b25273 --- /dev/null +++ b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h @@ -0,0 +1,25 @@ +// +// MASDataTask+MASPrivate.h +// MASFoundation +// +// Created by nimma01 on 05/12/19. +// Copyright © 2019 CA Technologies. All rights reserved. +// + +#import +#import "MASDataTask.h" +#import "MASSessionDataTaskOperation.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MASDataTask (MASPrivate) +{ + +} + +- (instancetype)initWithTask:(MASSessionDataTaskOperation*)operation; +- (void)cancelOperation; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m new file mode 100644 index 00000000..7257fdd8 --- /dev/null +++ b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m @@ -0,0 +1,37 @@ +// +// MASDataTask+MASPrivate.m +// MASFoundation +// +// Created by nimma01 on 05/12/19. +// Copyright © 2019 CA Technologies. All rights reserved. +// + +#import "MASDataTask+MASPrivate.h" + +@interface MASDataTask() +{ + +} + +@property(readwrite)NSString* taskID; +@property(nonatomic,readwrite)MASSessionDataTaskOperation* operation; + +@end + +@implementation MASDataTask (MASPrivate) + + +- (instancetype)initWithTask:(MASSessionDataTaskOperation*)operation +{ + if(self = [super init]){ + self.operation = operation; + self.taskID = operation.taskID; + } + + return self; +} + + + + +@end diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.h b/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.h index 37b832fc..9304ee12 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.h +++ b/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.h @@ -22,6 +22,7 @@ @property (nonatomic, copy) MASNetworkDataTaskDidReceiveDataBlock didReceiveDataBlock; @property (nonatomic, copy) MASNetworkDataTaskWillCacheResponseBlock willCacheResponseBlock; @property (nonatomic, copy) MASNetworkDataTaskDidReceiveResponseBlock didReceiveResponseBlock; +@property (nonatomic,readonly) NSString* taskID; - (instancetype)initWithSession:(NSURLSession *)session request:(NSURLRequest *)request progress:(MASFileRequestProgressBlock)progress; diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m b/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m index 7889c12a..4619f9b8 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m +++ b/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m @@ -29,6 +29,7 @@ @interface MASSessionDataTaskOperation () @property (nonatomic, readwrite, strong) MASURLRequest *request; @property (nonatomic, readwrite, strong) NSURLSession *session; +@property (nonatomic, strong) NSString* taskID; @property (nonatomic)MASFileRequestProgressBlock fileProgressblock; @@ -49,6 +50,7 @@ - (instancetype)initWithSession:(NSURLSession *)session request:(NSURLRequest *) { self.request = (MASURLRequest *)request; [self setResponseType:self.request.responseType]; + self.taskID = [[NSUUID UUID] UUIDString]; } return self; diff --git a/MASFoundation/MASFoundation.h b/MASFoundation/MASFoundation.h index 7f36d17b..4f76e160 100644 --- a/MASFoundation/MASFoundation.h +++ b/MASFoundation/MASFoundation.h @@ -53,6 +53,7 @@ FOUNDATION_EXPORT const unsigned char MASFoundationVersionString[]; #import #import #import +#import // // AuthCredentials Models From 08cbd247a780c78970c0e559f7d7cd23f9cac5c1 Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Mon, 9 Dec 2019 15:46:43 +0530 Subject: [PATCH 02/11] extending cancel functionality to Multi-part form request --- MASFoundation/Classes/MAS.h | 28 +++++++++++++++++ MASFoundation/Classes/MAS.m | 30 ++++++++++++++++++- .../services/network/MASNetworkingService.h | 2 +- .../services/network/MASNetworkingService.m | 17 ++++++++--- 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/MASFoundation/Classes/MAS.h b/MASFoundation/Classes/MAS.h index 3ad83c32..2e03b95b 100644 --- a/MASFoundation/Classes/MAS.h +++ b/MASFoundation/Classes/MAS.h @@ -1088,6 +1088,34 @@ withParameters:(NSDictionary *_Nullable)parameterInfo */ + (void)postMultiPartForm:(nonnull MASRequest *)request constructingBodyWithBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:( MASFileRequestProgressBlock _Nullable )progressBlock completion:(nullable MASResponseObjectErrorBlock)completion; + +/** +* Post a multi-part form with the parameters defined in the MASRequest object +* +* If endPointPath is full URL format (including port number and http protocol), SDK will validate the server from the client side through SSL pinning (authentication challenge) with +* provided subjectKeyHash (also known as public key hash) in configuration in mag.mobile_sdk.trusted_cert_pinned_public_key_hashes and mag.mobile_sdk.enable_public_key_pinning. +* ALL of servers' public key hashes in certificate chain must be defined in the list. This means when it is configured to use public key hash pinning for SSL pinning, +* subjectKeyHash (public key hash) of the gateway must be also present within the list. The list can contain multiple hash values in array for multiple servers. +* +* When SDK fails to validate SSL with certificate or subjectKeyHash pinning for communication to HTTPs, SDK will cancel the request. +* +* If endPointPath is full URL format, upon successful SSL pinning validation, SDK will also validate the user session against primary gateway regardless the request is being made +* to the primary gateway or not. To ensure bypass the user session validation for public API, use [MAS deleteFrom:withParameters:requestType:responseType:isPublic:completion:] method +* with isPublic being YES. +* +* The API appends the file data and any other parameters to the body and follows the standards defined for Content-Type = multipart/form-data +* +* @param request MASRequest An object containing all parameters to call the endpoint +* When the value is set to true, all automatically injected credentials in SDK will be excluded in the request. +* @param formDataBlock This is a block that gets called while constructing the body of the multi-part form request. Typically files can be added to the body by calling various APIs available in MASMultiPartFormData +* @see MASMultiPartFormData +* @param progressBlock Block which gives back the NSProgress of the task that is going on. Different values can be read from the progress object to present a meaningful progress updates in the UI. Recommend to use progress.fractioncompleted for progress bar updates. +* @param taskBlock Block which gives back handle to the underlying task object. This task can be cancelled by calling cancel on the object. +* @param completion An MASResponseObjectErrorBlock (NSHTTPURLResponse *response, id responseObject, NSError *error) that will +* receive the NSHTTPURLResponse object, response object which needs to perform type casting based on the object type, and NSError object when error occurs. +*/ ++ (void)postMultiPartForm:(nonnull MASRequest *)request constructingBodyWithBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:( MASFileRequestProgressBlock _Nullable )progressBlock taskBlock:(MASDataTaskBlock _Nullable )taskBlock completion:(nullable MASResponseObjectErrorBlock)completion; + ///-------------------------------------- /// @name JWT Signing ///-------------------------------------- diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index b5cd15de..6c4f5e21 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -1188,7 +1188,35 @@ + (void)postMultiPartForm:(nonnull MASRequest *)request constructingBodyWithBloc (request.timeoutInterval == MASDefaultNetworkTimeoutConfiguration) ? [self timeoutIntervalForEndpoint:request.endPoint] : request.timeoutInterval; - [[MASNetworkingService sharedService] postMultiPartForm:request.endPoint withParameters:request.body andHeaders:request.header requestType:request.requestType responseType:request.responseType isPublic:request.isPublic timeoutInterval:timeoutInterval constructingBodyBlock:formDataBlock progress:progressBlock completion:completion]; + + + [[MASNetworkingService sharedService] postMultiPartForm:request.endPoint withParameters:request.body andHeaders:request.header requestType:request.requestType responseType:request.responseType isPublic:request.isPublic timeoutInterval:timeoutInterval constructingBodyBlock:formDataBlock progress:progressBlock taskBlock:nil completion:completion]; + + }]; +} + ++ (void)postMultiPartForm:(nonnull MASRequest *)request constructingBodyWithBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:( MASFileRequestProgressBlock _Nullable )progressBlock taskBlock:(MASDataTaskBlock _Nullable )taskBlock completion:(nullable MASResponseObjectErrorBlock)completion +{ + if(![request.httpMethod isEqualToString:@"POST"] || request.requestType != MASRequestResponseTypeFormData) + { + NSError* error = [NSError errorInvalidRequestForFileUpload]; + completion(nil,nil,error); + return; + } + + [MAS checkAndValidateRequestScope:request.endPoint headerInfo:request.header isPublic:request.isPublic completion:^(BOOL completed, NSError *error) { + + if(!completed){ + completion(nil,nil,error); + return; + } + + // If default timeoutInterval override to NetworkConfiguration timeoutInterval. + NSTimeInterval timeoutInterval = + (request.timeoutInterval == MASDefaultNetworkTimeoutConfiguration) ? + [self timeoutIntervalForEndpoint:request.endPoint] : request.timeoutInterval; + + [[MASNetworkingService sharedService] postMultiPartForm:request.endPoint withParameters:request.body andHeaders:request.header requestType:request.requestType responseType:request.responseType isPublic:request.isPublic timeoutInterval:timeoutInterval constructingBodyBlock:formDataBlock progress:progressBlock taskBlock:taskBlock completion:completion]; }]; } diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h index 4201714e..b3c119f9 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h @@ -851,7 +851,7 @@ timeoutInterval:(NSTimeInterval)timeoutInterval # pragma mark - HTTP File Requests -- (void)postMultiPartForm:(NSString*)endPoint withParameters:(NSDictionary *)parameterInfo andHeaders:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic timeoutInterval:(NSTimeInterval)timeoutInterval constructingBodyBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:(MASFileRequestProgressBlock)progress completion:(MASResponseObjectErrorBlock)completion; +- (void)postMultiPartForm:(NSString*)endPoint withParameters:(NSDictionary *)parameterInfo andHeaders:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic timeoutInterval:(NSTimeInterval)timeoutInterval constructingBodyBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:(MASFileRequestProgressBlock)progress taskBlock:(MASDataTaskBlock)taskBlock completion:(MASResponseObjectErrorBlock)completion; @end diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m index 56f08a75..6db477fa 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m @@ -1538,7 +1538,7 @@ - (void)httpPutTo:(NSString *)endPoint } -- (void)postMultiPartForm:(NSString*)endPoint withParameters:(NSDictionary *)parameterInfo andHeaders:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic timeoutInterval:(NSTimeInterval)timeoutInterval constructingBodyBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:(MASFileRequestProgressBlock)progress completion:(MASResponseObjectErrorBlock)completion +- (void)postMultiPartForm:(NSString*)endPoint withParameters:(NSDictionary *)parameterInfo andHeaders:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic timeoutInterval:(NSTimeInterval)timeoutInterval constructingBodyBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:(MASFileRequestProgressBlock)progress taskBlock:(MASDataTaskBlock)taskBlock completion:(MASResponseObjectErrorBlock)completion { // // endPoint cannot be nil @@ -1553,11 +1553,11 @@ - (void)postMultiPartForm:(NSString*)endPoint withParameters:(NSDictionary *)par return; } - [self httpFileUploadRequest:endPoint parameters:parameterInfo headers:headerInfo requestType:requestType responseType:responseType isPublic:isPublic timeoutInterval:timeoutInterval constructingBodyBlock:formDataBlock progress:progress completion:completion]; + [self httpFileUploadRequest:endPoint parameters:parameterInfo headers:headerInfo requestType:requestType responseType:responseType isPublic:isPublic timeoutInterval:timeoutInterval constructingBodyBlock:formDataBlock progress:progress taskBlock:taskBlock completion:completion]; } -- (void)httpFileUploadRequest:(NSString *)endPoint parameters:(NSDictionary *)parameterInfo headers:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic timeoutInterval:(NSTimeInterval)timeoutInterval constructingBodyBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:(MASFileRequestProgressBlock)progress completion:(MASResponseObjectErrorBlock)completion +- (void)httpFileUploadRequest:(NSString *)endPoint parameters:(NSDictionary *)parameterInfo headers:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic timeoutInterval:(NSTimeInterval)timeoutInterval constructingBodyBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:(MASFileRequestProgressBlock)progress taskBlock:(MASDataTaskBlock)taskBlock completion:(MASResponseObjectErrorBlock)completion { NSMutableDictionary *mutableHeaderInfo = [headerInfo mutableCopy]; @@ -1588,6 +1588,8 @@ - (void)httpFileUploadRequest:(NSString *)endPoint parameters:(NSDictionary *)pa } }]]; + MASDataTask* newDataTask = [[MASDataTask alloc] initWithTask:operation]; + if (![self isMAGEndpoint:endPoint]) { @@ -1626,6 +1628,10 @@ - (void)httpFileUploadRequest:(NSString *)endPoint parameters:(NSDictionary *)pa // [_sessionManager.internalOperationQueue addOperation:operation]; } + + if(taskBlock){ + taskBlock(newDataTask,nil); + } } @@ -1811,7 +1817,10 @@ - (void)httpRequestWithCancel:(MASRequest*)request taskBlock:(MASDataTaskBlock)t [_sessionManager.internalOperationQueue addOperation:operation]; } - taskBlock(newDataTask,nil); + if(taskBlock){ + taskBlock(newDataTask,nil); + } + } From 94500b0caa4b2c1f9d2e8ff01d168da9def88859 Mon Sep 17 00:00:00 2001 From: Mahendra Nimishakavi Date: Tue, 10 Dec 2019 15:21:24 +0530 Subject: [PATCH 03/11] added cancel request on MAS and implemented map to store operations and tasks to cancel. # added cleaning logic for tasks before adding a new task --- MASFoundation/Classes/MAS.h | 2 + MASFoundation/Classes/MAS.m | 6 +++ MASFoundation/Classes/MASDataTask.m | 5 +- .../services/network/MASNetworkingService.h | 2 + .../services/network/MASNetworkingService.m | 47 +++++++++++++++++-- .../network/internal/MASDataTask+MASPrivate.h | 3 +- .../network/internal/MASDataTask+MASPrivate.m | 11 +++++ .../internal/MASSessionDataTaskOperation.m | 1 + 8 files changed, 71 insertions(+), 6 deletions(-) diff --git a/MASFoundation/Classes/MAS.h b/MASFoundation/Classes/MAS.h index 2e03b95b..7fa91087 100644 --- a/MASFoundation/Classes/MAS.h +++ b/MASFoundation/Classes/MAS.h @@ -1060,6 +1060,8 @@ withParameters:(NSDictionary *_Nullable)parameterInfo + (void)invoke:(nonnull MASRequest *)request taskBlock:(nullable MASDataTaskBlock)dataTask completion:(nullable MASResponseObjectErrorBlock)completion; ++ (void)cancelRequest:(MASDataTask*)task; + # pragma mark - FILE Requests /** diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index 6c4f5e21..2d5d73c2 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -1222,6 +1222,12 @@ + (void)postMultiPartForm:(nonnull MASRequest *)request constructingBodyWithBloc } ++ (void)cancelRequest:(MASDataTask*)task +{ + [[MASNetworkingService sharedService] cancelRequest:task]; +} + + # pragma mark - Private + (void)checkAndValidateRequestScope:(NSString*)endPoint headerInfo:(NSDictionary *)headerInfo isPublic:(BOOL)isPublic completion:(MASCompletionErrorBlock)completion diff --git a/MASFoundation/Classes/MASDataTask.m b/MASFoundation/Classes/MASDataTask.m index a7274c78..5a6736f3 100644 --- a/MASFoundation/Classes/MASDataTask.m +++ b/MASFoundation/Classes/MASDataTask.m @@ -30,7 +30,10 @@ - (id)init - (void)cancel { - [self.operation cancel]; + if(![self.operation isFinished] && ![self.operation isCancelled]){ + [self.operation cancel]; + } + } @end diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h index b3c119f9..95b0e3e0 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h @@ -849,6 +849,8 @@ timeoutInterval:(NSTimeInterval)timeoutInterval - (void)httpRequestWithCancel:(MASRequest*)request taskBlock:(MASDataTaskBlock)taskBlock completion:(MASResponseInfoErrorBlock)completion; +- (void)cancelRequest:(MASDataTask*)task; + # pragma mark - HTTP File Requests - (void)postMultiPartForm:(NSString*)endPoint withParameters:(NSDictionary *)parameterInfo andHeaders:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic timeoutInterval:(NSTimeInterval)timeoutInterval constructingBodyBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:(MASFileRequestProgressBlock)progress taskBlock:(MASDataTaskBlock)taskBlock completion:(MASResponseObjectErrorBlock)completion; diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m index 6db477fa..809632bb 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m @@ -63,6 +63,7 @@ @interface MASNetworkingService () @property (nonatomic, strong, readwrite) MASURLSessionManager *sessionManager; @property (nonatomic, strong, readwrite) MASNetworkReachability *gatewayReachabilityManager; @property (readwrite, nonatomic, strong) MASAuthValidationOperation *authValidationOperation; +@property (nonatomic, strong) NSMutableDictionary* tasks; @end @@ -240,8 +241,10 @@ + (instancetype)sharedService dispatch_once(&onceToken, ^ { sharedInstance = [[MASNetworkingService alloc] initProtected]; + }); + return sharedInstance; } @@ -269,6 +272,10 @@ - (void)serviceDidLoad - (void)serviceWillStart { + + if(!self.tasks){ + self.tasks = [[NSMutableDictionary alloc] init]; + } // // establish URLSession with configuration's host name and start networking monitoring // @@ -431,8 +438,7 @@ - (MASSessionDataTaskCompletionBlock)sessionDataTaskCompletionBlockWithEndPoint: httpMethod:(NSString *)httpMethod requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType - isPublic:(BOOL)isPublic - completionBlock:(MASResponseInfoErrorBlock)completion + isPublic:(BOOL)isPublic completionBlock:(MASResponseInfoErrorBlock)completion { __block MASRequestResponseType blockResponseType = responseType; __block MASRequestResponseType blockRequestType = requestType; @@ -1589,6 +1595,7 @@ - (void)httpFileUploadRequest:(NSString *)endPoint parameters:(NSDictionary *)pa }]]; MASDataTask* newDataTask = [[MASDataTask alloc] initWithTask:operation]; + [self cacheDataTask:newDataTask]; if (![self isMAGEndpoint:endPoint]) @@ -1773,10 +1780,12 @@ - (void)httpRequestWithCancel:(MASRequest*)request taskBlock:(MASDataTaskBlock)t httpMethod:urlRequest.HTTPMethod requestType:request.requestType responseType:request.responseType - isPublic:request.isPublic - completionBlock:completion]]; + isPublic:request.isPublic completionBlock:completion]]; + MASDataTask* newDataTask = [[MASDataTask alloc] initWithTask:operation]; + [self cacheDataTask:newDataTask]; + if (![self isMAGEndpoint:request.endPoint]) @@ -1824,6 +1833,36 @@ - (void)httpRequestWithCancel:(MASRequest*)request taskBlock:(MASDataTaskBlock)t } +- (void)cacheDataTask:(MASDataTask*)dataTask +{ + [self cleanUpFinishedTasks]; + if(dataTask.taskID){ + [self.tasks setObject:dataTask forKey:dataTask.taskID]; + } +} + +- (void)cleanUpFinishedTasks +{ + NSLog(@"cleaning up tasks"); + for (NSString* key in self.tasks){ + if([[self.tasks objectForKey:key] isFinished] || [[self.tasks objectForKey:key] isCancelled]){ + [self.tasks removeObjectForKey:key]; + } + } + NSLog(@"finished cleaning up"); +} + +- (void)cancelRequest:(MASDataTask*)task +{ + NSString* taskID = task.taskID; + if([self.tasks objectForKey:taskID]){ + MASDataTask* taskToBeCancelled = [self.tasks objectForKey:taskID]; + [taskToBeCancelled cancel]; + [self.tasks removeObjectForKey:taskToBeCancelled.taskID]; + } +} + + - (MASURLRequest*)getURLRequest:(NSString *)httpMethod endPoint:(NSString *)endPoint parameters:(NSDictionary *)parameterInfo headers:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic timeoutInterval:(NSTimeInterval)timeoutInterval { diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h index 06b25273..15a6ce59 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h +++ b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h @@ -18,7 +18,8 @@ NS_ASSUME_NONNULL_BEGIN } - (instancetype)initWithTask:(MASSessionDataTaskOperation*)operation; -- (void)cancelOperation; +- (BOOL)isFinished; +-(BOOL)isCancelled; @end diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m index 7257fdd8..9b791774 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m +++ b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m @@ -31,6 +31,17 @@ - (instancetype)initWithTask:(MASSessionDataTaskOperation*)operation return self; } +- (BOOL)isFinished +{ + return [self.operation isFinished]; +} + + +-(BOOL)isCancelled +{ + return [self.operation isCancelled]; +} + diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m b/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m index 4619f9b8..965f0229 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m +++ b/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m @@ -64,6 +64,7 @@ - (instancetype)initWithSession:(NSURLSession *)session request:(NSURLRequest *) self.request = (MASURLRequest *)request; [self setResponseType:self.request.responseType]; self.fileProgressblock = progress; + self.taskID = [[NSUUID UUID] UUIDString]; } return self; From 64d2ebc86fed4a28c6636f14f839f28999f5b02e Mon Sep 17 00:00:00 2001 From: Mahendra Date: Mon, 16 Dec 2019 12:46:55 +0530 Subject: [PATCH 04/11] Implementation of cancel all tasks and few optimizations --- MASFoundation/Classes/MAS.h | 4 +++- MASFoundation/Classes/MAS.m | 5 +++++ .../services/network/MASNetworkingService.h | 2 ++ .../services/network/MASNetworkingService.m | 14 +++++++++++++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/MASFoundation/Classes/MAS.h b/MASFoundation/Classes/MAS.h index 7fa91087..a1a810af 100644 --- a/MASFoundation/Classes/MAS.h +++ b/MASFoundation/Classes/MAS.h @@ -1060,7 +1060,9 @@ withParameters:(NSDictionary *_Nullable)parameterInfo + (void)invoke:(nonnull MASRequest *)request taskBlock:(nullable MASDataTaskBlock)dataTask completion:(nullable MASResponseObjectErrorBlock)completion; -+ (void)cancelRequest:(MASDataTask*)task; ++ (void)cancelRequest:(nonnull MASDataTask*)task; + ++ (void)cancelAllRequests; # pragma mark - FILE Requests diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index 2d5d73c2..969f5f87 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -1227,6 +1227,11 @@ + (void)cancelRequest:(MASDataTask*)task [[MASNetworkingService sharedService] cancelRequest:task]; } ++ (void)cancelAllRequests +{ + [[MASNetworkingService sharedService] cancelAllRequests]; +} + # pragma mark - Private diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h index 95b0e3e0..c7638acf 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h @@ -851,6 +851,8 @@ timeoutInterval:(NSTimeInterval)timeoutInterval - (void)cancelRequest:(MASDataTask*)task; +- (void)cancelAllRequests; + # pragma mark - HTTP File Requests - (void)postMultiPartForm:(NSString*)endPoint withParameters:(NSDictionary *)parameterInfo andHeaders:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic timeoutInterval:(NSTimeInterval)timeoutInterval constructingBodyBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:(MASFileRequestProgressBlock)progress taskBlock:(MASDataTaskBlock)taskBlock completion:(MASResponseObjectErrorBlock)completion; diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m index 809632bb..71915c10 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m @@ -1844,11 +1844,14 @@ - (void)cacheDataTask:(MASDataTask*)dataTask - (void)cleanUpFinishedTasks { NSLog(@"cleaning up tasks"); + NSMutableArray* keysToRemove = [[NSMutableArray alloc] init]; for (NSString* key in self.tasks){ if([[self.tasks objectForKey:key] isFinished] || [[self.tasks objectForKey:key] isCancelled]){ - [self.tasks removeObjectForKey:key]; + [keysToRemove addObject:key]; + //[self.tasks removeObjectForKey:key]; } } + [self.tasks removeObjectsForKeys:keysToRemove]; NSLog(@"finished cleaning up"); } @@ -1863,6 +1866,15 @@ - (void)cancelRequest:(MASDataTask*)task } +- (void)cancelAllRequests +{ + [[_sessionManager operationQueue] cancelAllOperations]; + [[_sessionManager internalOperationQueue] cancelAllOperations]; + +} + + + - (MASURLRequest*)getURLRequest:(NSString *)httpMethod endPoint:(NSString *)endPoint parameters:(NSDictionary *)parameterInfo headers:(NSDictionary *)headerInfo requestType:(MASRequestResponseType)requestType responseType:(MASRequestResponseType)responseType isPublic:(BOOL)isPublic timeoutInterval:(NSTimeInterval)timeoutInterval { From 2193259e38bc4f191ff10fa6168656c8508a971a Mon Sep 17 00:00:00 2001 From: Mahendra Date: Wed, 18 Dec 2019 14:51:54 +0530 Subject: [PATCH 05/11] added code to cancel and cancel all requests --- MASFoundation/Classes/MAS.h | 43 ++++++++++++++++++- MASFoundation/Classes/MAS.m | 11 ++++- MASFoundation/Classes/MASDataTask.m | 5 ++- MASFoundation/Classes/MASError.h | 5 +++ .../_private_/categories/NSError+MASPrivate.h | 9 ++++ .../_private_/categories/NSError+MASPrivate.m | 10 +++++ .../services/network/MASNetworkingService.m | 10 +++-- .../internal/MASSessionTaskOperation.m | 10 +++++ 8 files changed, 95 insertions(+), 8 deletions(-) diff --git a/MASFoundation/Classes/MAS.h b/MASFoundation/Classes/MAS.h index a1a810af..b3bb9d23 100644 --- a/MASFoundation/Classes/MAS.h +++ b/MASFoundation/Classes/MAS.h @@ -1058,10 +1058,51 @@ withParameters:(NSDictionary *_Nullable)parameterInfo */ + (void)invoke:(nonnull MASRequest *)request completion:(nullable MASResponseObjectErrorBlock)completion; + +/** +* Invoke the endpoint with the parameters defined in the MASRequest object and also cancel a pending request using the taskBlock +* +* If endPointPath is full URL format (including port number and http protocol), SDK will validate the server from the client side through SSL pinning (authentication challenge) with +* provided subjectKeyHash (also known as public key hash) in configuration in mag.mobile_sdk.trusted_cert_pinned_public_key_hashes and mag.mobile_sdk.enable_public_key_pinning. +* ALL of servers' public key hashes in certificate chain must be defined in the list. This means when it is configured to use public key hash pinning for SSL pinning, +* subjectKeyHash (public key hash) of the gateway must be also present within the list. The list can contain multiple hash values in array for multiple servers. +* +* When SDK fails to validate SSL with certificate or subjectKeyHash pinning for communication to HTTPs, SDK will cancel the request. +* +* If endPointPath is full URL format, upon successful SSL pinning validation, SDK will also validate the user session against primary gateway regardless the request is being made +* to the primary gateway or not. To ensure bypass the user session validation for public API, use [MAS deleteFrom:withParameters:requestType:responseType:isPublic:completion:] method +* with isPublic being YES. +* +* @param request MASRequest An object containing all parameters to call the endpoint +* When the value is set to true, all automatically injected credentials in SDK will be excluded in the request. +* @param dataTask MASDataTaskBlock A block which gives a MASDataTask object that can be used to cancel the request +* @param completion An MASResponseObjectErrorBlock (NSHTTPURLResponse *response, id responseObject, NSError *error) that will +* receive the NSHTTPURLResponse object, response object which needs to perform type casting based on the object type, and NSError object when error occurs. + @see cancelRequest +*/ + + (void)invoke:(nonnull MASRequest *)request taskBlock:(nullable MASDataTaskBlock)dataTask completion:(nullable MASResponseObjectErrorBlock)completion; -+ (void)cancelRequest:(nonnull MASDataTask*)task; +/** +* API to cancel a pending HTTP request that was invoked using the API invoke:taksBlock:completion: +* This is a best effort cancel and uses the underlying cancel functionality of iOS. +* This means there could be scenarios where the request has already been complete and the response is received. In such cases calling cancel has no real meaning. +* The completion handler returns with an error description that the task has been cancelled. But in some cases if the request has a dependent Task like a login to be completed, then calling cancel on the request may not return a response back as the task has not been started yet. +* Cancelling an already finished task has no effect. +* @param task MASDataTask object that was obtained as a result of invoking a request using the API invoke:taksBlock:completion: +*/ + ++ (void)cancelRequest:(nonnull MASDataTask*)task error:(NSError*_Nullable*_Nullable)error; + + +/** +* API to cancel all the pending requests in the queue. +* This is a best effort cancel and uses the underlying cancel functionality of iOS. +* This means there could be scenarios where the request has already been complete and the response is received. In such cases calling cancel has no real meaning. +* All the taks that are pending and not finished yet will be cancelled. There is no guarantee for a callback with error for all the requests. + * Use this when you are sure to cancel all the existing requests and do not really care about the outcome. For example, User moved away from the flow and does not really need any response from earlier tasks. +*/ + (void)cancelAllRequests; # pragma mark - FILE Requests diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index 969f5f87..46826020 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -1222,8 +1222,17 @@ + (void)postMultiPartForm:(nonnull MASRequest *)request constructingBodyWithBloc } -+ (void)cancelRequest:(MASDataTask*)task ++ (void)cancelRequest:(nonnull MASDataTask*)task error:(NSError**)error { + // + // Check if MAS has been started. + // + if ([MAS MASState] != MASStateDidStart) + { + *error = [NSError errorMASIsNotStarted]; + + } + [[MASNetworkingService sharedService] cancelRequest:task]; } diff --git a/MASFoundation/Classes/MASDataTask.m b/MASFoundation/Classes/MASDataTask.m index 5a6736f3..15cd3467 100644 --- a/MASFoundation/Classes/MASDataTask.m +++ b/MASFoundation/Classes/MASDataTask.m @@ -13,7 +13,7 @@ @interface MASDataTask() { } -@property(nonatomic,readwrite)MASSessionDataTaskOperation* operation; +@property(nonatomic,readwrite,weak)MASSessionDataTaskOperation* operation; @property(readwrite)NSString* taskID; @end @@ -30,7 +30,8 @@ - (id)init - (void)cancel { - if(![self.operation isFinished] && ![self.operation isCancelled]){ + if(self.operation && (![self.operation isFinished] && ![self.operation isCancelled])){ + DLog(@"Cancelling task with ID %@",self.taskID); [self.operation cancel]; } diff --git a/MASFoundation/Classes/MASError.h b/MASFoundation/Classes/MASError.h index ea6bfe60..009aa5df 100644 --- a/MASFoundation/Classes/MASError.h +++ b/MASFoundation/Classes/MASError.h @@ -208,6 +208,11 @@ typedef NS_ENUM(NSInteger, MASFoundationErrorCode) // MASFoundationErrorCodeInvalidRequestForFileUpload = 180100, + // + // Data Task Cancelled + // + MASFoundationErrorCodeTaskCancelled = 180102, + MASFoundationErrorCodeCount = -999999 }; diff --git a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.h b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.h index dc59163f..467df7c6 100644 --- a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.h +++ b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.h @@ -656,4 +656,13 @@ */ + (NSError *)errorInvalidRequestForFileUpload; + +/** +* Create MASFoundationErrorDomainLocal NSError for MASFoundationErrorCodeTaskCancelled. +* +* @return Returns an NSError instance with the domain MASFoundationErrorDomainLocal and +* error MASFoundationErrorCodeTaskCancelled +*/ ++ (NSError *)errorDataTaskCancelled; + @end diff --git a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m index 173bdbcc..d15c42df 100644 --- a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m +++ b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m @@ -838,6 +838,11 @@ + (NSError *)errorInvalidRequestForFileUpload return [self errorForFoundationCode:MASFoundationErrorCodeInvalidRequestForFileUpload errorDomain:MASFoundationErrorDomainLocal]; } ++ (NSError *)errorDataTaskCancelled +{ + return [self errorForFoundationCode:MASFoundationErrorCodeTaskCancelled errorDomain:MASFoundationErrorDomainLocal]; +} + # pragma mark - Foundation Errors Private @@ -1114,6 +1119,11 @@ + (NSString *)descriptionForFoundationErrorCode:(MASFoundationErrorCode)errorCod case MASFoundationErrorCodeInvalidRequestForFileUpload : return @"the MASRequest is not valid for multi-part file upload. Please check if the request is of method POST and the request type is MASRequestResponseTypeFormData."; + // + // Task Cancelled Error + // + case MASFoundationErrorCodeTaskCancelled : return @"The request has been Cancelled"; + // // Default // diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m index 71915c10..b9e18291 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m @@ -1784,6 +1784,7 @@ - (void)httpRequestWithCancel:(MASRequest*)request taskBlock:(MASDataTaskBlock)t MASDataTask* newDataTask = [[MASDataTask alloc] initWithTask:operation]; + DLog(@"MASNetworkingService : created Task with ID %@",newDataTask.taskID); [self cacheDataTask:newDataTask]; @@ -1837,13 +1838,14 @@ - (void)cacheDataTask:(MASDataTask*)dataTask { [self cleanUpFinishedTasks]; if(dataTask.taskID){ + DLog(@"MASNetworkingService : Added Task with ID %@ to the cache",dataTask.taskID); [self.tasks setObject:dataTask forKey:dataTask.taskID]; } } - (void)cleanUpFinishedTasks { - NSLog(@"cleaning up tasks"); + NSLog(@"cleanUpFinishedTasks : cleaning up tasks"); NSMutableArray* keysToRemove = [[NSMutableArray alloc] init]; for (NSString* key in self.tasks){ if([[self.tasks objectForKey:key] isFinished] || [[self.tasks objectForKey:key] isCancelled]){ @@ -1852,13 +1854,13 @@ - (void)cleanUpFinishedTasks } } [self.tasks removeObjectsForKeys:keysToRemove]; - NSLog(@"finished cleaning up"); + NSLog(@"cleanUpFinishedTasks : finished cleaning up"); } - (void)cancelRequest:(MASDataTask*)task { NSString* taskID = task.taskID; - if([self.tasks objectForKey:taskID]){ + if(self.tasks && [self.tasks objectForKey:taskID]){ MASDataTask* taskToBeCancelled = [self.tasks objectForKey:taskID]; [taskToBeCancelled cancel]; [self.tasks removeObjectForKey:taskToBeCancelled.taskID]; @@ -1868,9 +1870,9 @@ - (void)cancelRequest:(MASDataTask*)task - (void)cancelAllRequests { + NSLog(@"Cancel All Requests"); [[_sessionManager operationQueue] cancelAllOperations]; [[_sessionManager internalOperationQueue] cancelAllOperations]; - } diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASSessionTaskOperation.m b/MASFoundation/Classes/_private_/services/network/internal/MASSessionTaskOperation.m index db685612..257e45dc 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASSessionTaskOperation.m +++ b/MASFoundation/Classes/_private_/services/network/internal/MASSessionTaskOperation.m @@ -135,6 +135,16 @@ - (void)start - (void)cancel { + if(!self.isExecuting){ + [self.task cancel]; + [super cancel]; + if(self.didCompleteWithDataErrorBlock){ + self.didCompleteWithDataErrorBlock(nil, nil, nil, [NSError errorDataTaskCancelled]); + } + + return; + } + [self.task cancel]; [super cancel]; } From cdc2e321f8cd9c59a4b0d3f0c5dd0d043eb119f2 Mon Sep 17 00:00:00 2001 From: Mahendra Date: Wed, 18 Dec 2019 14:55:57 +0530 Subject: [PATCH 06/11] updated documentation --- MASFoundation/Classes/MAS.h | 47 ++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/MASFoundation/Classes/MAS.h b/MASFoundation/Classes/MAS.h index b3bb9d23..4e5f28b6 100644 --- a/MASFoundation/Classes/MAS.h +++ b/MASFoundation/Classes/MAS.h @@ -1084,27 +1084,8 @@ withParameters:(NSDictionary *_Nullable)parameterInfo + (void)invoke:(nonnull MASRequest *)request taskBlock:(nullable MASDataTaskBlock)dataTask completion:(nullable MASResponseObjectErrorBlock)completion; -/** -* API to cancel a pending HTTP request that was invoked using the API invoke:taksBlock:completion: -* This is a best effort cancel and uses the underlying cancel functionality of iOS. -* This means there could be scenarios where the request has already been complete and the response is received. In such cases calling cancel has no real meaning. -* The completion handler returns with an error description that the task has been cancelled. But in some cases if the request has a dependent Task like a login to be completed, then calling cancel on the request may not return a response back as the task has not been started yet. -* Cancelling an already finished task has no effect. -* @param task MASDataTask object that was obtained as a result of invoking a request using the API invoke:taksBlock:completion: -*/ - -+ (void)cancelRequest:(nonnull MASDataTask*)task error:(NSError*_Nullable*_Nullable)error; -/** -* API to cancel all the pending requests in the queue. -* This is a best effort cancel and uses the underlying cancel functionality of iOS. -* This means there could be scenarios where the request has already been complete and the response is received. In such cases calling cancel has no real meaning. -* All the taks that are pending and not finished yet will be cancelled. There is no guarantee for a callback with error for all the requests. - * Use this when you are sure to cancel all the existing requests and do not really care about the outcome. For example, User moved away from the flow and does not really need any response from earlier tasks. -*/ -+ (void)cancelAllRequests; - # pragma mark - FILE Requests /** @@ -1158,9 +1139,37 @@ withParameters:(NSDictionary *_Nullable)parameterInfo * @param taskBlock Block which gives back handle to the underlying task object. This task can be cancelled by calling cancel on the object. * @param completion An MASResponseObjectErrorBlock (NSHTTPURLResponse *response, id responseObject, NSError *error) that will * receive the NSHTTPURLResponse object, response object which needs to perform type casting based on the object type, and NSError object when error occurs. + @see cancelRequest */ + (void)postMultiPartForm:(nonnull MASRequest *)request constructingBodyWithBlock:(nonnull MASMultiPartFormDataBlock)formDataBlock progress:( MASFileRequestProgressBlock _Nullable )progressBlock taskBlock:(MASDataTaskBlock _Nullable )taskBlock completion:(nullable MASResponseObjectErrorBlock)completion; + +///-------------------------------------- +/// @name Cancel HTTP Requests +///-------------------------------------- +# pragma mark - Cancel APIs + +/** +* API to cancel a pending HTTP request that was invoked using the API invoke:taksBlock:completion: +* This is a best effort cancel and uses the underlying cancel functionality of iOS. +* This means there could be scenarios where the request has already been complete and the response is received. In such cases calling cancel has no real meaning. +* The completion handler returns with an error description that the task has been cancelled. But in some cases if the request has a dependent Task like a login to be completed, then calling cancel on the request may not return a response back as the task has not been started yet. +* Cancelling an already finished task has no effect. +* @param task MASDataTask object that was obtained as a result of invoking a request using the API invoke:taksBlock:completion: +*/ + ++ (void)cancelRequest:(nonnull MASDataTask*)task error:(NSError*_Nullable*_Nullable)error; + + +/** +* API to cancel all the pending requests in the queue. +* This is a best effort cancel and uses the underlying cancel functionality of iOS. +* This means there could be scenarios where the request has already been complete and the response is received. In such cases calling cancel has no real meaning. +* All the taks that are pending and not finished yet will be cancelled. There is no guarantee for a callback with error for all the requests. + * Use this when you are sure to cancel all the existing requests and do not really care about the outcome. For example, User moved away from the flow and does not really need any response from earlier tasks. +*/ ++ (void)cancelAllRequests; + ///-------------------------------------- /// @name JWT Signing ///-------------------------------------- From eb76765bf67dff9ab9f962dc8a10d77f6c92b0be Mon Sep 17 00:00:00 2001 From: Mahendra Date: Wed, 18 Dec 2019 14:59:22 +0530 Subject: [PATCH 07/11] commented an un-necessary log --- .../services/network/internal/MASSessionDataTaskOperation.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m b/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m index 965f0229..1f758336 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m +++ b/MASFoundation/Classes/_private_/services/network/internal/MASSessionDataTaskOperation.m @@ -303,7 +303,7 @@ - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend { - NSLog(@"total bytes sent - %lld total bytes expected %lld",totalBytesSent,totalBytesExpectedToSend); + //DLog(@"total bytes sent - %lld total bytes expected %lld",totalBytesSent,totalBytesExpectedToSend); if(self.fileProgressblock){ //NSProgress* progress = [NSProgress progressWithTotalUnitCount:totalBytesExpectedToSend]; //[progress set] From 616e1d391dd26a66e6a1c14667bf96fee2d70c7d Mon Sep 17 00:00:00 2001 From: Mahendra Date: Wed, 18 Dec 2019 15:02:56 +0530 Subject: [PATCH 08/11] updated license details in the files --- MASFoundation/Classes/MASDataTask.h | 4 +++- MASFoundation/Classes/MASDataTask.m | 4 +++- .../services/network/internal/MASDataTask+MASPrivate.h | 4 +++- .../services/network/internal/MASDataTask+MASPrivate.m | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/MASFoundation/Classes/MASDataTask.h b/MASFoundation/Classes/MASDataTask.h index 8842b848..4be246ef 100644 --- a/MASFoundation/Classes/MASDataTask.h +++ b/MASFoundation/Classes/MASDataTask.h @@ -2,9 +2,11 @@ // MASDataTask.h // MASFoundation // -// Created by nimma01 on 28/11/19. // Copyright © 2019 CA Technologies. All rights reserved. // +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// #import diff --git a/MASFoundation/Classes/MASDataTask.m b/MASFoundation/Classes/MASDataTask.m index 15cd3467..7ddf8e42 100644 --- a/MASFoundation/Classes/MASDataTask.m +++ b/MASFoundation/Classes/MASDataTask.m @@ -2,9 +2,11 @@ // MASDataTask.m // MASFoundation // -// Created by nimma01 on 28/11/19. // Copyright © 2019 CA Technologies. All rights reserved. // +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// #import "MASDataTask.h" #import "MASSessionDataTaskOperation.h" diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h index 15a6ce59..b7fad193 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h +++ b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h @@ -2,9 +2,11 @@ // MASDataTask+MASPrivate.h // MASFoundation // -// Created by nimma01 on 05/12/19. // Copyright © 2019 CA Technologies. All rights reserved. // +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// #import #import "MASDataTask.h" diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m index 9b791774..6486c181 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m +++ b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m @@ -2,9 +2,11 @@ // MASDataTask+MASPrivate.m // MASFoundation // -// Created by nimma01 on 05/12/19. // Copyright © 2019 CA Technologies. All rights reserved. // +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// #import "MASDataTask+MASPrivate.h" From a7e370eeaade6dd1093caa2ce1e7f5f10bfb611e Mon Sep 17 00:00:00 2001 From: Mahendra Date: Thu, 2 Jan 2020 13:41:14 +0530 Subject: [PATCH 09/11] imrpoved error handling for the cancel task --- MASFoundation/Classes/MAS.m | 3 ++- MASFoundation/Classes/MASDataTask.h | 2 -- MASFoundation/Classes/MASDataTask.m | 8 ------- MASFoundation/Classes/MASError.h | 10 ++++++++ .../_private_/categories/NSError+MASPrivate.h | 18 ++++++++++++++ .../_private_/categories/NSError+MASPrivate.m | 24 +++++++++++++++++++ .../services/network/MASNetworkingService.h | 2 +- .../services/network/MASNetworkingService.m | 16 ++++++++++--- .../network/internal/MASDataTask+MASPrivate.h | 1 + .../network/internal/MASDataTask+MASPrivate.m | 12 ++++++++++ 10 files changed, 81 insertions(+), 15 deletions(-) diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index 46826020..a32043de 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -1230,10 +1230,11 @@ + (void)cancelRequest:(nonnull MASDataTask*)task error:(NSError**)error if ([MAS MASState] != MASStateDidStart) { *error = [NSError errorMASIsNotStarted]; + return; } - [[MASNetworkingService sharedService] cancelRequest:task]; + [[MASNetworkingService sharedService] cancelRequest:task error:error]; } + (void)cancelAllRequests diff --git a/MASFoundation/Classes/MASDataTask.h b/MASFoundation/Classes/MASDataTask.h index 4be246ef..0cb29d27 100644 --- a/MASFoundation/Classes/MASDataTask.h +++ b/MASFoundation/Classes/MASDataTask.h @@ -20,8 +20,6 @@ NS_ASSUME_NONNULL_BEGIN @property(readonly)NSString* taskID; -- (void)cancel; - @end NS_ASSUME_NONNULL_END diff --git a/MASFoundation/Classes/MASDataTask.m b/MASFoundation/Classes/MASDataTask.m index 7ddf8e42..9d5ea96e 100644 --- a/MASFoundation/Classes/MASDataTask.m +++ b/MASFoundation/Classes/MASDataTask.m @@ -30,13 +30,5 @@ - (id)init return nil; } -- (void)cancel -{ - if(self.operation && (![self.operation isFinished] && ![self.operation isCancelled])){ - DLog(@"Cancelling task with ID %@",self.taskID); - [self.operation cancel]; - } - -} @end diff --git a/MASFoundation/Classes/MASError.h b/MASFoundation/Classes/MASError.h index 009aa5df..c1894a37 100644 --- a/MASFoundation/Classes/MASError.h +++ b/MASFoundation/Classes/MASError.h @@ -213,6 +213,16 @@ typedef NS_ENUM(NSInteger, MASFoundationErrorCode) // MASFoundationErrorCodeTaskCancelled = 180102, + // + // Data task not found + // + MASFoundationErrorCodeDataTaskNotFound = 180103, + + // + // Data task not cancellable + // + MASFoundationErrorCodeDataTaskNotCancellable = 180104, + MASFoundationErrorCodeCount = -999999 }; diff --git a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.h b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.h index 467df7c6..7942f72b 100644 --- a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.h +++ b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.h @@ -665,4 +665,22 @@ */ + (NSError *)errorDataTaskCancelled; +/** +* Create MASFoundationErrorDomainLocal NSError for MASFoundationDataTaskNotFound. +* +* @return Returns an NSError instance with the domain MASFoundationErrorDomainLocal and +* error MASFoundationDataTaskNotFound +*/ ++ (NSError *)errorDataTaskNotFound; + + +/** +* Create MASFoundationErrorDomainLocal NSError for MASFoundationDataTaskNotFound. +* +* @return Returns an NSError instance with the domain MASFoundationErrorDomainLocal and +* error MASFoundationDataTaskNotFound +*/ ++ (NSError *)errorDataTaskNotCancellable; + + @end diff --git a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m index d15c42df..de9658f8 100644 --- a/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m +++ b/MASFoundation/Classes/_private_/categories/NSError+MASPrivate.m @@ -843,6 +843,16 @@ + (NSError *)errorDataTaskCancelled return [self errorForFoundationCode:MASFoundationErrorCodeTaskCancelled errorDomain:MASFoundationErrorDomainLocal]; } ++ (NSError *)errorDataTaskNotFound +{ + return [self errorForFoundationCode:MASFoundationErrorCodeDataTaskNotFound errorDomain:MASFoundationErrorDomainLocal]; +} + ++ (NSError *)errorDataTaskNotCancellable +{ + return [self errorForFoundationCode:MASFoundationErrorCodeDataTaskNotCancellable errorDomain:MASFoundationErrorDomainLocal]; +} + # pragma mark - Foundation Errors Private @@ -1124,6 +1134,20 @@ + (NSString *)descriptionForFoundationErrorCode:(MASFoundationErrorCode)errorCod // case MASFoundationErrorCodeTaskCancelled : return @"The request has been Cancelled"; + + // + // Task Not found Error + // + + case MASFoundationErrorCodeDataTaskNotFound : return @"The given DataTask is either invalid or does not exist"; + + + // + // Task Can not be Cancelled Error + // + + case MASFoundationErrorCodeDataTaskNotCancellable : return @"Unable to cancel the task. The Task is either finished or cancelled"; + // // Default // diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h index c7638acf..bc70d5c3 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.h @@ -849,7 +849,7 @@ timeoutInterval:(NSTimeInterval)timeoutInterval - (void)httpRequestWithCancel:(MASRequest*)request taskBlock:(MASDataTaskBlock)taskBlock completion:(MASResponseInfoErrorBlock)completion; -- (void)cancelRequest:(MASDataTask*)task; +- (void)cancelRequest:(MASDataTask*)task error:(NSError**)error; - (void)cancelAllRequests; diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m index b9e18291..f66e18df 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m @@ -296,6 +296,7 @@ - (void)serviceWillStop [_gatewayReachabilityManager stopMonitoring]; _sessionManager = nil; } + [self cleanUpFinishedTasks]; [super serviceWillStop]; } @@ -1836,7 +1837,7 @@ - (void)httpRequestWithCancel:(MASRequest*)request taskBlock:(MASDataTaskBlock)t - (void)cacheDataTask:(MASDataTask*)dataTask { - [self cleanUpFinishedTasks]; + //[self cleanUpFinishedTasks]; if(dataTask.taskID){ DLog(@"MASNetworkingService : Added Task with ID %@ to the cache",dataTask.taskID); [self.tasks setObject:dataTask forKey:dataTask.taskID]; @@ -1857,14 +1858,23 @@ - (void)cleanUpFinishedTasks NSLog(@"cleanUpFinishedTasks : finished cleaning up"); } -- (void)cancelRequest:(MASDataTask*)task +- (void)cancelRequest:(MASDataTask*)task error:(NSError**)error; { NSString* taskID = task.taskID; if(self.tasks && [self.tasks objectForKey:taskID]){ MASDataTask* taskToBeCancelled = [self.tasks objectForKey:taskID]; - [taskToBeCancelled cancel]; + BOOL isTaskCancelled = [taskToBeCancelled cancelTask]; [self.tasks removeObjectForKey:taskToBeCancelled.taskID]; + + if (!isTaskCancelled){ + *error = [NSError errorDataTaskNotFound]; + } } + else { + //task not found error + *error = [NSError errorDataTaskNotFound]; + } + } diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h index b7fad193..517c15c3 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h +++ b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.h @@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithTask:(MASSessionDataTaskOperation*)operation; - (BOOL)isFinished; -(BOOL)isCancelled; +- (BOOL)cancelTask; @end diff --git a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m index 6486c181..32c15a65 100644 --- a/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m +++ b/MASFoundation/Classes/_private_/services/network/internal/MASDataTask+MASPrivate.m @@ -44,6 +44,18 @@ -(BOOL)isCancelled return [self.operation isCancelled]; } +- (BOOL)cancelTask +{ + if(self.operation && (![self.operation isFinished] && ![self.operation isCancelled])){ + DLog(@"Cancelling task with ID %@",self.taskID); + [self.operation cancel]; + return YES; + } + + DLog(@"Unable to cancel task. The operation is either finished or cancelled earlier"); + return NO; +} + From 63710b837eef744bbe52dabebe9b880c267b7c04 Mon Sep 17 00:00:00 2001 From: Mahendra Date: Fri, 10 Jan 2020 11:19:33 +0530 Subject: [PATCH 10/11] removed unnecessary erro object in the callback for tasks --- MASFoundation.xcodeproj/project.pbxproj | 25 ++++++++++--------- MASFoundation/Classes/MAS.h | 2 +- MASFoundation/Classes/MAS.m | 4 +-- MASFoundation/Classes/MASConstants.h | 2 +- .../services/network/MASNetworkingService.m | 4 +-- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/MASFoundation.xcodeproj/project.pbxproj b/MASFoundation.xcodeproj/project.pbxproj index d245747e..8c947746 100644 --- a/MASFoundation.xcodeproj/project.pbxproj +++ b/MASFoundation.xcodeproj/project.pbxproj @@ -1797,6 +1797,7 @@ TargetAttributes = { 1059D36F1B61AA3700223267 = { CreatedOnToolsVersion = 6.4; + DevelopmentTeam = 2JJZ96P8P5; ProvisioningStyle = Manual; }; 1059D37A1B61AA3800223267 = { @@ -2082,7 +2083,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; @@ -2131,7 +2132,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; @@ -2159,13 +2160,13 @@ 1059D3871B61AA3800223267 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 2.0.00; DEAD_CODE_STRIPPING = YES; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 2JJZ96P8P5; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -2207,13 +2208,13 @@ 1059D3881B61AA3800223267 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 2.0.00; DEAD_CODE_STRIPPING = YES; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 2JJZ96P8P5; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -2255,7 +2256,7 @@ 1059D38A1B61AA3800223267 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = 2JJZ96P8P5; FRAMEWORK_SEARCH_PATHS = ( @@ -2278,7 +2279,7 @@ 1059D38B1B61AA3800223267 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = 2JJZ96P8P5; FRAMEWORK_SEARCH_PATHS = ( @@ -2297,7 +2298,7 @@ 1059D3BA1B61C00500223267 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; ENABLE_BITCODE = YES; MACH_O_TYPE = staticlib; @@ -2309,7 +2310,7 @@ 1059D3BB1B61C00500223267 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; ENABLE_BITCODE = YES; MACH_O_TYPE = staticlib; diff --git a/MASFoundation/Classes/MAS.h b/MASFoundation/Classes/MAS.h index 4e5f28b6..4222d408 100644 --- a/MASFoundation/Classes/MAS.h +++ b/MASFoundation/Classes/MAS.h @@ -1081,7 +1081,7 @@ withParameters:(NSDictionary *_Nullable)parameterInfo @see cancelRequest */ -+ (void)invoke:(nonnull MASRequest *)request taskBlock:(nullable MASDataTaskBlock)dataTask completion:(nullable MASResponseObjectErrorBlock)completion; ++ (void)invoke:(nonnull MASRequest *)request taskBlock:(nullable MASDataTaskBlock)taskBlock completion:(nullable MASResponseObjectErrorBlock)completion; diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index a32043de..586be88a 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -1139,7 +1139,7 @@ + (void)invoke:(nonnull MASRequest *)request completion:(nullable MASResponseObj } -+ (void)invoke:(nonnull MASRequest *)request taskBlock:(nullable MASDataTaskBlock)dataTask completion:(nullable MASResponseObjectErrorBlock)completion ++ (void)invoke:(nonnull MASRequest *)request taskBlock:(nullable MASDataTaskBlock)taskBlock completion:(nullable MASResponseObjectErrorBlock)completion { __block MASResponseObjectErrorBlock blockCompletion = completion; @@ -1157,7 +1157,7 @@ + (void)invoke:(nonnull MASRequest *)request taskBlock:(nullable MASDataTaskBloc (request.timeoutInterval == MASDefaultNetworkTimeoutConfiguration) ? [self timeoutIntervalForEndpoint:request.endPoint] : request.timeoutInterval; - [MAS httpRouterMethod:request taskBlock:dataTask completion:^(NSDictionary * _Nullable responseInfo, NSError * _Nullable error) { + [MAS httpRouterMethod:request taskBlock:taskBlock completion:^(NSDictionary * _Nullable responseInfo, NSError * _Nullable error) { if (blockCompletion) { blockCompletion([responseInfo objectForKey:MASNSHTTPURLResponseObjectKey], [responseInfo objectForKey:MASResponseInfoBodyInfoKey], error); diff --git a/MASFoundation/Classes/MASConstants.h b/MASFoundation/Classes/MASConstants.h index 33aa4464..4e1db729 100644 --- a/MASFoundation/Classes/MASConstants.h +++ b/MASFoundation/Classes/MASConstants.h @@ -113,7 +113,7 @@ typedef void (^MASResponseObjectErrorBlock)(NSHTTPURLResponse *_Nullable respons /** * The MASDataTaskBlock which contains the dataTask object that is being invoked. Users can typically call cancel on the request using this callback. */ -typedef void (^MASDataTaskBlock)(MASDataTask* _Nullable dataTask,NSError* _Nullable error); +typedef void (^MASDataTaskBlock)(MASDataTask* _Nullable dataTask); /** * The MASUser specific (MASUser *user, NSError *error) block. diff --git a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m index f66e18df..15bc8eee 100644 --- a/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m +++ b/MASFoundation/Classes/_private_/services/network/MASNetworkingService.m @@ -1638,7 +1638,7 @@ - (void)httpFileUploadRequest:(NSString *)endPoint parameters:(NSDictionary *)pa } if(taskBlock){ - taskBlock(newDataTask,nil); + taskBlock(newDataTask); } } @@ -1829,7 +1829,7 @@ - (void)httpRequestWithCancel:(MASRequest*)request taskBlock:(MASDataTaskBlock)t } if(taskBlock){ - taskBlock(newDataTask,nil); + taskBlock(newDataTask); } } From 61493cc7102514b8c5078923c5e8756df4c26fd9 Mon Sep 17 00:00:00 2001 From: Mahendra Date: Fri, 10 Jan 2020 14:13:20 +0530 Subject: [PATCH 11/11] fixed a compilation bug --- MASFoundation/Classes/models/MASBrowserBasedAuthentication.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m index 8a9b792b..a10e97f2 100644 --- a/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m +++ b/MASFoundation/Classes/models/MASBrowserBasedAuthentication.m @@ -197,7 +197,10 @@ - (MASSessionDataTaskHTTPRedirectBlock)getRedirectionBlock blockSelf.webLoginCallBack(nil, YES, nil); } } - return request; + //return a nil request as we would have already cancelled the request + //return a nil as compiler expects a NSURLRequest object + NSURLRequest* nilRequest = nil; + return nilRequest; }; return redirectionBlock;