From 75c7a693cca48cec9b025c3bcc571b7e6c7c3021 Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Fri, 11 Sep 2015 14:49:43 +0200 Subject: [PATCH 01/14] Added cache policy support --- SVHTTPRequest/SVHTTPRequest.h | 1 + SVHTTPRequest/SVHTTPRequest.m | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/SVHTTPRequest/SVHTTPRequest.h b/SVHTTPRequest/SVHTTPRequest.h index 8403c52..05e0406 100644 --- a/SVHTTPRequest/SVHTTPRequest.h +++ b/SVHTTPRequest/SVHTTPRequest.h @@ -41,6 +41,7 @@ typedef NSUInteger SVHTTPRequestMethod; - (void)preprocessParameters; - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field; ++ (void)setDefaultCachePolicy:(NSURLRequestCachePolicy)cachePolicy; + (void)setDefaultTimeoutInterval:(NSTimeInterval)interval; + (void)setDefaultUserAgent:(NSString*)userAgent; diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index 044293b..b6fde66 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -31,6 +31,7 @@ - (NSString*)encodedURLParameterString; static NSInteger SVHTTPRequestTaskCount = 0; static NSString *defaultUserAgent; +static NSURLRequestCachePolicy defaultCachePolicy; static NSTimeInterval SVHTTPRequestTimeoutInterval = 20; @interface SVHTTPRequest () @@ -88,6 +89,10 @@ - (void)dealloc { #endif } ++ (void)setDefaultCachePolicy:(NSURLRequestCachePolicy)cachePolicy { + defaultCachePolicy = cachePolicy; +} + + (void)setDefaultTimeoutInterval:(NSTimeInterval)interval { SVHTTPRequestTimeoutInterval = interval; } @@ -400,7 +405,11 @@ - (void)start { [self.operationRequest setTimeoutInterval:self.timeoutInterval]; } - [self.operationRequest setCachePolicy:self.cachePolicy]; + if(defaultCachePolicy) + [self.operationRequest setCachePolicy:defaultCachePolicy]; + else + [self.operationRequest setCachePolicy:self.cachePolicy]; + self.operationConnection = [[NSURLConnection alloc] initWithRequest:self.operationRequest delegate:self startImmediately:NO]; NSOperationQueue *currentQueue = [NSOperationQueue currentQueue]; From b047eb803b273821eb28341305cf94f7c709e40b Mon Sep 17 00:00:00 2001 From: Benoit Date: Wed, 23 Dec 2015 13:46:20 +0100 Subject: [PATCH 02/14] Transition from NSURLConnection to NSURLSession --- SVHTTPRequest/SVHTTPRequest.h | 2 +- SVHTTPRequest/SVHTTPRequest.m | 113 +++++++++++++++------------------- 2 files changed, 52 insertions(+), 63 deletions(-) diff --git a/SVHTTPRequest/SVHTTPRequest.h b/SVHTTPRequest/SVHTTPRequest.h index 05e0406..b458f75 100644 --- a/SVHTTPRequest/SVHTTPRequest.h +++ b/SVHTTPRequest/SVHTTPRequest.h @@ -21,7 +21,7 @@ enum { }; typedef NSUInteger SVHTTPRequestMethod; -@interface SVHTTPRequest : NSOperation +@interface SVHTTPRequest : NSOperation + (SVHTTPRequest*)GET:(NSString*)address parameters:(NSDictionary*)parameters completion:(SVHTTPRequestCompletionHandler)block; + (SVHTTPRequest*)GET:(NSString*)address parameters:(NSDictionary*)parameters saveToPath:(NSString*)savePath progress:(void (^)(float progress))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index b6fde66..1340f79 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -39,7 +39,8 @@ @interface SVHTTPRequest () @property (nonatomic, strong) NSDictionary *parameters; @property (nonatomic, strong) NSMutableData *operationData; @property (nonatomic, strong) NSFileHandle *operationFileHandle; -@property (nonatomic, strong) NSURLConnection *operationConnection; +@property (nonatomic, strong) NSURLSession *operationSession; +@property (nonatomic, strong) NSURLSessionTask *operationSessionTask; @property (nonatomic, strong) NSHTTPURLResponse *operationURLResponse; @property (nonatomic, strong) NSString *operationSavePath; @property (nonatomic, assign) CFRunLoopRef operationRunLoop; @@ -71,7 +72,6 @@ @interface SVHTTPRequest () - (void)addParametersToRequest:(NSDictionary*)paramsDict; - (void)finish; -- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error; - (void)callCompletionBlockWithResponse:(id)response error:(NSError *)error; @end @@ -82,7 +82,7 @@ @implementation SVHTTPRequest @synthesize state = _state; - (void)dealloc { - [_operationConnection cancel]; + [_operationSession invalidateAndCancel]; #if !OS_OBJECT_USE_OBJC dispatch_release(_saveDataDispatchGroup); dispatch_release(_saveDataDispatchQueue); @@ -405,39 +405,30 @@ - (void)start { [self.operationRequest setTimeoutInterval:self.timeoutInterval]; } + NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; + self.operationSession = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil]; + if(defaultCachePolicy) [self.operationRequest setCachePolicy:defaultCachePolicy]; else [self.operationRequest setCachePolicy:self.cachePolicy]; - self.operationConnection = [[NSURLConnection alloc] initWithRequest:self.operationRequest delegate:self startImmediately:NO]; - - NSOperationQueue *currentQueue = [NSOperationQueue currentQueue]; - BOOL inBackgroundAndInOperationQueue = (currentQueue != nil && currentQueue != [NSOperationQueue mainQueue]); - NSRunLoop *targetRunLoop = (inBackgroundAndInOperationQueue) ? [NSRunLoop currentRunLoop] : [NSRunLoop mainRunLoop]; - - if(self.operationSavePath) // schedule on main run loop so scrolling doesn't prevent UI updates of the progress block - [self.operationConnection scheduleInRunLoop:targetRunLoop forMode:NSRunLoopCommonModes]; + if(self.operationSavePath) + self.operationSessionTask = [self.operationSession downloadTaskWithRequest:self.operationRequest]; else - [self.operationConnection scheduleInRunLoop:targetRunLoop forMode:NSDefaultRunLoopMode]; + self.operationSessionTask = [self.operationSession dataTaskWithRequest:self.operationRequest]; - [self.operationConnection start]; + [self.operationSessionTask resume]; #if !(defined SVHTTPREQUEST_DISABLE_LOGGING) NSLog(@"[%@] %@", self.operationRequest.HTTPMethod, self.operationRequest.URL.absoluteString); #endif - - // make NSRunLoop stick around until operation is finished - if(inBackgroundAndInOperationQueue) { - self.operationRunLoop = CFRunLoopGetCurrent(); - CFRunLoopRun(); - } } // private method; not part of NSOperation - (void)finish { - [self.operationConnection cancel]; - self.operationConnection = nil; + [self.operationSession invalidateAndCancel]; + self.operationSession = nil; [self decreaseSVHTTPRequestTaskCount]; @@ -503,28 +494,18 @@ - (void)requestTimeout { failingURL.absoluteString, NSURLErrorFailingURLStringErrorKey, nil]; NSError *timeoutError = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:userInfo]; - [self connection:nil didFailWithError:timeoutError]; + [self URLSession:self.operationSession task:self.operationSessionTask didCompleteWithError:timeoutError]; } -- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler { self.expectedContentLength = response.expectedContentLength; self.receivedContentLength = 0; self.operationURLResponse = (NSHTTPURLResponse*)response; + completionHandler(NSURLSessionResponseAllow); } -- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { dispatch_group_async(self.saveDataDispatchGroup, self.saveDataDispatchQueue, ^{ - if(self.operationSavePath) { - @try { //writeData: can throw exception when there's no disk space. Give an error, don't crash - [self.operationFileHandle writeData:data]; - } - @catch (NSException *exception) { - [self.operationConnection cancel]; - NSError *writeError = [NSError errorWithDomain:@"SVHTTPRequestWriteError" code:0 userInfo:exception.userInfo]; - [self callCompletionBlockWithResponse:nil error:writeError]; - } - } - else [self.operationData appendData:data]; }); @@ -540,40 +521,48 @@ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { } } -- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend { if(self.operationProgressBlock && [self.operationRequest.HTTPMethod isEqualToString:@"POST"]) { - self.operationProgressBlock((float)totalBytesWritten/(float)totalBytesExpectedToWrite); + self.operationProgressBlock((float)totalBytesSent/(float)totalBytesExpectedToSend); } } -- (void)connectionDidFinishLoading:(NSURLConnection *)connection { - dispatch_group_notify(self.saveDataDispatchGroup, self.saveDataDispatchQueue, ^{ - - id response = [NSData dataWithData:self.operationData]; - NSError *error = nil; - - if ([[self.operationURLResponse MIMEType] isEqualToString:@"application/json"]) { - if(self.operationData && self.operationData.length > 0) { - //We parse the string before, because we need it to be UTF-8 in NSJSONSerialization - NSString *utf8String = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]; - if (utf8String == nil) { - utf8String = [[NSString alloc] initWithData:response encoding:NSASCIIStringEncoding]; - } - - NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:[utf8String dataUsingEncoding:NSUTF8StringEncoding] - options:NSJSONReadingAllowFragments error:&error]; - - if(jsonObject) - response = jsonObject; - } - } - - [self callCompletionBlockWithResponse:response error:error]; + +- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { + dispatch_group_async(self.saveDataDispatchGroup, self.saveDataDispatchQueue, ^{ + NSData *fileData = [NSData dataWithContentsOfURL:location]; + [self.operationFileHandle writeData:fileData]; }); } -- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { - [self callCompletionBlockWithResponse:nil error:error]; +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { + if(error) { + [self callCompletionBlockWithResponse:nil error:error]; + } else { + dispatch_group_notify(self.saveDataDispatchGroup, self.saveDataDispatchQueue, ^{ + + id response = [NSData dataWithData:self.operationData]; + NSError *err = nil; + + if ([[self.operationURLResponse MIMEType] isEqualToString:@"application/json"]) { + if(self.operationData && self.operationData.length > 0) { + //We parse the string before, because we need it to be UTF-8 in NSJSONSerialization + NSString *utf8String = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]; + if (utf8String == nil) { + utf8String = [[NSString alloc] initWithData:response encoding:NSASCIIStringEncoding]; + } + + NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:[utf8String dataUsingEncoding:NSUTF8StringEncoding] + options:NSJSONReadingAllowFragments error:&err]; + + if(jsonObject) + response = jsonObject; + } + } + + [self callCompletionBlockWithResponse:response error:err]; + }); + } } - (void)callCompletionBlockWithResponse:(id)response error:(NSError *)error { From c27080cecf210cadee72f23aa8c562f0735c39cb Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Sat, 9 Jan 2016 18:15:12 +0100 Subject: [PATCH 03/14] Removed dispatch group and queue + cleaning code --- SVHTTPRequest/SVHTTPRequest.m | 132 +++++++++++++++------------------- 1 file changed, 57 insertions(+), 75 deletions(-) diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index 1340f79..bbbb60a 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -49,14 +49,6 @@ @interface SVHTTPRequest () @property (nonatomic, readwrite) UIBackgroundTaskIdentifier backgroundTaskIdentifier; #endif -#if !OS_OBJECT_USE_OBJC -@property (nonatomic, assign) dispatch_queue_t saveDataDispatchQueue; -@property (nonatomic, assign) dispatch_group_t saveDataDispatchGroup; -#else -@property (nonatomic, strong) dispatch_queue_t saveDataDispatchQueue; -@property (nonatomic, strong) dispatch_group_t saveDataDispatchGroup; -#endif - @property (nonatomic, copy) SVHTTPRequestCompletionHandler operationCompletionBlock; @property (nonatomic, copy) void (^operationProgressBlock)(float progress); @@ -188,9 +180,6 @@ - (SVHTTPRequest*)initWithAddress:(NSString*)urlString method:(SVHTTPRequestMeth self.operationProgressBlock = progressBlock; self.operationSavePath = savePath; - self.saveDataDispatchGroup = dispatch_group_create(); - self.saveDataDispatchQueue = dispatch_queue_create("com.samvermette.SVHTTPRequest", DISPATCH_QUEUE_SERIAL); - NSURL *url = [[NSURL alloc] initWithString:urlString]; self.operationRequest = [[NSMutableURLRequest alloc] initWithURL:url]; @@ -214,7 +203,7 @@ - (SVHTTPRequest*)initWithAddress:(NSString*)urlString method:(SVHTTPRequestMeth [self.operationRequest setHTTPMethod:@"DELETE"]; else if(method == SVHTTPRequestMethodHEAD) [self.operationRequest setHTTPMethod:@"HEAD"]; - + self.state = SVHTTPRequestStateReady; self.parameters = parameters; @@ -246,7 +235,7 @@ - (void)addParametersToRequest:(NSObject*)parameters { else if([parameters isKindOfClass:[NSDictionary class]]) { __block BOOL hasData = NO; NSDictionary *paramsDict = (NSDictionary*)parameters; - + [paramsDict.allValues enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if([obj isKindOfClass:[NSData class]] || [obj isKindOfClass:[NSURL class]]) hasData = YES; @@ -299,7 +288,7 @@ - (void)addParametersToRequest:(NSObject*)parameters { else { [postData appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; } - + [postData appendData:data]; [postData appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; dataIdx++; @@ -505,9 +494,7 @@ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)data } - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { - dispatch_group_async(self.saveDataDispatchGroup, self.saveDataDispatchQueue, ^{ - [self.operationData appendData:data]; - }); + [self.operationData appendData:data]; if(self.operationProgressBlock) { //If its -1 that means the header does not have the content size value @@ -529,39 +516,34 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSend - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { - dispatch_group_async(self.saveDataDispatchGroup, self.saveDataDispatchQueue, ^{ - NSData *fileData = [NSData dataWithContentsOfURL:location]; - [self.operationFileHandle writeData:fileData]; - }); + NSData *fileData = [NSData dataWithContentsOfURL:location]; + [self.operationFileHandle writeData:fileData]; } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { if(error) { [self callCompletionBlockWithResponse:nil error:error]; } else { - dispatch_group_notify(self.saveDataDispatchGroup, self.saveDataDispatchQueue, ^{ - - id response = [NSData dataWithData:self.operationData]; - NSError *err = nil; - - if ([[self.operationURLResponse MIMEType] isEqualToString:@"application/json"]) { - if(self.operationData && self.operationData.length > 0) { - //We parse the string before, because we need it to be UTF-8 in NSJSONSerialization - NSString *utf8String = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]; - if (utf8String == nil) { - utf8String = [[NSString alloc] initWithData:response encoding:NSASCIIStringEncoding]; - } - - NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:[utf8String dataUsingEncoding:NSUTF8StringEncoding] - options:NSJSONReadingAllowFragments error:&err]; - - if(jsonObject) - response = jsonObject; + id response = [NSData dataWithData:self.operationData]; + NSError *err = nil; + + if ([[self.operationURLResponse MIMEType] isEqualToString:@"application/json"]) { + if(self.operationData && self.operationData.length > 0) { + //We parse the string before, because we need it to be UTF-8 in NSJSONSerialization + NSString *utf8String = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]; + if (utf8String == nil) { + utf8String = [[NSString alloc] initWithData:response encoding:NSASCIIStringEncoding]; } + + NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:[utf8String dataUsingEncoding:NSUTF8StringEncoding] + options:NSJSONReadingAllowFragments error:&err]; + + if(jsonObject) + response = jsonObject; } - - [self callCompletionBlockWithResponse:response error:err]; - }); + } + + [self callCompletionBlockWithResponse:response error:err]; } } @@ -614,7 +596,7 @@ - (NSString*)encodedURLParameterString { NULL, CFSTR(":/=,!$&'()*+;[]@#?^%\"`<>{}\\|~ "), kCFStringEncodingUTF8); - return result; + return result; } @end @@ -633,53 +615,53 @@ - (NSString*)encodedURLParameterString { @implementation NSData (SVHTTPRequest) - (NSString *)base64EncodingWithLineLength:(unsigned int) lineLength { - const unsigned char *bytes = [self bytes]; - NSMutableString *result = [NSMutableString stringWithCapacity:[self length]]; - unsigned long ixtext = 0; - unsigned long lentext = [self length]; - long ctremaining = 0; - unsigned char inbuf[3], outbuf[4]; - short i = 0; - unsigned int charsonline = 0; + const unsigned char *bytes = [self bytes]; + NSMutableString *result = [NSMutableString stringWithCapacity:[self length]]; + unsigned long ixtext = 0; + unsigned long lentext = [self length]; + long ctremaining = 0; + unsigned char inbuf[3], outbuf[4]; + short i = 0; + unsigned int charsonline = 0; short ctcopy = 0; - unsigned long ix = 0; + unsigned long ix = 0; - while( YES ) { - ctremaining = lentext - ixtext; - if( ctremaining <= 0 ) break; + while( YES ) { + ctremaining = lentext - ixtext; + if( ctremaining <= 0 ) break; - for( i = 0; i < 3; i++ ) { - ix = ixtext + i; - if( ix < lentext ) inbuf[i] = bytes[ix]; - else inbuf [i] = 0; - } + for( i = 0; i < 3; i++ ) { + ix = ixtext + i; + if( ix < lentext ) inbuf[i] = bytes[ix]; + else inbuf [i] = 0; + } - outbuf [0] = (inbuf [0] & 0xFC) >> 2; - outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4); - outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6); - outbuf [3] = inbuf [2] & 0x3F; - ctcopy = 4; + outbuf [0] = (inbuf [0] & 0xFC) >> 2; + outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4); + outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6); + outbuf [3] = inbuf [2] & 0x3F; + ctcopy = 4; - switch( ctremaining ) { + switch( ctremaining ) { case 1: ctcopy = 2; break; case 2: ctcopy = 3; break; - } + } - for( i = 0; i < ctcopy; i++ ) - [result appendFormat:@"%c", encodingTable[outbuf[i]]]; + for( i = 0; i < ctcopy; i++ ) + [result appendFormat:@"%c", encodingTable[outbuf[i]]]; - for( i = ctcopy; i < 4; i++ ) - [result appendFormat:@"%c",'=']; + for( i = ctcopy; i < 4; i++ ) + [result appendFormat:@"%c",'=']; - ixtext += 3; - charsonline += 4; - } + ixtext += 3; + charsonline += 4; + } - return result; + return result; } - (BOOL)isJPG { From 36e1031e0cdc73a588fbb8991d4b8cc9a0e519b8 Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Sun, 24 Jan 2016 20:48:12 +0100 Subject: [PATCH 04/14] Changed progress block to pass totalBytes and expectedBytes --- SVHTTPRequest/SVHTTPRequest.h | 4 ++-- SVHTTPRequest/SVHTTPRequest.m | 24 +++++++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/SVHTTPRequest/SVHTTPRequest.h b/SVHTTPRequest/SVHTTPRequest.h index b458f75..f35922b 100644 --- a/SVHTTPRequest/SVHTTPRequest.h +++ b/SVHTTPRequest/SVHTTPRequest.h @@ -24,10 +24,10 @@ typedef NSUInteger SVHTTPRequestMethod; @interface SVHTTPRequest : NSOperation + (SVHTTPRequest*)GET:(NSString*)address parameters:(NSDictionary*)parameters completion:(SVHTTPRequestCompletionHandler)block; -+ (SVHTTPRequest*)GET:(NSString*)address parameters:(NSDictionary*)parameters saveToPath:(NSString*)savePath progress:(void (^)(float progress))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; ++ (SVHTTPRequest*)GET:(NSString*)address parameters:(NSDictionary*)parameters saveToPath:(NSString*)savePath progress:(void (^)(int64_t totalBytes, int64_t totalBytesExpected))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; + (SVHTTPRequest*)POST:(NSString*)address parameters:(NSObject*)parameters completion:(SVHTTPRequestCompletionHandler)block; -+ (SVHTTPRequest*)POST:(NSString *)address parameters:(NSObject *)parameters progress:(void (^)(float))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; ++ (SVHTTPRequest*)POST:(NSString *)address parameters:(NSObject *)parameters progress:(void (^)(int64_t totalBytes, int64_t totalBytesExpected))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; + (SVHTTPRequest*)PUT:(NSString*)address parameters:(NSObject*)parameters completion:(SVHTTPRequestCompletionHandler)block; + (SVHTTPRequest*)DELETE:(NSString*)address parameters:(NSDictionary*)parameters completion:(SVHTTPRequestCompletionHandler)block; diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index bbbb60a..2b1a4c0 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -50,7 +50,7 @@ @interface SVHTTPRequest () #endif @property (nonatomic, copy) SVHTTPRequestCompletionHandler operationCompletionBlock; -@property (nonatomic, copy) void (^operationProgressBlock)(float progress); +@property (nonatomic, copy) void (^operationProgressBlock)(int64_t totalBytes, int64_t totalBytesExpected); @property (nonatomic, readwrite) SVHTTPRequestState state; @property (nonatomic, strong) NSString *requestPath; @@ -126,7 +126,7 @@ + (SVHTTPRequest*)GET:(NSString *)address parameters:(NSDictionary *)parameters return requestObject; } -+ (SVHTTPRequest*)GET:(NSString *)address parameters:(NSDictionary *)parameters saveToPath:(NSString *)savePath progress:(void (^)(float))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { ++ (SVHTTPRequest*)GET:(NSString *)address parameters:(NSDictionary *)parameters saveToPath:(NSString *)savePath progress:(void (^)(int64_t totalBytes, int64_t totalBytesExpected))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { SVHTTPRequest *requestObject = [[self alloc] initWithAddress:address method:SVHTTPRequestMethodGET parameters:parameters saveToPath:savePath progress:progressBlock completion:completionBlock]; [requestObject start]; @@ -140,7 +140,7 @@ + (SVHTTPRequest*)POST:(NSString *)address parameters:(NSObject *)parameters com return requestObject; } -+ (SVHTTPRequest*)POST:(NSString *)address parameters:(NSObject *)parameters progress:(void (^)(float))progressBlock completion:(void (^)(id, NSHTTPURLResponse*, NSError *))completionBlock { ++ (SVHTTPRequest*)POST:(NSString *)address parameters:(NSObject *)parameters progress:(void (^)(int64_t totalBytes, int64_t totalBytesExpected))progressBlock completion:(void (^)(id, NSHTTPURLResponse*, NSError *))completionBlock { SVHTTPRequest *requestObject = [[self alloc] initWithAddress:address method:SVHTTPRequestMethodPOST parameters:parameters saveToPath:nil progress:progressBlock completion:completionBlock]; [requestObject start]; @@ -174,7 +174,7 @@ - (SVHTTPRequest*)initWithAddress:(NSString *)urlString method:(SVHTTPRequestMet return [(id)self initWithAddress:urlString method:method parameters:parameters saveToPath:nil progress:NULL completion:completionBlock]; } -- (SVHTTPRequest*)initWithAddress:(NSString*)urlString method:(SVHTTPRequestMethod)method parameters:(NSDictionary*)parameters saveToPath:(NSString*)savePath progress:(void (^)(float))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { +- (SVHTTPRequest*)initWithAddress:(NSString*)urlString method:(SVHTTPRequestMethod)method parameters:(NSDictionary*)parameters saveToPath:(NSString*)savePath progress:(void (^)(int64_t totalBytes, int64_t totalBytesExpected))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { self = [super init]; self.operationCompletionBlock = completionBlock; self.operationProgressBlock = progressBlock; @@ -500,17 +500,27 @@ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)data //If its -1 that means the header does not have the content size value if(self.expectedContentLength != -1) { self.receivedContentLength += data.length; - self.operationProgressBlock(self.receivedContentLength/self.expectedContentLength); + self.operationProgressBlock(self.receivedContentLength, self.expectedContentLength); } else { //we dont know the full size so always return -1 as the progress - self.operationProgressBlock(-1); + self.operationProgressBlock(-1, -1); } } } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend { if(self.operationProgressBlock && [self.operationRequest.HTTPMethod isEqualToString:@"POST"]) { - self.operationProgressBlock((float)totalBytesSent/(float)totalBytesExpectedToSend); + dispatch_async(dispatch_get_main_queue(), ^{ + self.operationProgressBlock(totalBytesSent, totalBytesExpectedToSend); + }); + } +} + +- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { + if(self.operationProgressBlock) { + dispatch_async(dispatch_get_main_queue(), ^{ + self.operationProgressBlock(totalBytesWritten, totalBytesExpectedToWrite); + }); } } From e6e9cad784b1dcdf17a29b314979af1a4bdaa4a1 Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Wed, 27 Jan 2016 14:41:27 +0100 Subject: [PATCH 05/14] Added missing UIKit framework import for use with Swift --- SVHTTPRequest/SVHTTPRequest.m | 1 + 1 file changed, 1 insertion(+) diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index 2b1a4c0..4d56bee 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -7,6 +7,7 @@ // https://github.com/samvermette/SVHTTPRequest // +#import #import "SVHTTPRequest.h" @interface NSData (Base64) From 2e20ce4e0f2bb5451e49ebd46a72fa141731ef91 Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Thu, 28 Jan 2016 15:44:13 +0100 Subject: [PATCH 06/14] Added a definition for the progress handler block --- SVHTTPRequest/SVHTTPClient.h | 5 +++-- SVHTTPRequest/SVHTTPClient.m | 8 ++++---- SVHTTPRequest/SVHTTPRequest.h | 4 ++-- SVHTTPRequest/SVHTTPRequest.m | 10 +++++----- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/SVHTTPRequest/SVHTTPClient.h b/SVHTTPRequest/SVHTTPClient.h index 5c94860..fca535a 100644 --- a/SVHTTPRequest/SVHTTPClient.h +++ b/SVHTTPRequest/SVHTTPClient.h @@ -10,6 +10,7 @@ #import typedef void (^SVHTTPRequestCompletionHandler)(id response, NSHTTPURLResponse *urlResponse, NSError *error); +typedef void (^SVHTTPRequestProgressHandler)(int64_t totalBytes, int64_t totalBytesExpected); @class SVHTTPRequest; @@ -22,10 +23,10 @@ typedef void (^SVHTTPRequestCompletionHandler)(id response, NSHTTPURLResponse *u - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field; - (SVHTTPRequest*)GET:(NSString*)path parameters:(NSDictionary*)parameters completion:(SVHTTPRequestCompletionHandler)completionBlock; -- (SVHTTPRequest*)GET:(NSString*)path parameters:(NSDictionary*)parameters saveToPath:(NSString*)savePath progress:(void (^)(float progress))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; +- (SVHTTPRequest*)GET:(NSString*)path parameters:(NSDictionary*)parameters saveToPath:(NSString*)savePath progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; - (SVHTTPRequest*)POST:(NSString*)path parameters:(NSObject*)parameters completion:(SVHTTPRequestCompletionHandler)completionBlock; -- (SVHTTPRequest*)POST:(NSString*)path parameters:(NSObject*)parameters progress:(void (^)(float progress))progressBlock completion:(void (^)(id response, NSHTTPURLResponse *urlResponse, NSError *error))completionBlock; +- (SVHTTPRequest*)POST:(NSString*)path parameters:(NSObject*)parameters progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; - (SVHTTPRequest*)PUT:(NSString*)path parameters:(NSObject*)parameters completion:(SVHTTPRequestCompletionHandler)completionBlock; - (SVHTTPRequest*)DELETE:(NSString*)path parameters:(NSDictionary*)parameters completion:(SVHTTPRequestCompletionHandler)completionBlock; diff --git a/SVHTTPRequest/SVHTTPClient.m b/SVHTTPRequest/SVHTTPClient.m index eb561af..10d0e32 100644 --- a/SVHTTPRequest/SVHTTPClient.m +++ b/SVHTTPRequest/SVHTTPClient.m @@ -18,7 +18,7 @@ - (SVHTTPRequest*)queueRequest:(NSString*)path method:(SVHTTPRequestMethod)method parameters:(NSDictionary*)parameters saveToPath:(NSString*)savePath - progress:(void (^)(float))progressBlock + progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; @property (nonatomic, strong) NSMutableDictionary *HTTPHeaderFields; @@ -74,7 +74,7 @@ - (SVHTTPRequest*)GET:(NSString *)path parameters:(NSDictionary *)parameters com return [self queueRequest:path method:SVHTTPRequestMethodGET parameters:parameters saveToPath:nil progress:nil completion:completionBlock]; } -- (SVHTTPRequest*)GET:(NSString *)path parameters:(NSDictionary *)parameters saveToPath:(NSString *)savePath progress:(void (^)(float))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { +- (SVHTTPRequest*)GET:(NSString *)path parameters:(NSDictionary *)parameters saveToPath:(NSString *)savePath progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { return [self queueRequest:path method:SVHTTPRequestMethodGET parameters:parameters saveToPath:savePath progress:progressBlock completion:completionBlock]; } @@ -82,7 +82,7 @@ - (SVHTTPRequest*)POST:(NSString *)path parameters:(NSDictionary *)parameters co return [self queueRequest:path method:SVHTTPRequestMethodPOST parameters:parameters saveToPath:nil progress:nil completion:completionBlock]; } -- (SVHTTPRequest*)POST:(NSString *)path parameters:(NSDictionary *)parameters progress:(void (^)(float))progressBlock completion:(void (^)(id, NSHTTPURLResponse*, NSError *))completionBlock { +- (SVHTTPRequest*)POST:(NSString *)path parameters:(NSDictionary *)parameters progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { return [self queueRequest:path method:SVHTTPRequestMethodPOST parameters:parameters saveToPath:nil progress:progressBlock completion:completionBlock]; } @@ -129,7 +129,7 @@ - (SVHTTPRequest*)queueRequest:(NSString*)path method:(SVHTTPRequestMethod)method parameters:(NSDictionary*)parameters saveToPath:(NSString*)savePath - progress:(void (^)(float))progressBlock + progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { NSString *completeURLString = [NSString stringWithFormat:@"%@%@", self.basePath, path]; diff --git a/SVHTTPRequest/SVHTTPRequest.h b/SVHTTPRequest/SVHTTPRequest.h index f35922b..1cfe019 100644 --- a/SVHTTPRequest/SVHTTPRequest.h +++ b/SVHTTPRequest/SVHTTPRequest.h @@ -27,7 +27,7 @@ typedef NSUInteger SVHTTPRequestMethod; + (SVHTTPRequest*)GET:(NSString*)address parameters:(NSDictionary*)parameters saveToPath:(NSString*)savePath progress:(void (^)(int64_t totalBytes, int64_t totalBytesExpected))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; + (SVHTTPRequest*)POST:(NSString*)address parameters:(NSObject*)parameters completion:(SVHTTPRequestCompletionHandler)block; -+ (SVHTTPRequest*)POST:(NSString *)address parameters:(NSObject *)parameters progress:(void (^)(int64_t totalBytes, int64_t totalBytesExpected))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; ++ (SVHTTPRequest*)POST:(NSString *)address parameters:(NSObject *)parameters progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; + (SVHTTPRequest*)PUT:(NSString*)address parameters:(NSObject*)parameters completion:(SVHTTPRequestCompletionHandler)block; + (SVHTTPRequest*)DELETE:(NSString*)address parameters:(NSDictionary*)parameters completion:(SVHTTPRequestCompletionHandler)block; @@ -65,7 +65,7 @@ typedef NSUInteger SVHTTPRequestMethod; method:(SVHTTPRequestMethod)method parameters:(NSObject*)parameters saveToPath:(NSString*)savePath - progress:(void (^)(float))progressBlock + progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; - (void)signRequestWithUsername:(NSString*)username password:(NSString*)password; diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index 4d56bee..58921ad 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -51,7 +51,7 @@ @interface SVHTTPRequest () #endif @property (nonatomic, copy) SVHTTPRequestCompletionHandler operationCompletionBlock; -@property (nonatomic, copy) void (^operationProgressBlock)(int64_t totalBytes, int64_t totalBytesExpected); +@property (nonatomic, copy) SVHTTPRequestProgressHandler operationProgressBlock; @property (nonatomic, readwrite) SVHTTPRequestState state; @property (nonatomic, strong) NSString *requestPath; @@ -127,7 +127,7 @@ + (SVHTTPRequest*)GET:(NSString *)address parameters:(NSDictionary *)parameters return requestObject; } -+ (SVHTTPRequest*)GET:(NSString *)address parameters:(NSDictionary *)parameters saveToPath:(NSString *)savePath progress:(void (^)(int64_t totalBytes, int64_t totalBytesExpected))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { ++ (SVHTTPRequest*)GET:(NSString *)address parameters:(NSDictionary *)parameters saveToPath:(NSString *)savePath progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { SVHTTPRequest *requestObject = [[self alloc] initWithAddress:address method:SVHTTPRequestMethodGET parameters:parameters saveToPath:savePath progress:progressBlock completion:completionBlock]; [requestObject start]; @@ -141,7 +141,7 @@ + (SVHTTPRequest*)POST:(NSString *)address parameters:(NSObject *)parameters com return requestObject; } -+ (SVHTTPRequest*)POST:(NSString *)address parameters:(NSObject *)parameters progress:(void (^)(int64_t totalBytes, int64_t totalBytesExpected))progressBlock completion:(void (^)(id, NSHTTPURLResponse*, NSError *))completionBlock { ++ (SVHTTPRequest*)POST:(NSString *)address parameters:(NSObject *)parameters progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { SVHTTPRequest *requestObject = [[self alloc] initWithAddress:address method:SVHTTPRequestMethodPOST parameters:parameters saveToPath:nil progress:progressBlock completion:completionBlock]; [requestObject start]; @@ -162,7 +162,7 @@ + (SVHTTPRequest*)DELETE:(NSString *)address parameters:(NSDictionary *)paramete return requestObject; } -+ (SVHTTPRequest*)HEAD:(NSString *)address parameters:(NSDictionary *)parameters completion:(void (^)(id, NSHTTPURLResponse *, NSError *))block { ++ (SVHTTPRequest*)HEAD:(NSString *)address parameters:(NSDictionary *)parameters completion:(SVHTTPRequestCompletionHandler)block { SVHTTPRequest *requestObject = [[self alloc] initWithAddress:address method:SVHTTPRequestMethodHEAD parameters:parameters saveToPath:nil progress:nil completion:block]; [requestObject start]; @@ -175,7 +175,7 @@ - (SVHTTPRequest*)initWithAddress:(NSString *)urlString method:(SVHTTPRequestMet return [(id)self initWithAddress:urlString method:method parameters:parameters saveToPath:nil progress:NULL completion:completionBlock]; } -- (SVHTTPRequest*)initWithAddress:(NSString*)urlString method:(SVHTTPRequestMethod)method parameters:(NSDictionary*)parameters saveToPath:(NSString*)savePath progress:(void (^)(int64_t totalBytes, int64_t totalBytesExpected))progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { +- (SVHTTPRequest*)initWithAddress:(NSString*)urlString method:(SVHTTPRequestMethod)method parameters:(NSDictionary*)parameters saveToPath:(NSString*)savePath progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { self = [super init]; self.operationCompletionBlock = completionBlock; self.operationProgressBlock = progressBlock; From 2d51958838b0c2fb311c21ec3779e90fd82f1661 Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Thu, 28 Jan 2016 15:44:38 +0100 Subject: [PATCH 07/14] Removed deprecated method since iOS 9 --- SVHTTPRequest/SVHTTPRequest.m | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index 58921ad..97d712e 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -602,12 +602,8 @@ - (void)callCompletionBlockWithResponse:(id)response error:(NSError *)error { @implementation NSString (SVHTTPRequest) - (NSString*)encodedURLParameterString { - NSString *result = (__bridge_transfer NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, - (__bridge CFStringRef)self, - NULL, - CFSTR(":/=,!$&'()*+;[]@#?^%\"`<>{}\\|~ "), - kCFStringEncodingUTF8); - return result; + NSString *result = [self stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet characterSetWithCharactersInString:@":/=,!$&'()*+;[]@#?^%\"`<>{}\\|~ "]]; + return result; } @end From 36b27ccd8fc07f92feedfee485ff3400cfb6d9b1 Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Thu, 28 Jan 2016 15:45:12 +0100 Subject: [PATCH 08/14] Added PUT HTTP method with progress block --- SVHTTPRequest/SVHTTPClient.h | 1 + SVHTTPRequest/SVHTTPClient.m | 4 ++++ SVHTTPRequest/SVHTTPRequest.h | 1 + SVHTTPRequest/SVHTTPRequest.m | 7 +++++++ 4 files changed, 13 insertions(+) diff --git a/SVHTTPRequest/SVHTTPClient.h b/SVHTTPRequest/SVHTTPClient.h index fca535a..d28ac9e 100644 --- a/SVHTTPRequest/SVHTTPClient.h +++ b/SVHTTPRequest/SVHTTPClient.h @@ -28,6 +28,7 @@ typedef void (^SVHTTPRequestProgressHandler)(int64_t totalBytes, int64_t totalBy - (SVHTTPRequest*)POST:(NSString*)path parameters:(NSObject*)parameters completion:(SVHTTPRequestCompletionHandler)completionBlock; - (SVHTTPRequest*)POST:(NSString*)path parameters:(NSObject*)parameters progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; - (SVHTTPRequest*)PUT:(NSString*)path parameters:(NSObject*)parameters completion:(SVHTTPRequestCompletionHandler)completionBlock; +- (SVHTTPRequest*)PUT:(NSString*)path parameters:(NSObject*)parameters progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; - (SVHTTPRequest*)DELETE:(NSString*)path parameters:(NSDictionary*)parameters completion:(SVHTTPRequestCompletionHandler)completionBlock; - (SVHTTPRequest*)HEAD:(NSString*)path parameters:(NSDictionary*)parameters completion:(SVHTTPRequestCompletionHandler)completionBlock; diff --git a/SVHTTPRequest/SVHTTPClient.m b/SVHTTPRequest/SVHTTPClient.m index 10d0e32..1bb6b4c 100644 --- a/SVHTTPRequest/SVHTTPClient.m +++ b/SVHTTPRequest/SVHTTPClient.m @@ -90,6 +90,10 @@ - (SVHTTPRequest*)PUT:(NSString *)path parameters:(NSDictionary *)parameters com return [self queueRequest:path method:SVHTTPRequestMethodPUT parameters:parameters saveToPath:nil progress:nil completion:completionBlock]; } +- (SVHTTPRequest*)PUT:(NSString *)path parameters:(NSDictionary *)parameters progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { + return [self queueRequest:path method:SVHTTPRequestMethodPUT parameters:parameters saveToPath:nil progress:progressBlock completion:completionBlock]; +} + - (SVHTTPRequest*)DELETE:(NSString *)path parameters:(NSDictionary *)parameters completion:(SVHTTPRequestCompletionHandler)completionBlock { return [self queueRequest:path method:SVHTTPRequestMethodDELETE parameters:parameters saveToPath:nil progress:nil completion:completionBlock]; } diff --git a/SVHTTPRequest/SVHTTPRequest.h b/SVHTTPRequest/SVHTTPRequest.h index 1cfe019..4a6437d 100644 --- a/SVHTTPRequest/SVHTTPRequest.h +++ b/SVHTTPRequest/SVHTTPRequest.h @@ -29,6 +29,7 @@ typedef NSUInteger SVHTTPRequestMethod; + (SVHTTPRequest*)POST:(NSString*)address parameters:(NSObject*)parameters completion:(SVHTTPRequestCompletionHandler)block; + (SVHTTPRequest*)POST:(NSString *)address parameters:(NSObject *)parameters progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; + (SVHTTPRequest*)PUT:(NSString*)address parameters:(NSObject*)parameters completion:(SVHTTPRequestCompletionHandler)block; ++ (SVHTTPRequest*)PUT:(NSString *)address parameters:(NSObject *)parameters progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock; + (SVHTTPRequest*)DELETE:(NSString*)address parameters:(NSDictionary*)parameters completion:(SVHTTPRequestCompletionHandler)block; + (SVHTTPRequest*)HEAD:(NSString*)address parameters:(NSDictionary*)parameters completion:(SVHTTPRequestCompletionHandler)block; diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index 97d712e..0208d60 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -155,6 +155,13 @@ + (SVHTTPRequest*)PUT:(NSString *)address parameters:(NSObject *)parameters comp return requestObject; } ++ (SVHTTPRequest*)PUT:(NSString *)address parameters:(NSObject *)parameters progress:(SVHTTPRequestProgressHandler)progressBlock completion:(SVHTTPRequestCompletionHandler)completionBlock { + SVHTTPRequest *requestObject = [[self alloc] initWithAddress:address method:SVHTTPRequestMethodPUT parameters:parameters saveToPath:nil progress:progressBlock completion:completionBlock]; + [requestObject start]; + + return requestObject; +} + + (SVHTTPRequest*)DELETE:(NSString *)address parameters:(NSDictionary *)parameters completion:(SVHTTPRequestCompletionHandler)block { SVHTTPRequest *requestObject = [[self alloc] initWithAddress:address method:SVHTTPRequestMethodDELETE parameters:parameters saveToPath:nil progress:nil completion:block]; [requestObject start]; From 3276314ee0d9b636d0fc536d7c303195d792e9d1 Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Sun, 19 Jun 2016 18:36:49 +0200 Subject: [PATCH 09/14] Added Accept-Language header --- SVHTTPRequest/SVHTTPRequest.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index 0208d60..d46284c 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -389,6 +389,8 @@ - (void)start { else if(defaultUserAgent) [self.operationRequest setValue:defaultUserAgent forHTTPHeaderField:@"User-Agent"]; + [self.operationRequest setValue:[[NSLocale currentLocale] localeIdentifier] forHTTPHeaderField:@"Accept-Language"]; + [self willChangeValueForKey:@"isExecuting"]; self.state = SVHTTPRequestStateExecuting; [self didChangeValueForKey:@"isExecuting"]; From cfaf9a577fff9d1efb8f6451785d1dfb47cf2458 Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Wed, 14 Jun 2017 21:53:26 +0200 Subject: [PATCH 10/14] Added application/javascript as a valid MIME type for json contents --- SVHTTPRequest/SVHTTPRequest.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index d46284c..48e7180 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -547,7 +547,7 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didComp id response = [NSData dataWithData:self.operationData]; NSError *err = nil; - if ([[self.operationURLResponse MIMEType] isEqualToString:@"application/json"]) { + if ([[self.operationURLResponse MIMEType] isEqualToString:@"application/json"] || [[self.operationURLResponse MIMEType] isEqualToString:@"application/javascript"]) { if(self.operationData && self.operationData.length > 0) { //We parse the string before, because we need it to be UTF-8 in NSJSONSerialization NSString *utf8String = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]; From b89617c99e46a6f4d424c157b281f84dd6a5937c Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Sat, 17 Jun 2017 21:55:04 +0200 Subject: [PATCH 11/14] Changed preprocessor macro because __has_feature(attribute_availability_app_extension) always returns true if Xcode can build extensions --- SVHTTPRequest/SVHTTPRequest.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index 48e7180..b3bf0c5 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -111,7 +111,7 @@ - (void)decreaseSVHTTPRequestTaskCount { } - (void)toggleNetworkActivityIndicator { -#if TARGET_OS_IPHONE && !__has_feature(attribute_availability_app_extension) +#if TARGET_OS_IOS dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:(SVHTTPRequestTaskCount > 0)]; }); From 6c601209eebca0b9d6b5df9f4e179fbf7ae999b0 Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Mon, 26 Jun 2017 22:08:10 +0200 Subject: [PATCH 12/14] Added SV_APP_EXTENSION test --- SVHTTPRequest/SVHTTPRequest.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index b3bf0c5..f2c6c44 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -369,8 +369,8 @@ - (void)start { } [self preprocessParameters]; - -#if TARGET_OS_IPHONE && !__has_feature(attribute_availability_app_extension) + +#if TARGET_OS_IPHONE && !(defined SV_APP_EXTENSION) // all requests should complete and run completion block unless we explicitely cancel them. self.backgroundTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ if(self.backgroundTaskIdentifier != UIBackgroundTaskInvalid) { @@ -431,7 +431,7 @@ - (void)finish { [self decreaseSVHTTPRequestTaskCount]; -#if TARGET_OS_IPHONE && !__has_feature(attribute_availability_app_extension) +#if TARGET_OS_IPHONE && !(defined SV_APP_EXTENSION) if(self.backgroundTaskIdentifier != UIBackgroundTaskInvalid) { [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskIdentifier]; self.backgroundTaskIdentifier = UIBackgroundTaskInvalid; From 512aaa4f05e6084557e7089170b3aef7bf58d98c Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Mon, 26 Jun 2017 22:10:34 +0200 Subject: [PATCH 13/14] Added missing test for app extension --- SVHTTPRequest/SVHTTPRequest.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index f2c6c44..76361b6 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -111,7 +111,7 @@ - (void)decreaseSVHTTPRequestTaskCount { } - (void)toggleNetworkActivityIndicator { -#if TARGET_OS_IOS +#if TARGET_OS_IOS && !(defined SV_APP_EXTENSION) dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:(SVHTTPRequestTaskCount > 0)]; }); From f9d1a31e6415fbd7b90cc14f60022e6754f0ef7b Mon Sep 17 00:00:00 2001 From: Benoit Deldicque Date: Fri, 16 Feb 2018 22:55:08 +0100 Subject: [PATCH 14/14] Fixed Xcode warning --- SVHTTPRequest/SVHTTPRequest.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SVHTTPRequest/SVHTTPRequest.m b/SVHTTPRequest/SVHTTPRequest.m index 76361b6..6dd5d6d 100644 --- a/SVHTTPRequest/SVHTTPRequest.m +++ b/SVHTTPRequest/SVHTTPRequest.m @@ -352,8 +352,10 @@ - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field { - (void)setTimeoutTimer:(NSTimer *)newTimer { - if(_timeoutTimer) - [_timeoutTimer invalidate], _timeoutTimer = nil; + if(_timeoutTimer) { + [_timeoutTimer invalidate]; + _timeoutTimer = nil; + } if(newTimer) _timeoutTimer = newTimer;