Skip to content
This repository has been archived by the owner on Jan 16, 2018. It is now read-only.

Commit

Permalink
Ensure all callbacks are called on the main thread, not the thread th…
Browse files Browse the repository at this point in the history
…e request was started on.
  • Loading branch information
lukeredpath committed Jul 29, 2011
1 parent 30f2b74 commit e4e8360
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 18 deletions.
18 changes: 14 additions & 4 deletions Classes/LRRestyRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ - (void)timeoutAfter:(NSTimeInterval)delayInSeconds handleWithBlock:(LRRestyRequ
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
if (![self isFinished]) {
[self cancelImmediately];
block(self);

dispatch_sync(dispatch_get_main_queue(), ^{
block(self);
});
}
});
}
Expand All @@ -133,7 +136,9 @@ - (void)start
[super start];

if ([delegate respondsToSelector:@selector(restyRequestDidStart:)]) {
[delegate restyRequestDidStart:self];
dispatch_sync(dispatch_get_main_queue(), ^{
[delegate restyRequestDidStart:self];
});
}
[LRResty log:[NSString stringWithFormat:@"Performing %@ with headers %@", self, [URLRequest allHTTPHeaderFields]]];
}
Expand All @@ -146,7 +151,10 @@ - (void)finish;
headers:[(NSHTTPURLResponse *)self.URLResponse allHeaderFields]
originalRequest:self];

[delegate restyRequest:self didFinishWithResponse:restResponse];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[delegate restyRequest:self didFinishWithResponse:restResponse];
});

[restResponse release];

[LRResty log:[NSString stringWithFormat:@"Finished request %@", self]];
Expand All @@ -168,7 +176,9 @@ - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallen
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if ([delegate respondsToSelector:@selector(restyRequest:didReceiveData:)]) {
[delegate restyRequest:self didReceiveData:data];
dispatch_sync(dispatch_get_main_queue(), ^{
[delegate restyRequest:self didReceiveData:data];
});
}
[super connection:connection didReceiveData:data];
}
Expand Down
38 changes: 24 additions & 14 deletions Classes/LRSynchronousProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,33 @@ + (id)performAsynchronousBlockAndReturnResultWhenReady:(LRSynchronousProxyBlock)

+ (id)performAsynchronousBlockWithTimeout:(NSTimeInterval)timeout andReturnResultWhenReady:(LRSynchronousProxyBlock)block
{
id result = nil;
__block id result = nil;

NSCondition *condition = [[NSCondition alloc] init];
dispatch_queue_t synchronousProxyQueue = dispatch_queue_create("co.uk.lukeredpath.resty.synchronousProxy", NULL);

block(&result, condition);
dispatch_sync(synchronousProxyQueue, ^{
NSCondition *condition = [[NSCondition alloc] init];

id blockResult = nil;

block(&blockResult, condition);

[condition lock];

if (timeout > 0) {
[condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:timeout]];
}
else {
[condition wait];
}

[condition unlock];
[condition release];

result = blockResult;
});

[condition lock];

if (timeout > 0) {
[condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:timeout]];
}
else {
[condition wait];
}

[condition unlock];
[condition release];
dispatch_release(synchronousProxyQueue);

return [result autorelease];
}
Expand Down
13 changes: 13 additions & 0 deletions Tests/Acceptance/DeleteResourceTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ - (void)testCanPerformDeleteRequestAndPassResponseToABlock
[testLocalResponse release];
}

- (void)testResponseBlockIsCalledOnMainThread
{
__block BOOL wasCalledOnMainThread = NO;

mimicDELETE(@"/simple/resource", andReturnAnything(), ^{
[client delete:resourceWithPath(@"/simple/resource") withBlock:^(LRRestyResponse *response) {
wasCalledOnMainThread = [[NSThread currentThread] isMainThread];
}];
});

assertEventuallyWithBlock(^{ return wasCalledOnMainThread; });
}

- (void)testCanPerformSynchronousDeleteRequest
{
LRRestyResponse *response = [client delete:resourceWithPath(@"/synchronous/echo")];
Expand Down
13 changes: 13 additions & 0 deletions Tests/Acceptance/GetResourceTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,19 @@ - (void)testCanPerformGetRequestAndPassResponseToABlock
[testLocalResponse release];
}

- (void)testResponseBlockIsCalledOnMainThread
{
__block BOOL wasCalledOnMainThread = NO;

mimicGET(@"/simple/resource", andReturnAnything(), ^{
[client get:resourceWithPath(@"/simple/resource") withBlock:^(LRRestyResponse *response) {
wasCalledOnMainThread = [[NSThread currentThread] isMainThread];
}];
});

assertEventuallyWithBlock(^{ return wasCalledOnMainThread; });
}

- (void)testCanPerformSynchronousGetRequest
{
LRRestyResponse *response = [client get:resourceWithPath(@"/synchronous/echo")];
Expand Down
16 changes: 16 additions & 0 deletions Tests/Acceptance/PostResourceTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,22 @@ - (void)testCanPostToResourceWithFormEncodedDataContainingNumbers
assertEventuallyThat(&receivedResponse, is(responseWithRequestEcho(@"params.number", @"123")));
}

- (void)testResponseBlockIsCalledOnMainThread
{
__block BOOL wasCalledOnMainThread = NO;

mimicPOST(@"/simple/resource", andEchoRequest(), ^{
[client post:resourceWithPath(@"/simple/resource")
payload:@"payload"
withBlock:^(LRRestyResponse *response) {

wasCalledOnMainThread = [[NSThread currentThread] isMainThread];
}];
});

assertEventuallyWithBlock(^{ return wasCalledOnMainThread; });
}

- (void)testCanPerformSynchronousPostRequest
{
LRRestyResponse *response = [client post:resourceWithPath(@"/synchronous/echo") payload:@"hello world"];
Expand Down
16 changes: 16 additions & 0 deletions Tests/Acceptance/PutResourceTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,22 @@ - (void)testCanPostToResourceWithFormEncodedDataContainingNumbers
assertEventuallyThat(&receivedResponse, is(responseWithRequestEcho(@"params.number", @"123")));
}

- (void)testResponseBlockIsCalledOnMainThread
{
__block BOOL wasCalledOnMainThread = NO;

mimicPUT(@"/simple/resource", andEchoRequest(), ^{
[client put:resourceWithPath(@"/simple/resource")
payload:@"payload"
withBlock:^(LRRestyResponse *response) {

wasCalledOnMainThread = [[NSThread currentThread] isMainThread];
}];
});

assertEventuallyWithBlock(^{ return wasCalledOnMainThread; });
}

- (void)testCanPerformSynchronousPutRequest
{
LRRestyResponse *response = [client put:resourceWithPath(@"/synchronous/echo") payload:@"hello world"];
Expand Down

0 comments on commit e4e8360

Please sign in to comment.