Execute callback blocks on original thread
This is required when ObjectiveCMIS Library is called from a background thread
git-svn-id: https://svn.apache.org/repos/asf/chemistry/objectivecmis/trunk@1659620 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ObjectiveCMIS/Bindings/Browser/CMISBrowserRepositoryService.m b/ObjectiveCMIS/Bindings/Browser/CMISBrowserRepositoryService.m
index c8222d7..433627c 100644
--- a/ObjectiveCMIS/Bindings/Browser/CMISBrowserRepositoryService.m
+++ b/ObjectiveCMIS/Bindings/Browser/CMISBrowserRepositoryService.m
@@ -80,7 +80,7 @@
completionBlock(nil);
}
} else {
- completionBlock(error);
+ completionBlock(error);
}
}];
diff --git a/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m b/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m
index f061c81..49d4dfb 100644
--- a/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m
+++ b/ObjectiveCMIS/Utils/CMISHttpDownloadRequest.m
@@ -192,13 +192,9 @@
// update statistics
self.bytesDownloaded += data.length;
- // pass progress to progressBlock, on the main thread
- if (self.progressBlock) {
- dispatch_async(dispatch_get_main_queue(), ^{
- if (self.progressBlock) {
- self.progressBlock(self.bytesDownloaded, self.bytesExpected);
- }
- });
+ // pass progress to progressBlock, on the original thread
+ if (self.originalThread) {
+ [self performSelector:@selector(executeProgressBlock:) onThread:self.originalThread withObject:@[@(self.bytesDownloaded), @(self.bytesExpected)] waitUntilDone:NO];
}
}
@@ -230,10 +226,10 @@
NSError *cmisError = [CMISErrors createCMISErrorWithCode:kCMISErrorCodeStorage
detailedDescription:@"Could not open output stream"];
- // call the completion block on the main thread
- dispatch_async(dispatch_get_main_queue(), ^{
- self.completionBlock(nil, cmisError);
- });
+ // call the completion block on the original thread
+ if (self.originalThread) {
+ [self performSelector:@selector(executeCompletionBlockError:) onThread:self.originalThread withObject:cmisError waitUntilDone:NO];
+ }
}
}
}
@@ -271,12 +267,16 @@
if (totalBytesExpected == NSURLSessionTransferSizeUnknown && self.bytesExpected != 0) {
totalBytesExpected = self.bytesExpected;
}
-
- dispatch_async(dispatch_get_main_queue(), ^{
- if (self.progressBlock) {
- self.progressBlock(totalBytesWritten, totalBytesExpected);
- }
- });
+ // pass progress to progressBlock, on the original thread
+ if (self.originalThread) {
+ [self performSelector:@selector(executeProgressBlock:) onThread:self.originalThread withObject:@[@(totalBytesWritten), @(totalBytesExpected)] waitUntilDone:NO];
+ }
+ }
+}
+
+- (void)executeProgressBlock:(NSArray*)valueArray {
+ if (self.progressBlock) {
+ self.progressBlock([valueArray[0] unsignedLongLongValue], [valueArray[1] unsignedLongLongValue]);
}
}
diff --git a/ObjectiveCMIS/Utils/CMISHttpRequest.h b/ObjectiveCMIS/Utils/CMISHttpRequest.h
index 45bc9fa..03fa8a4 100644
--- a/ObjectiveCMIS/Utils/CMISHttpRequest.h
+++ b/ObjectiveCMIS/Utils/CMISHttpRequest.h
@@ -34,6 +34,7 @@
@property (nonatomic, strong) NSHTTPURLResponse *response;
@property (nonatomic, strong) CMISBindingSession *session;
@property (nonatomic, copy) void (^completionBlock)(CMISHttpResponse *httpResponse, NSError *error);
+@property (nonatomic, weak) NSThread *originalThread;
/**
* starts a URL request for given HTTP method
@@ -61,4 +62,10 @@
/// Creates an appropriate task for the given request object.
- (NSURLSessionTask *)taskForRequest:(NSURLRequest *)request;
+/// Call completion block with response returned from server
+- (void)executeCompletionBlockResponse:(CMISHttpResponse*)response;
+
+/// Call completion block with error returned from server
+- (void)executeCompletionBlockError:(NSError*)error;
+
@end
diff --git a/ObjectiveCMIS/Utils/CMISHttpRequest.m b/ObjectiveCMIS/Utils/CMISHttpRequest.m
index e03a2bb..12a16c1 100644
--- a/ObjectiveCMIS/Utils/CMISHttpRequest.m
+++ b/ObjectiveCMIS/Utils/CMISHttpRequest.m
@@ -39,7 +39,6 @@
NSString * const kCMISExceptionUpdateConflict = @"updateConflict";
NSString * const kCMISExceptionVersioning = @"versioning";
-
@implementation CMISHttpRequest
@@ -69,6 +68,7 @@
{
self = [super init];
if (self) {
+ _originalThread = [NSThread currentThread];
_requestMethod = httpRequestMethod;
_completionBlock = completionBlock;
}
@@ -147,10 +147,7 @@
if (self.completionBlock) {
NSString *detailedDescription = [NSString stringWithFormat:@"Could not create network session for %@", urlRequest.URL];
NSError *cmisError = [CMISErrors createCMISErrorWithCode:kCMISErrorCodeConnection detailedDescription:detailedDescription];
- void (^completionBlock)(CMISHttpResponse *httpResponse, NSError *error);
- completionBlock = self.completionBlock;
- self.completionBlock = nil; // Prevent multiple execution if method on this request gets called inside completion block
- completionBlock(nil, cmisError);
+ [self executeCompletionBlockResponse:nil error:cmisError];
}
}
@@ -212,14 +209,14 @@
httpResponse = nil;
}
}
-
- // call the completion block on the main thread
- dispatch_async(dispatch_get_main_queue(), ^{
- void (^completionBlock)(CMISHttpResponse *httpResponse, NSError *error);
- completionBlock = self.completionBlock;
- self.completionBlock = nil; // Prevent multiple execution if method on this request gets called inside completion block
- completionBlock(httpResponse, cmisError);
- });
+ // call the completion block on the original thread
+ if (self.originalThread) {
+ if(cmisError) {
+ [self performSelector:@selector(executeCompletionBlockError:) onThread:self.originalThread withObject:cmisError waitUntilDone:NO];
+ } else {
+ [self performSelector:@selector(executeCompletionBlockResponse:) onThread:self.originalThread withObject:httpResponse waitUntilDone:NO];
+ }
+ }
}
// clean up
@@ -333,4 +330,21 @@
return YES;
}
+- (void)executeCompletionBlockResponse:(CMISHttpResponse*)response {
+ [self executeCompletionBlockResponse:response error:nil];
+}
+
+- (void)executeCompletionBlockError:(NSError*)error {
+ [self executeCompletionBlockResponse:nil error:error];
+}
+
+- (void)executeCompletionBlockResponse:(CMISHttpResponse*)response error:(NSError*)error {
+ if (self.completionBlock) {
+ void (^completionBlock)(CMISHttpResponse *httpResponse, NSError *error);
+ completionBlock = self.completionBlock;
+ self.completionBlock = nil; // Prevent multiple execution if method on this request gets called inside completion block
+ completionBlock(response, error);
+ }
+}
+
@end
diff --git a/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m b/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m
index f64928d..f0e1cc5 100644
--- a/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m
+++ b/ObjectiveCMIS/Utils/CMISHttpUploadRequest.m
@@ -266,12 +266,18 @@
if (totalBytesSent >= totalBytesExpectedToSend) {
self.transferCompleted = YES;
}
- self.progressBlock((unsigned long long)totalBytesSent, (unsigned long long)totalBytesExpectedToSend);
+ // pass progress to progressBlock, on the original thread
+ if (self.originalThread) {
+ [self performSelector:@selector(executeProgressBlock:) onThread:self.originalThread withObject:@[@(totalBytesSent), @(totalBytesExpectedToSend)] waitUntilDone:NO];
+ }
} else {
if (totalBytesSent >= self.bytesExpected) {
self.transferCompleted = YES;
}
- self.progressBlock((unsigned long long)totalBytesSent, self.bytesExpected);
+ // pass progress to progressBlock, on the original thread
+ if (self.originalThread) {
+ [self performSelector:@selector(executeProgressBlock:) onThread:self.originalThread withObject:@[@(totalBytesSent), @(self.bytesExpected)] waitUntilDone:NO];
+ }
}
}
}
@@ -504,5 +510,10 @@
self.streamStartData = nil;
}
+- (void)executeProgressBlock:(NSArray*)valueArray {
+ if (self.progressBlock) {
+ self.progressBlock([valueArray[0] unsignedLongLongValue], [valueArray[1] unsignedLongLongValue]);
+ }
+}
@end