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