1010#import " STHTTPNetTask.h"
1111#import " STHTTPNetTaskParametersPacker.h"
1212#import " STNetTaskQueueLog.h"
13+ #import < objc/runtime.h>
1314
1415static uint8_t const STBase64EncodingTable[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ;
1516static NSString * STBase64String (NSString *string)
5253 return [NSString stringWithString: encodedString];
5354}
5455
56+ @interface NSURLSessionTask (STHTTPNetTaskQueueHandler)
57+
58+ @property (nonatomic , strong , readonly ) NSData *data;
59+ @property (nonatomic , copy ) void (^completionBlock)(NSURLSessionTask *, NSError *);
60+
61+ - (void )appendData : (NSData *)data ;
62+
63+ @end
64+
65+ @implementation NSURLSessionTask (STHTTPNetTaskQueueHandler)
66+
67+ - (void )appendData : (NSData *)data
68+ {
69+ NSMutableData *mutableData = objc_getAssociatedObject (self, @selector (data ));
70+ if (!mutableData) {
71+ mutableData = [NSMutableData new ];
72+ objc_setAssociatedObject (self, @selector (data ), mutableData, OBJC_ASSOCIATION_RETAIN_NONATOMIC );
73+ }
74+ [mutableData appendData: data];
75+ }
76+
77+ - (NSData *)data
78+ {
79+ NSMutableData *data = objc_getAssociatedObject (self, @selector (data ));
80+ return [NSData dataWithData: data];
81+ }
82+
83+ - (void )setCompletionBlock : (void (^)(NSURLSessionTask *, NSError *))completionBlock
84+ {
85+ objc_setAssociatedObject (self, @selector (completionBlock ), completionBlock, OBJC_ASSOCIATION_COPY_NONATOMIC );
86+ }
87+
88+ - (void (^)(NSURLSessionTask *, NSError *))completionBlock
89+ {
90+ return objc_getAssociatedObject (self, @selector (completionBlock ));
91+ }
92+
93+ @end
94+
95+ @interface STHTTPNetTaskQueueHandler () <NSURLSessionDataDelegate >
96+
97+ @end
98+
5599@implementation STHTTPNetTaskQueueHandler
56100{
57101 NSURL *_baseURL;
@@ -70,7 +114,7 @@ - (instancetype)initWithBaseURL:(NSURL *)baseURL configuration:(NSURLSessionConf
70114{
71115 if (self = [super init ]) {
72116 _baseURL = baseURL;
73- _urlSession = [NSURLSession sessionWithConfiguration: configuration];
117+ _urlSession = [NSURLSession sessionWithConfiguration: configuration delegate: self delegateQueue: nil ];
74118 _methodMap = @{ @(STHTTPNetTaskGet): @" GET" ,
75119 @(STHTTPNetTaskDelete): @" DELETE" ,
76120 @(STHTTPNetTaskHead): @" HEAD" ,
@@ -105,8 +149,48 @@ - (void)netTaskQueue:(STNetTaskQueue *)netTaskQueue handleTask:(STNetTask *)task
105149 [request setValue: [NSString stringWithFormat: @" Basic %@ " , STBase64String (credentials)] forHTTPHeaderField: @" Authorization" ];
106150 }
107151
108- void (^completionHandler)(NSData *, NSURLResponse *, NSError *) = ^(NSData *data, NSURLResponse *response, NSError *error) {
109- NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
152+ switch (httpTask.method ) {
153+ case STHTTPNetTaskGet:
154+ case STHTTPNetTaskHead:
155+ case STHTTPNetTaskDelete: {
156+ NSURLComponents *urlComponents = [NSURLComponents componentsWithURL: [_baseURL URLByAppendingPathComponent: httpTask.uri]
157+ resolvingAgainstBaseURL: NO ];
158+ if (parameters.count ) {
159+ urlComponents.query = [self queryStringFromParameters: parameters];
160+ }
161+ request.URL = urlComponents.URL ;
162+ sessionTask = [_urlSession dataTaskWithRequest: request];
163+ }
164+ break ;
165+ case STHTTPNetTaskPost:
166+ case STHTTPNetTaskPut:
167+ case STHTTPNetTaskPatch: {
168+ request.URL = [_baseURL URLByAppendingPathComponent: httpTask.uri];
169+ NSDictionary *datas = httpTask.datas ;
170+ if (!datas.count ) {
171+ request.HTTPBody = [self bodyDataFromParameters: parameters requestType: httpTask.requestType];
172+ [request setValue: _contentTypeMap[@(httpTask.requestType)] forHTTPHeaderField: @" Content-Type" ];
173+ sessionTask = [_urlSession dataTaskWithRequest: request];
174+ }
175+ else {
176+ NSString *contentType = [NSString stringWithFormat: @" multipart/form-data; boundary=%@ " , _formDataBoundary];
177+ [request setValue: contentType forHTTPHeaderField: @" Content-Type" ];
178+ sessionTask = [_urlSession uploadTaskWithRequest: request
179+ fromData: [self formDataFromParameters: parameters datas: datas]];
180+ }
181+ }
182+ break ;
183+ default : {
184+ NSAssert (NO , @" Invalid STHTTPNetTaskMethod" );
185+ }
186+ break ;
187+ }
188+
189+ [httpTask setValue: sessionTask forKey: @" sessionTask" ];
190+
191+ sessionTask.completionBlock = ^(NSURLSessionTask *sessionTask, NSError *error) {
192+ NSData *data = sessionTask.data ;
193+ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)sessionTask.response ;
110194 if (httpResponse.statusCode >= 200 && httpResponse.statusCode < 300 ) {
111195 id responseObj = nil ;
112196 NSError *error = nil ;
@@ -128,7 +212,7 @@ - (void)netTaskQueue:(STNetTaskQueue *)netTaskQueue handleTask:(STNetTask *)task
128212 [STNetTaskQueueLog log: @" Response parsed error: %@ " , exception.debugDescription];
129213 error = [NSError errorWithDomain: STHTTPNetTaskResponseParsedError
130214 code: 0
131- userInfo: @{ @" url" : response .URL .absoluteString }];
215+ userInfo: @{ @" url" : httpResponse .URL .absoluteString }];
132216 }
133217 }
134218 break ;
@@ -140,7 +224,7 @@ - (void)netTaskQueue:(STNetTaskQueue *)netTaskQueue handleTask:(STNetTask *)task
140224 [STNetTaskQueueLog log: @" Response parsed error: %@ " , error.debugDescription];
141225 error = [NSError errorWithDomain: STHTTPNetTaskResponseParsedError
142226 code: 0
143- userInfo: @{ @" url" : response .URL .absoluteString }];
227+ userInfo: @{ @" url" : httpResponse .URL .absoluteString }];
144228 }
145229 }
146230 else {
@@ -168,46 +252,6 @@ - (void)netTaskQueue:(STNetTaskQueue *)netTaskQueue handleTask:(STNetTask *)task
168252 [netTaskQueue task: task didFailWithError: error];
169253 }
170254 };
171-
172- switch (httpTask.method ) {
173- case STHTTPNetTaskGet:
174- case STHTTPNetTaskHead:
175- case STHTTPNetTaskDelete: {
176- NSURLComponents *urlComponents = [NSURLComponents componentsWithURL: [_baseURL URLByAppendingPathComponent: httpTask.uri]
177- resolvingAgainstBaseURL: NO ];
178- if (parameters.count ) {
179- urlComponents.query = [self queryStringFromParameters: parameters];
180- }
181- request.URL = urlComponents.URL ;
182- sessionTask = [_urlSession dataTaskWithRequest: request completionHandler: completionHandler];
183- }
184- break ;
185- case STHTTPNetTaskPost:
186- case STHTTPNetTaskPut:
187- case STHTTPNetTaskPatch: {
188- request.URL = [_baseURL URLByAppendingPathComponent: httpTask.uri];
189- NSDictionary *datas = httpTask.datas ;
190- if (!datas.count ) {
191- request.HTTPBody = [self bodyDataFromParameters: parameters requestType: httpTask.requestType];
192- [request setValue: _contentTypeMap[@(httpTask.requestType)] forHTTPHeaderField: @" Content-Type" ];
193- sessionTask = [_urlSession dataTaskWithRequest: request completionHandler: completionHandler];
194- }
195- else {
196- NSString *contentType = [NSString stringWithFormat: @" multipart/form-data; boundary=%@ " , _formDataBoundary];
197- [request setValue: contentType forHTTPHeaderField: @" Content-Type" ];
198- sessionTask = [_urlSession uploadTaskWithRequest: request
199- fromData: [self formDataFromParameters: parameters datas: datas]
200- completionHandler: completionHandler];
201- }
202- }
203- break ;
204- default : {
205- NSAssert (NO , @" Invalid STHTTPNetTaskMethod" );
206- }
207- break ;
208- }
209-
210- [httpTask setValue: sessionTask forKey: @" sessionTask" ];
211255 [sessionTask resume ];
212256}
213257
@@ -223,6 +267,21 @@ - (void)netTaskQueue:(STNetTaskQueue *)netTaskQueue didCancelTask:(STNetTask *)t
223267 [httpTask setValue: nil forKey: @" sessionTask" ];
224268}
225269
270+ - (void )netTaskQueueDidBecomeInactive : (STNetTaskQueue *)netTaskQueue
271+ {
272+ [_urlSession invalidateAndCancel ];
273+ }
274+
275+ - (void )URLSession : (NSURLSession *)session dataTask : (NSURLSessionDataTask *)dataTask didReceiveData : (NSData *)data
276+ {
277+ [dataTask appendData: data];
278+ }
279+
280+ - (void )URLSession : (NSURLSession *)session task : (NSURLSessionTask *)task didCompleteWithError : (NSError *)error
281+ {
282+ task.completionBlock (task, error);
283+ }
284+
226285- (NSString *)queryStringFromParameters : (NSDictionary *)parameters
227286{
228287 if (!parameters.count ) {
0 commit comments