Ben Copsey

Added requestStarted delegate methods to ASIHTTPRequest and ASINetworkQueue

Added delegate method tests
Thanks to Lu for the code!

Also, fixed progress tests on Mac OS, broken as a result of the recent fix relating to setMaxValue: for iPhone
@@ -234,6 +234,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; @@ -234,6 +234,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount;
234 // This lock prevents the operation from being cancelled at an inopportune moment 234 // This lock prevents the operation from being cancelled at an inopportune moment
235 NSRecursiveLock *cancelledLock; 235 NSRecursiveLock *cancelledLock;
236 236
  237 + // Called on the delegate when the request starts
  238 + SEL didStartSelector;
  239 +
237 // Called on the delegate when the request completes successfully 240 // Called on the delegate when the request completes successfully
238 SEL didFinishSelector; 241 SEL didFinishSelector;
239 242
@@ -394,6 +397,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; @@ -394,6 +397,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount;
394 397
395 #pragma mark handling request complete / failure 398 #pragma mark handling request complete / failure
396 399
  400 +// Called when a request starts, lets the delegate now via didStartSelector
  401 +- (void)requestStarted;
  402 +
397 // Called when a request completes successfully, lets the delegate now via didFinishSelector 403 // Called when a request completes successfully, lets the delegate now via didFinishSelector
398 - (void)requestFinished; 404 - (void)requestFinished;
399 405
@@ -588,6 +594,7 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; @@ -588,6 +594,7 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount;
588 @property (assign) BOOL useSessionPersistance; 594 @property (assign) BOOL useSessionPersistance;
589 @property (retain) NSString *downloadDestinationPath; 595 @property (retain) NSString *downloadDestinationPath;
590 @property (retain) NSString *temporaryFileDownloadPath; 596 @property (retain) NSString *temporaryFileDownloadPath;
  597 +@property (assign) SEL didStartSelector;
591 @property (assign) SEL didFinishSelector; 598 @property (assign) SEL didFinishSelector;
592 @property (assign) SEL didFailSelector; 599 @property (assign) SEL didFailSelector;
593 @property (retain,readonly) NSString *authenticationRealm; 600 @property (retain,readonly) NSString *authenticationRealm;
@@ -185,6 +185,7 @@ static BOOL isiPhoneOS2; @@ -185,6 +185,7 @@ static BOOL isiPhoneOS2;
185 [self setUseCookiePersistance:YES]; 185 [self setUseCookiePersistance:YES];
186 [self setValidatesSecureCertificate:YES]; 186 [self setValidatesSecureCertificate:YES];
187 [self setRequestCookies:[[[NSMutableArray alloc] init] autorelease]]; 187 [self setRequestCookies:[[[NSMutableArray alloc] init] autorelease]];
  188 + [self setDidStartSelector:@selector(requestStarted:)];
188 [self setDidFinishSelector:@selector(requestFinished:)]; 189 [self setDidFinishSelector:@selector(requestFinished:)];
189 [self setDidFailSelector:@selector(requestFailed:)]; 190 [self setDidFailSelector:@selector(requestFailed:)];
190 [self setURL:newURL]; 191 [self setURL:newURL];
@@ -643,6 +644,8 @@ static BOOL isiPhoneOS2; @@ -643,6 +644,8 @@ static BOOL isiPhoneOS2;
643 return; 644 return;
644 } 645 }
645 646
  647 + [self requestStarted];
  648 +
646 [self setAuthenticationLock:[[[NSConditionLock alloc] initWithCondition:1] autorelease]]; 649 [self setAuthenticationLock:[[[NSConditionLock alloc] initWithCondition:1] autorelease]];
647 650
648 [self setComplete:NO]; 651 [self setComplete:NO];
@@ -1252,6 +1255,23 @@ static BOOL isiPhoneOS2; @@ -1252,6 +1255,23 @@ static BOOL isiPhoneOS2;
1252 1255
1253 #pragma mark handling request complete / failure 1256 #pragma mark handling request complete / failure
1254 1257
  1258 +
  1259 +- (void)requestStarted
  1260 +{
  1261 + if ([self error] || [self mainRequest]) {
  1262 + return;
  1263 + }
  1264 + // Let the queue know we have started
  1265 + if ([[self queue] respondsToSelector:@selector(requestDidStart:)]) {
  1266 + [[self queue] performSelectorOnMainThread:@selector(requestDidStart:) withObject:self waitUntilDone:[NSThread isMainThread]];
  1267 + }
  1268 +
  1269 + // Let the delegate know we have started
  1270 + if ([self didStartSelector] && [[self delegate] respondsToSelector:[self didStartSelector]]) {
  1271 + [[self delegate] performSelectorOnMainThread:[self didStartSelector] withObject:self waitUntilDone:[NSThread isMainThread]];
  1272 + }
  1273 +}
  1274 +
1255 // Subclasses might override this method to process the result in the same thread 1275 // Subclasses might override this method to process the result in the same thread
1256 // If you do this, don't forget to call [super requestFinished] to let the queue / delegate know we're done 1276 // If you do this, don't forget to call [super requestFinished] to let the queue / delegate know we're done
1257 - (void)requestFinished 1277 - (void)requestFinished
@@ -3108,6 +3128,7 @@ static BOOL isiPhoneOS2; @@ -3108,6 +3128,7 @@ static BOOL isiPhoneOS2;
3108 @synthesize useCookiePersistance; 3128 @synthesize useCookiePersistance;
3109 @synthesize downloadDestinationPath; 3129 @synthesize downloadDestinationPath;
3110 @synthesize temporaryFileDownloadPath; 3130 @synthesize temporaryFileDownloadPath;
  3131 +@synthesize didStartSelector;
3111 @synthesize didFinishSelector; 3132 @synthesize didFinishSelector;
3112 @synthesize didFailSelector; 3133 @synthesize didFailSelector;
3113 @synthesize authenticationRealm; 3134 @synthesize authenticationRealm;
@@ -13,6 +13,9 @@ @@ -13,6 +13,9 @@
13 // Delegate will get didFail + didFinish messages (if set) 13 // Delegate will get didFail + didFinish messages (if set)
14 id delegate; 14 id delegate;
15 15
  16 + // Will be called when a request starts with the request as the argument
  17 + SEL requestDidStartSelector;
  18 +
16 // Will be called when a request completes with the request as the argument 19 // Will be called when a request completes with the request as the argument
17 SEL requestDidFinishSelector; 20 SEL requestDidFinishSelector;
18 21
@@ -99,6 +102,7 @@ @@ -99,6 +102,7 @@
99 @property (assign,setter=setUploadProgressDelegate:) id uploadProgressDelegate; 102 @property (assign,setter=setUploadProgressDelegate:) id uploadProgressDelegate;
100 @property (assign,setter=setDownloadProgressDelegate:) id downloadProgressDelegate; 103 @property (assign,setter=setDownloadProgressDelegate:) id downloadProgressDelegate;
101 104
  105 +@property (assign) SEL requestDidStartSelector;
102 @property (assign) SEL requestDidFinishSelector; 106 @property (assign) SEL requestDidFinishSelector;
103 @property (assign) SEL requestDidFailSelector; 107 @property (assign) SEL requestDidFailSelector;
104 @property (assign) SEL queueDidFinishSelector; 108 @property (assign) SEL queueDidFinishSelector;
@@ -177,6 +177,13 @@ @@ -177,6 +177,13 @@
177 177
178 } 178 }
179 179
  180 +- (void)requestDidStart:(ASIHTTPRequest *)request
  181 +{
  182 + if ([self requestDidStartSelector]) {
  183 + [[self delegate] performSelector:[self requestDidStartSelector] withObject:request];
  184 + }
  185 +}
  186 +
180 - (void)requestDidFail:(ASIHTTPRequest *)request 187 - (void)requestDidFail:(ASIHTTPRequest *)request
181 { 188 {
182 [self setRequestsCount:[self requestsCount]-1]; 189 [self setRequestsCount:[self requestsCount]-1];
@@ -331,6 +338,7 @@ @@ -331,6 +338,7 @@
331 @synthesize shouldCancelAllRequestsOnFailure; 338 @synthesize shouldCancelAllRequestsOnFailure;
332 @synthesize uploadProgressDelegate; 339 @synthesize uploadProgressDelegate;
333 @synthesize downloadProgressDelegate; 340 @synthesize downloadProgressDelegate;
  341 +@synthesize requestDidStartSelector;
334 @synthesize requestDidFinishSelector; 342 @synthesize requestDidFinishSelector;
335 @synthesize requestDidFailSelector; 343 @synthesize requestDidFailSelector;
336 @synthesize queueDidFinishSelector; 344 @synthesize queueDidFinishSelector;
@@ -12,9 +12,13 @@ @@ -12,9 +12,13 @@
12 12
13 @interface ASIHTTPRequestTests : ASITestCase { 13 @interface ASIHTTPRequestTests : ASITestCase {
14 float progress; 14 float progress;
  15 + BOOL started;
  16 + BOOL finished;
  17 + BOOL failed;
15 } 18 }
16 19
17 - (void)testBasicDownload; 20 - (void)testBasicDownload;
  21 +- (void)testDelegateMethods;
18 - (void)testConditionalGET; 22 - (void)testConditionalGET;
19 - (void)testException; 23 - (void)testException;
20 - (void)testTimeOut; 24 - (void)testTimeOut;
@@ -65,6 +65,85 @@ @@ -65,6 +65,85 @@
65 GHAssertTrue(success,@"Failed to generate an error for a bad host"); 65 GHAssertTrue(success,@"Failed to generate an error for a bad host");
66 } 66 }
67 67
  68 +- (void)testDelegateMethods
  69 +{
  70 + started = NO;
  71 + finished = NO;
  72 + failed = NO;
  73 +
  74 + // Test default delegate methods
  75 + ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
  76 + [request setDelegate:self];
  77 + [request start];
  78 + GHAssertTrue(started,@"Failed to call the delegate method when the request started");
  79 + GHAssertTrue(finished,@"Failed to call the delegate method when the request finished");
  80 +
  81 + request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
  82 + [request setDelegate:self];
  83 + [request setTimeOutSeconds:0.01];
  84 + [request start];
  85 + GHAssertTrue(failed,@"Failed to call the delegate method when the request failed");
  86 +
  87 + started = NO;
  88 + finished = NO;
  89 + failed = NO;
  90 +
  91 + // Test custom delegate methods
  92 + request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
  93 + [request setDelegate:self];
  94 + [request setDidStartSelector:@selector(delegateTestStarted:)];
  95 + [request setDidFinishSelector:@selector(delegateTestFinished:)];
  96 + [request start];
  97 +
  98 + // Hacky, but this test won't run on the main thread, we have to hope the delegate methods will be called in this time
  99 + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
  100 +
  101 + GHAssertTrue(started,@"Failed to call the delegate method when the request started");
  102 + GHAssertTrue(finished,@"Failed to call the delegate method when the request finished");
  103 +
  104 + request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
  105 + [request setDidFailSelector:@selector(delegateTestFailed:)];
  106 + [request setDelegate:self];
  107 + [request setTimeOutSeconds:0.01];
  108 + [request start];
  109 +
  110 + // Hacky, but this test won't run on the main thread, we have to hope the delegate methods will be called in this time
  111 + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
  112 +
  113 + GHAssertTrue(failed,@"Failed to call the delegate method when the request failed");
  114 +
  115 +}
  116 +
  117 +- (void)requestStarted:(ASIHTTPRequest *)request
  118 +{
  119 + started = YES;
  120 +}
  121 +
  122 +- (void)requestFinished:(ASIHTTPRequest *)request
  123 +{
  124 + finished = YES;
  125 +}
  126 +
  127 +- (void)requestFailed:(ASIHTTPRequest *)request
  128 +{
  129 + failed = YES;
  130 +}
  131 +
  132 +- (void)delegateTestStarted:(ASIHTTPRequest *)request
  133 +{
  134 + started = YES;
  135 +}
  136 +
  137 +- (void)delegateTestFinished:(ASIHTTPRequest *)request
  138 +{
  139 + finished = YES;
  140 +}
  141 +
  142 +- (void)delegateTestFailed:(ASIHTTPRequest *)request
  143 +{
  144 + failed = YES;
  145 +}
  146 +
68 - (void)testConditionalGET 147 - (void)testConditionalGET
69 { 148 {
70 ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/i/logo.png"]]; 149 ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/i/logo.png"]];
@@ -41,6 +41,10 @@ IMPORTANT @@ -41,6 +41,10 @@ IMPORTANT
41 41
42 ASINetworkQueue *addMoreRequestsQueue; 42 ASINetworkQueue *addMoreRequestsQueue;
43 int requestsFinishedCount; 43 int requestsFinishedCount;
  44 +
  45 + BOOL started;
  46 + BOOL finished;
  47 + BOOL failed;
44 } 48 }
45 49
46 - (void)testFailure; 50 - (void)testFailure;
@@ -53,6 +53,56 @@ IMPORTANT @@ -53,6 +53,56 @@ IMPORTANT
53 } 53 }
54 54
55 55
  56 +- (void)testDelegateMethods
  57 +{
  58 + started = NO;
  59 + finished = NO;
  60 + failed = NO;
  61 +
  62 + ASINetworkQueue *networkQueue = [ASINetworkQueue queue];
  63 + [networkQueue setDelegate:self];
  64 + [networkQueue setRequestDidStartSelector:@selector(delegateTestStarted:)];
  65 + [networkQueue setRequestDidFinishSelector:@selector(delegateTestFinished:)];
  66 +
  67 + ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
  68 + [networkQueue addOperation:request];
  69 + [networkQueue go];
  70 +
  71 + [networkQueue waitUntilAllOperationsAreFinished];
  72 +
  73 + GHAssertTrue(started,@"Failed to call the delegate method when the request started");
  74 + GHAssertTrue(finished,@"Failed to call the delegate method when the request finished");
  75 +
  76 + networkQueue = [ASINetworkQueue queue];
  77 + [networkQueue setDelegate:self];
  78 + [networkQueue setRequestDidFailSelector:@selector(delegateTestFailed:)];
  79 +
  80 + request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
  81 + [request setTimeOutSeconds:0.01];
  82 + [networkQueue addOperation:request];
  83 + [networkQueue go];
  84 +
  85 + [networkQueue waitUntilAllOperationsAreFinished];
  86 +
  87 + GHAssertTrue(failed,@"Failed to call the delegate method when the request failed");
  88 +
  89 +}
  90 +
  91 +- (void)delegateTestStarted:(ASIHTTPRequest *)request
  92 +{
  93 + started = YES;
  94 +}
  95 +
  96 +- (void)delegateTestFinished:(ASIHTTPRequest *)request
  97 +{
  98 + finished = YES;
  99 +}
  100 +
  101 +- (void)delegateTestFailed:(ASIHTTPRequest *)request
  102 +{
  103 + failed = YES;
  104 +}
  105 +
56 106
57 - (void)testDownloadProgress 107 - (void)testDownloadProgress
58 { 108 {