From 4515d7e07846447a0622ff9b939954f4c34b8c8f Mon Sep 17 00:00:00 2001 From: Jakey Date: Fri, 23 Dec 2016 09:45:55 +0800 Subject: [PATCH] NSURLSession+JKSynchronousTask --- JKCategories-Demo.xcodeproj/project.pbxproj | 14 +++ .../Controller/RootViewController.m | 3 +- .../NSURLSession+JKSynchronousTask.h | 44 ++++++++ .../NSURLSession+JKSynchronousTask.m | 100 ++++++++++++++++++ JKCategories/JKFoundation.h | 1 + README.md | 1 + 6 files changed, 162 insertions(+), 1 deletion(-) create mode 100755 JKCategories/Foundation/NSURLSession/NSURLSession+JKSynchronousTask.h create mode 100755 JKCategories/Foundation/NSURLSession/NSURLSession+JKSynchronousTask.m diff --git a/JKCategories-Demo.xcodeproj/project.pbxproj b/JKCategories-Demo.xcodeproj/project.pbxproj index df3b0f7..e42e1ed 100644 --- a/JKCategories-Demo.xcodeproj/project.pbxproj +++ b/JKCategories-Demo.xcodeproj/project.pbxproj @@ -348,6 +348,7 @@ A2FF6FE71D04334F00320C36 /* NSData+JKPCM.m in Sources */ = {isa = PBXBuildFile; fileRef = A2FF6FE61D04334F00320C36 /* NSData+JKPCM.m */; }; B869399D1CA8EEB500EE7A1A /* UIButton+JKImagePosition.m in Sources */ = {isa = PBXBuildFile; fileRef = B869399C1CA8EEB500EE7A1A /* UIButton+JKImagePosition.m */; }; B87E87E11DFAAFC7008EB83A /* UIWebView+JKLoadInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = B87E87E01DFAAFC7008EB83A /* UIWebView+JKLoadInfo.m */; }; + B87F47971E0CB81900B788C6 /* NSURLSession+JKSynchronousTask.m in Sources */ = {isa = PBXBuildFile; fileRef = B87F47961E0CB81900B788C6 /* NSURLSession+JKSynchronousTask.m */; }; B8A419521DDC07C800BDB39A /* NSString+JKHTML.m in Sources */ = {isa = PBXBuildFile; fileRef = B8A419511DDC07C800BDB39A /* NSString+JKHTML.m */; }; B8C8D1361DED106A0069354F /* UIButton+JKBadge.m in Sources */ = {isa = PBXBuildFile; fileRef = B8C8D1351DED106A0069354F /* UIButton+JKBadge.m */; }; B8C8D1391DED106F0069354F /* UIBarButtonItem+JKBadge.m in Sources */ = {isa = PBXBuildFile; fileRef = B8C8D1381DED106F0069354F /* UIBarButtonItem+JKBadge.m */; }; @@ -980,6 +981,8 @@ B869399C1CA8EEB500EE7A1A /* UIButton+JKImagePosition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+JKImagePosition.m"; sourceTree = ""; }; B87E87DF1DFAAFC7008EB83A /* UIWebView+JKLoadInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIWebView+JKLoadInfo.h"; sourceTree = ""; }; B87E87E01DFAAFC7008EB83A /* UIWebView+JKLoadInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIWebView+JKLoadInfo.m"; sourceTree = ""; }; + B87F47951E0CB81900B788C6 /* NSURLSession+JKSynchronousTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLSession+JKSynchronousTask.h"; sourceTree = ""; }; + B87F47961E0CB81900B788C6 /* NSURLSession+JKSynchronousTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLSession+JKSynchronousTask.m"; sourceTree = ""; }; B8A419501DDC07C800BDB39A /* NSString+JKHTML.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+JKHTML.h"; sourceTree = ""; }; B8A419511DDC07C800BDB39A /* NSString+JKHTML.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+JKHTML.m"; sourceTree = ""; }; B8C8D1341DED106A0069354F /* UIButton+JKBadge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+JKBadge.h"; sourceTree = ""; }; @@ -1431,6 +1434,7 @@ A22725F11A3E736D0061605B /* Foundation */ = { isa = PBXGroup; children = ( + B87F47941E0CB80E00B788C6 /* NSURLSession */, A205E4C81C28E55F002A1E33 /* NSURLConnection */, A205E4BE1C28E42A002A1E33 /* NSInvocation */, A29551B01C22A3B2007962FC /* NSOperation */, @@ -2863,6 +2867,15 @@ name = Frameworks; sourceTree = ""; }; + B87F47941E0CB80E00B788C6 /* NSURLSession */ = { + isa = PBXGroup; + children = ( + B87F47951E0CB81900B788C6 /* NSURLSession+JKSynchronousTask.h */, + B87F47961E0CB81900B788C6 /* NSURLSession+JKSynchronousTask.m */, + ); + path = NSURLSession; + sourceTree = ""; + }; BCB79A091AFDE92200C12525 /* UIAlertView */ = { isa = PBXGroup; children = ( @@ -3055,6 +3068,7 @@ A281FBA31AC8127E009040DA /* NSObjectDemoViewController.m in Sources */, A28BE3781A3EC1C6005C4AC6 /* NSObject+JKAddProperty.m in Sources */, A21F34D21B0F249D00D73A91 /* UIAlertViewDemoViewController.m in Sources */, + B87F47971E0CB81900B788C6 /* NSURLSession+JKSynchronousTask.m in Sources */, A2EF56D21B21C42A0005F730 /* NSManagedObjectContext+JKExtensions.m in Sources */, A280E5251A5233A700E6ACA2 /* UIButton+JKBlock.m in Sources */, A281FBA81AC81299009040DA /* NSSetDemoViewController.m in Sources */, diff --git a/JKCategories-Demo/Controller/RootViewController.m b/JKCategories-Demo/Controller/RootViewController.m index 99d2c40..b682c7a 100644 --- a/JKCategories-Demo/Controller/RootViewController.m +++ b/JKCategories-Demo/Controller/RootViewController.m @@ -77,7 +77,8 @@ - (void)viewDidLoad { @"NSURLRequest", @"NSOperation", @"NSInvocation", - @"NSURLConnection" + @"NSURLConnection", + @"NSURLSession" ], @"CoreLocation":@[@"CALayer", diff --git a/JKCategories/Foundation/NSURLSession/NSURLSession+JKSynchronousTask.h b/JKCategories/Foundation/NSURLSession/NSURLSession+JKSynchronousTask.h new file mode 100755 index 0000000..43642c0 --- /dev/null +++ b/JKCategories/Foundation/NSURLSession/NSURLSession+JKSynchronousTask.h @@ -0,0 +1,44 @@ +// +// NSURLSession+SynchronousTask.h +// +// Copyright (c) 2015 Florian Schliep (http://floschliep.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// https://github.com/floschliep/NSURLSession-SynchronousTask + +#import + +@interface NSURLSession (JKSynchronousTask) + +#pragma mark - NSURLSessionDataTask + +- (nullable NSData *)jk_sendSynchronousDataTaskWithURL:(nonnull NSURL *)url returningResponse:(NSURLResponse *_Nullable*_Nullable)response error:(NSError *_Nullable*_Nullable)error; +- (nullable NSData *)jk_sendSynchronousDataTaskWithRequest:(nonnull NSURLRequest *)request returningResponse:(NSURLResponse *_Nullable*_Nullable)response error:(NSError *_Nullable*_Nullable)error; + +#pragma mark - NSURLSessionDownloadTask + +- (nullable NSURL *)jk_sendSynchronousDownloadTaskWithURL:(nonnull NSURL *)url returningResponse:(NSURLResponse *_Nullable*_Nullable)response error:(NSError *_Nullable*_Nullable)error; +- (nullable NSURL *)jk_sendSynchronousDownloadTaskWithRequest:(nonnull NSURLRequest *)request returningResponse:(NSURLResponse *_Nullable*_Nullable)response error:(NSError *_Nullable*_Nullable)error; + +#pragma mark - NSURLSessionUploadTask + +- (nullable NSData *)jk_sendSynchronousUploadTaskWithRequest:(nonnull NSURLRequest *)request fromFile:(nonnull NSURL *)fileURL returningResponse:(NSURLResponse *_Nullable*_Nullable)response error:(NSError *_Nullable*_Nullable)error; +- (nullable NSData *)jk_sendSynchronousUploadTaskWithRequest:(nonnull NSURLRequest *)request fromData:(nonnull NSData *)bodyData returningResponse:(NSURLResponse *_Nullable*_Nullable)response error:(NSError *_Nullable*_Nullable)error; + +@end diff --git a/JKCategories/Foundation/NSURLSession/NSURLSession+JKSynchronousTask.m b/JKCategories/Foundation/NSURLSession/NSURLSession+JKSynchronousTask.m new file mode 100755 index 0000000..76b8c66 --- /dev/null +++ b/JKCategories/Foundation/NSURLSession/NSURLSession+JKSynchronousTask.m @@ -0,0 +1,100 @@ +// +// NSURLSession+SynchronousTask.m +// +// Copyright (c) 2015 Florian Schliep (http://floschliep.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "NSURLSession+JKSynchronousTask.h" + +@implementation NSURLSession (JKSynchronousTask) + +#pragma mark - NSURLSessionDataTask + +- (nullable NSData *)jk_sendSynchronousDataTaskWithURL:(nonnull NSURL *)url returningResponse:(NSURLResponse *_Nullable*_Nullable)response error:(NSError *_Nullable*_Nullable)error { + return [self jk_sendSynchronousDataTaskWithRequest:[NSURLRequest requestWithURL:url] returningResponse:response error:error]; +} + +- (nullable NSData *)jk_sendSynchronousDataTaskWithRequest:(nonnull NSURLRequest *)request returningResponse:(NSURLResponse *_Nullable*_Nullable)response error:(NSError *_Nullable*_Nullable)error { + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + __block NSData *data = nil; + [[self dataTaskWithRequest:request completionHandler:^(NSData *taskData, NSURLResponse *taskResponse, NSError *taskError) { + data = taskData; + if (response) { + *response = taskResponse; + } + if (error) { + *error = taskError; + } + dispatch_semaphore_signal(semaphore); + }] resume]; + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + + return data; +} + +#pragma mark - NSURLSessionDownloadTask + +- (nullable NSURL *)jk_sendSynchronousDownloadTaskWithURL:(nonnull NSURL *)url returningResponse:(NSURLResponse *_Nullable*_Nullable)response error:(NSError *_Nullable*_Nullable)error { + return [self jk_sendSynchronousDownloadTaskWithRequest:[NSURLRequest requestWithURL:url] returningResponse:response error:error]; +} + +- (nullable NSURL *)jk_sendSynchronousDownloadTaskWithRequest:(nonnull NSURLRequest *)request returningResponse:(NSURLResponse *_Nullable*_Nullable)response error:(NSError *_Nullable*_Nullable)error { + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + __block NSURL *location = nil; + [[self downloadTaskWithRequest:request completionHandler:^(NSURL *taskLocation, NSURLResponse *taskResponse, NSError *taskError) { + location = taskLocation; + if (response) { + *response = taskResponse; + } + if (error) { + *error = taskError; + } + dispatch_semaphore_signal(semaphore); + }] resume]; + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + + return location; +} + +#pragma mark - NSURLSessionUploadTask + +- (nullable NSData *)jk_sendSynchronousUploadTaskWithRequest:(nonnull NSURLRequest *)request fromFile:(nonnull NSURL *)fileURL returningResponse:(NSURLResponse *_Nullable*_Nullable)response error:(NSError *_Nullable*_Nullable)error { + return [self jk_sendSynchronousUploadTaskWithRequest:request fromData:[NSData dataWithContentsOfURL:fileURL] returningResponse:response error:error]; +} + +- (nullable NSData *)jk_sendSynchronousUploadTaskWithRequest:(nonnull NSURLRequest *)request fromData:(nonnull NSData *)bodyData returningResponse:(NSURLResponse *_Nullable*_Nullable)response error:(NSError *_Nullable*_Nullable)error { + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + __block NSData *data = nil; + [[self uploadTaskWithRequest:request fromData:bodyData completionHandler:^(NSData *taskData, NSURLResponse *taskResponse, NSError *taskError) { + data = taskData; + if (response) { + *response = taskResponse; + } + if (error) { + *error = taskError; + } + dispatch_semaphore_signal(semaphore); + }] resume]; + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + + return data; +} + +@end diff --git a/JKCategories/JKFoundation.h b/JKCategories/JKFoundation.h index 960610c..145f6d5 100644 --- a/JKCategories/JKFoundation.h +++ b/JKCategories/JKFoundation.h @@ -86,6 +86,7 @@ #import "NSURL+JKQueryDictionary.h" #import "NSURLConnection+JKSelfSigned.h" #import "NSURLRequest+JKParamsFromDictionary.h" +#import "NSURLSession+JKSynchronousTask.h" #import "NSUserDefaults+JKiCloudSync.h" #import "NSUserDefaults+JKSafeAccess.h" diff --git a/README.md b/README.md index e0fb123..ab9aa76 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ import the header file into any class where you wish to make use of the function * NSOperation * NSInvocation * NSURLConnection +* NSURLSession ### UIKit * UIAlertView