Skip to content

Commit 23ff1ad

Browse files
author
Evadne Wu
committed
WIP
- adds NSURLConnection delegate method interceptor - uses request context and cleans up interface - fixes up categories on the request context for form URL encoding and multipart data generation - initial options transforming kludge in anticipation of late evaluation vanquishing entire hack
1 parent 4415bee commit 23ff1ad

27 files changed

Lines changed: 990 additions & 863 deletions

‎IRRemoteResourcesManager.m‎

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -380,32 +380,36 @@ - (void) retrieveResourceAtURL:(NSURL *)anURL usingPriority:(NSOperationQueuePri
380380

381381
}
382382

383-
__block __typeof__(self) nrSelf = self;
383+
__weak IRRemoteResourcesManager *wSelf = self;
384384

385-
[nrSelf performInBackground: ^ {
385+
[wSelf performInBackground: ^ {
386386

387-
__block IRRemoteResourceDownloadOperation *operation = [self operationWithURL:anURL];
387+
IRRemoteResourceDownloadOperation *operation = [wSelf operationWithURL:anURL];
388388

389389
if (!operation) {
390390

391-
operation = [self prospectiveOperationForURL:anURL enqueue:YES];
391+
operation = [wSelf prospectiveOperationForURL:anURL enqueue:YES];
392392
operation.queuePriority = priority;
393393

394-
[nrSelf addOperation:operation];
394+
__weak IRRemoteResourceDownloadOperation *wOperation = operation;
395+
396+
[wSelf addOperation:operation];
395397
[operation appendCompletionBlock:^{
396-
[nrSelf removeOperation:operation];
398+
[wSelf removeOperation:wOperation];
397399
}];
398400

399401
} else {
400402

401-
if (forcesReload && [nrSelf.queue.operations containsObject:operation]) {
403+
if (forcesReload && [wSelf.queue.operations containsObject:operation]) {
402404

403405
operation = [operation continuationOperationCancellingCurrentOperation:YES];
404406
operation.queuePriority = priority;
405407

406-
[nrSelf addOperation:operation];
408+
__weak IRRemoteResourceDownloadOperation *wOperation = operation;
409+
410+
[wSelf addOperation:operation];
407411
[operation appendCompletionBlock:^{
408-
[nrSelf removeOperation:operation];
412+
[wSelf removeOperation:wOperation];
409413
}];
410414

411415
}
@@ -420,15 +424,15 @@ - (void) retrieveResourceAtURL:(NSURL *)anURL usingPriority:(NSOperationQueuePri
420424

421425
if (![[NSFileManager defaultManager] fileExistsAtPath:capturedPath]) {
422426

423-
[nrSelf performInBackground:^{
427+
[wSelf performInBackground:^{
424428
aBlock(nil);
425429
}];
426430

427431
return;
428432

429433
}
430434

431-
[nrSelf performInBackground: ^ {
435+
[wSelf performInBackground: ^ {
432436

433437
NSCParameterAssert([[NSFileManager defaultManager] fileExistsAtPath:capturedPath]);
434438
aBlock([NSURL fileURLWithPath:capturedPath]);
@@ -443,7 +447,7 @@ - (void) retrieveResourceAtURL:(NSURL *)anURL usingPriority:(NSOperationQueuePri
443447

444448
[self beginSuspendingOperationQueue];
445449

446-
[nrSelf performInBackground: ^ {
450+
[wSelf performInBackground: ^ {
447451

448452
[self enqueueOperationsIfNeeded];
449453

‎IRWebAPIEngine+ExternalTransforms.m‎

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,31 @@
77
//
88

99
#import "IRWebAPIEngine+ExternalTransforms.h"
10+
#import "IRWebAPIRequestContext.h"
11+
#import "IRWebAPIHelpers.h"
1012

1113
@interface IRWebAPIEngine (ExternalTransforms_KnownPrivate)
1214

13-
- (NSDictionary *) baseRequestContextWithMethodName:(NSString *)inMethodName arguments:(NSDictionary *)inArgumentsOrNil options:(NSDictionary *)inOptionsOrNil;
15+
- (IRWebAPIRequestContext *) baseRequestContextWithMethodName:(NSString *)inMethodName arguments:(NSDictionary *)inArgumentsOrNil options:(NSDictionary *)inOptionsOrNil;
1416

15-
- (NSDictionary *) requestContextByTransformingContext:(NSDictionary *)inContext forMethodNamed:(NSString *)inMethodName;
17+
- (IRWebAPIRequestContext *) requestContextByTransformingContext:(IRWebAPIRequestContext *)inContext forMethodNamed:(NSString *)inMethodName;
1618

17-
- (NSURLRequest *) requestWithContext:(NSDictionary *)inContext;
19+
- (NSURLRequest *) requestWithContext:(IRWebAPIRequestContext *)inContext;
1820

1921
@end
2022

2123
@implementation IRWebAPIEngine (ExternalTransforms)
2224

2325
- (NSURLRequest *) transformedRequestWithRequest:(NSURLRequest *)aRequest usingMethodName:(NSString *)aName {
2426

25-
NSDictionary *baseContext = [self baseRequestContextWithMethodName:aName arguments:nil options:nil];
27+
IRWebAPIRequestContext *baseContext = [self baseRequestContextWithMethodName:aName arguments:nil options:nil];
2628

27-
NSURL *baseURL = [baseContext objectForKey:kIRWebAPIEngineRequestHTTPBaseURL];
28-
NSDictionary *headerFields = [baseContext objectForKey:kIRWebAPIEngineRequestHTTPHeaderFields];
29-
NSDictionary *arguments = [baseContext objectForKey:kIRWebAPIEngineRequestHTTPQueryParameters];
30-
NSData *httpBody = [baseContext objectForKey:kIRWebAPIEngineRequestHTTPBody];
31-
NSString *httpMethod = [baseContext objectForKey:kIRWebAPIEngineRequestHTTPMethod];
32-
IRWebAPIResponseParser responseParser = [baseContext objectForKey:kIRWebAPIEngineParser];
29+
NSURL *baseURL = baseContext.baseURL;
30+
NSDictionary *headerFields = baseContext.headerFields;
31+
NSDictionary *arguments = baseContext.queryParams;
32+
NSData *httpBody = baseContext.body;
33+
NSString *httpMethod = baseContext.method;
34+
IRWebAPIResponseParser responseParser = baseContext.parser;
3335

3436
if ([[aRequest allHTTPHeaderFields] count])
3537
headerFields = [aRequest allHTTPHeaderFields];
@@ -59,22 +61,20 @@ - (NSURLRequest *) transformedRequestWithRequest:(NSURLRequest *)aRequest usingM
5961

6062
}
6163

62-
NSDictionary *inferredContext = [NSDictionary dictionaryWithObjectsAndKeys:
64+
IRWebAPIRequestContext *inferredContext = [IRWebAPIRequestContext new];
65+
inferredContext.baseURL = baseURL;
66+
[headerFields enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
67+
[inferredContext setValue:obj forHeaderField:key];
68+
}];
69+
[arguments enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
70+
[inferredContext setValue:obj forQueryParam:key];
71+
}];
72+
inferredContext.body = httpBody;
73+
inferredContext.method = httpMethod;
74+
inferredContext.parser = responseParser;
6375

64-
baseURL, kIRWebAPIEngineRequestHTTPBaseURL,
65-
headerFields, kIRWebAPIEngineRequestHTTPHeaderFields,
66-
arguments, kIRWebAPIEngineRequestHTTPQueryParameters,
67-
httpBody, kIRWebAPIEngineRequestHTTPBody,
68-
httpMethod, kIRWebAPIEngineRequestHTTPMethod,
69-
responseParser, kIRWebAPIEngineParser,
70-
aName, kIRWebAPIEngineIncomingMethodName,
71-
72-
nil];
73-
74-
NSDictionary *transformedContext = [self requestContextByTransformingContext:inferredContext forMethodNamed:aName];
75-
NSURLRequest *returnedRequest = [self requestWithContext:transformedContext];
76-
77-
return returnedRequest;
76+
IRWebAPIRequestContext *transformedContext = [self requestContextByTransformingContext:inferredContext forMethodNamed:aName];
77+
return [[IRWebAPIRequestOperation alloc] initWithContext:transformedContext].request;
7878

7979
}
8080

‎IRWebAPIEngine+FormMultipart.h‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,20 @@
77
//
88

99
#import "IRWebAPIEngine.h"
10+
#import "IRWebAPIRequestContext.h"
1011

12+
@interface IRWebAPIRequestContext (FormMultipart)
1113

12-
extern NSString * const kIRWebAPIEngineRequestContextFormMultipartFieldsKey;
14+
@property (nonatomic, readonly, copy) NSDictionary *formMultipartFields;
15+
- (void) removeAllFormMultipartFieldValues;
16+
- (void) setValue:(id)obj forFormMultipartField:(NSString *)key;
17+
18+
@end
1319

1420
@interface IRWebAPIEngine (FormMultipart)
1521

1622
+ (IRWebAPIRequestContextTransformer) defaultFormMultipartTransformer;
1723

1824
@end
25+
26+
extern NSString * const kIRWebAPIEngineRequestContextFormMultipartFieldsKey;

‎IRWebAPIEngine+FormMultipart.m‎

Lines changed: 64 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,57 +6,90 @@
66
// Copyright 2011 Iridia Productions. All rights reserved.
77
//
88

9+
#import <objc/runtime.h>
910
#import "IRWebAPIEngine+FormMultipart.h"
10-
1111
#import "IRWebAPIEngine+LocalCaching.h"
12+
#import "IRWebAPIHelpers.h"
1213

1314
NSString * const kIRWebAPIEngineRequestContextFormMultipartFieldsKey = @"kIRWebAPIEngineRequestContextFormMultipartFieldsKey";
1415

16+
static NSString * const kFormMultipartFields = @"-[IRWebAPIRequestContext(FormMultipart) formMultipartFields]";
17+
18+
@implementation IRWebAPIRequestContext (FormMultipart)
19+
20+
- (NSDictionary *) formMultipartFields {
21+
22+
NSMutableDictionary *formMultipartFields = objc_getAssociatedObject(self, &kFormMultipartFields);
23+
24+
if (!formMultipartFields) {
25+
formMultipartFields = [NSMutableDictionary dictionary];
26+
objc_setAssociatedObject(self, &kFormMultipartFields, formMultipartFields, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
27+
}
28+
29+
return [formMultipartFields copy];
30+
31+
}
32+
33+
- (void) removeAllFormMultipartFieldValues {
34+
35+
[self willChangeValueForKey:@"formMultipartFields"];
36+
objc_setAssociatedObject(self, &kFormMultipartFields, nil, OBJC_ASSOCIATION_ASSIGN);
37+
[self didChangeValueForKey:@"formMultipartFields"];
38+
39+
}
40+
41+
- (void) setValue:(id)obj forFormMultipartField:(NSString *)key {
42+
43+
NSMutableDictionary *formMultipartFields = objc_getAssociatedObject(self, &kFormMultipartFields);
44+
45+
if (!formMultipartFields) {
46+
formMultipartFields = [NSMutableDictionary dictionary];
47+
objc_setAssociatedObject(self, &kFormMultipartFields, formMultipartFields, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
48+
}
49+
50+
[self willChangeValueForKey:@"formMultipartFields"];
51+
52+
if (obj) {
53+
[formMultipartFields setObject:obj forKey:key];
54+
} else {
55+
[formMultipartFields removeObjectForKey:key];
56+
}
57+
58+
[self didChangeValueForKey:@"formMultipartFields"];
59+
60+
}
61+
62+
@end
63+
1564
@implementation IRWebAPIEngine (FormMultipart)
1665

1766
+ (IRWebAPIRequestContextTransformer) defaultFormMultipartTransformer {
1867

19-
return [(^ (NSDictionary *inOriginalContext) {
68+
return [(^ (IRWebAPIRequestContext *context) {
2069

21-
NSDictionary *formNamesToContents = [inOriginalContext objectForKey:kIRWebAPIEngineRequestContextFormMultipartFieldsKey];
22-
23-
if(!formNamesToContents || ([formNamesToContents count] == 0))
24-
return inOriginalContext;
70+
NSDictionary *formNamesToContents = context.formMultipartFields;
2571

26-
NSMutableDictionary *returnedContext = [inOriginalContext mutableCopy];
72+
if (![formNamesToContents count])
73+
return context;
2774

2875
NSError *error;
2976
NSURL *fileHandleURL = [[self class] newTemporaryFileURL];
3077

3178
if (![[NSFileManager defaultManager] createFileAtPath:[fileHandleURL path] contents:[NSData data] attributes:nil]) {
32-
3379
NSLog(@"Error creating file for URL %@.", fileHandleURL);
34-
return (NSDictionary *)returnedContext;
35-
80+
return context;
3681
}
3782

3883
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingToURL:fileHandleURL error:&error];
3984
if (!fileHandle) {
40-
4185
NSLog(@"Error grabbing file handle for URL %@: %@", fileHandleURL, error);
42-
return (NSDictionary *)returnedContext;
43-
86+
return context;
4487
}
4588

4689
[fileHandle truncateFileAtOffset:0];
4790
[fileHandle seekToEndOfFile];
4891

49-
50-
NSMutableDictionary *headerFields = [returnedContext objectForKey:kIRWebAPIEngineRequestHTTPHeaderFields];
51-
if (!headerFields) {
52-
53-
headerFields = [NSMutableDictionary dictionary];
54-
[returnedContext setObject:headerFields forKey:kIRWebAPIEngineRequestHTTPHeaderFields];
55-
56-
}
57-
58-
[headerFields setObject:@"8bit" forKey:@"Content-Transfer-Encoding"];
59-
92+
[context setValue:@"8bit" forHeaderField:@"Content-Transfer-Encoding"];
6093

6194
NSString *mineBoundary = [NSString stringWithFormat:@"----_=_%@_%@_%@_=_----",
6295

@@ -70,7 +103,8 @@ + (IRWebAPIRequestContextTransformer) defaultFormMultipartTransformer {
70103
NSData *newLineData = [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding];
71104
NSData *separatorData = [@"--" dataUsingEncoding:NSUTF8StringEncoding];
72105

73-
[headerFields setObject:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", mineBoundary] forKey:@"Content-Type"];
106+
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", mineBoundary];
107+
[context setValue:contentType forHeaderField:@"Content-Type"];
74108

75109
// Start writing
76110

@@ -148,24 +182,12 @@ + (IRWebAPIRequestContextTransformer) defaultFormMultipartTransformer {
148182

149183
[fileHandle closeFile];
150184

151-
[returnedContext setObject:[NSData dataWithContentsOfMappedFile:[fileHandleURL path]] forKey:kIRWebAPIEngineRequestHTTPBody];
152-
153-
154-
NSMutableArray *temporaryFileURLs = [returnedContext objectForKey:kIRWebAPIEngineRequestContextLocalCachingTemporaryFileURLsKey];
155-
if (!temporaryFileURLs) {
156-
157-
temporaryFileURLs = [NSMutableArray array];
158-
[returnedContext setObject:temporaryFileURLs forKey:kIRWebAPIEngineRequestContextLocalCachingTemporaryFileURLsKey];
159-
160-
}
161-
162-
[temporaryFileURLs addObject:fileHandleURL];
163-
164-
[returnedContext setObject:temporaryFileURLs forKey:kIRWebAPIEngineRequestContextLocalCachingTemporaryFileURLsKey];
165-
[returnedContext removeObjectForKey:kIRWebAPIEngineRequestContextFormMultipartFieldsKey];
166-
[returnedContext setObject:@"POST" forKey:kIRWebAPIEngineRequestHTTPMethod];
185+
[context setBody:[NSData dataWithContentsOfMappedFile:[fileHandleURL path]]];
186+
[context addCacheFileURL:fileHandleURL];
187+
[context removeAllFormMultipartFieldValues];
188+
[context setMethod:@"POST"];
167189

168-
return (NSDictionary *)returnedContext;
190+
return context;
169191

170192
}) copy];
171193

‎IRWebAPIEngine+FormURLEncoding.h‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@
88

99
#import "IRWebAPIEngine.h"
1010

11-
extern NSString * const kIRWebAPIEngineRequestContextFormURLEncodingFieldsKey;
11+
@interface IRWebAPIRequestContext (FormURLEncoding)
1212

13-
NSData * IRWebAPIEngineFormURLEncodedDataWithDictionary (NSDictionary *dictionary);
13+
@property (nonatomic, readonly, copy) NSDictionary *formURLEncodingFields;
14+
- (void) removeAllFormURLEncodingFieldValues;
15+
- (void) setValue:(id)obj forFormURLEncodingField:(NSString *)key;
16+
17+
@end
1418

1519
@interface IRWebAPIEngine (FormURLEncoding)
1620

1721
+ (IRWebAPIRequestContextTransformer) defaultFormURLEncodingTransformer;
1822

1923
@end
24+
25+
extern NSData * IRWebAPIEngineFormURLEncodedDataWithDictionary (NSDictionary *formNamesToContents);

0 commit comments

Comments
 (0)