From 755e722cc87f8564537b766e46afeea2a459b53a Mon Sep 17 00:00:00 2001
From: Seamus Campbell <conform@gmail.com>
Date: Wed, 4 Mar 2015 10:29:14 -0800
Subject: [PATCH 1/4] Fix double-escaping of input URI. Prefer supplied UTI if
 available. Modernize Objective-C usage.

---
 src/ios/FileOpener2.m | 64 ++++++++++++++++++-------------------------
 1 file changed, 27 insertions(+), 37 deletions(-)

diff --git a/src/ios/FileOpener2.m b/src/ios/FileOpener2.m
index 1d4a306..2b32e6d 100644
--- a/src/ios/FileOpener2.m
+++ b/src/ios/FileOpener2.m
@@ -27,57 +27,47 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #import <MobileCoreServices/MobileCoreServices.h>
 
 @implementation FileOpener2
-@synthesize controller = docController;
 
 - (void) open: (CDVInvokedUrlCommand*)command {
 
-    NSString *path = [[command.arguments objectAtIndex:0] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
-    //NSString *uti = [command.arguments objectAtIndex:1];
+    NSString *path = [command.arguments objectAtIndex:0];
+    NSString *uti = nil;
+    if (command.arguments.count > 1) {
+        uti = [command.arguments objectAtIndex:1];
+    }
 
     CDVViewController* cont = (CDVViewController*)[ super viewController ];
 
-    NSArray *dotParts = [path componentsSeparatedByString:@"."];
-    NSString *fileExt = [dotParts lastObject];
-	//NSString *fileExt = [[dotparts lastObject] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+    if (!uti) {
+        NSArray *dotParts = [path componentsSeparatedByString:@"."];
+        NSString *fileExt = [dotParts lastObject];
 
-	NSString *uti = (__bridge NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExt, NULL);
+        NSString *uti = (__bridge NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExt, NULL);
+    }
 
-    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+    dispatch_async(dispatch_get_main_queue(), ^{
         //NSLog(@"path %@, uti:%@", path, uti);
-        NSURL *fileURL = nil;
-
-        //fileURL = [NSURL URLWithString:path];
-        fileURL = [NSURL fileURLWithPath:path];
+        NSURL *fileURL = [NSURL fileURLWithPath:path];
         
         localFile = fileURL.path;
 
-        dispatch_async(dispatch_get_main_queue(), ^{
+        self.controller = [UIDocumentInteractionController  interactionControllerWithURL:fileURL];
+        self.controller.delegate = self;
+        self.controller.UTI = uti;
 
-            docController = [UIDocumentInteractionController  interactionControllerWithURL:fileURL];
-            docController.delegate = self;
-            docController.UTI = uti;
+        CGRect rect = CGRectMake(0, 0, 1000.0f, 150.0f);
+        CDVPluginResult* pluginResult = nil;
+        BOOL wasOpened = [docController presentOptionsMenuFromRect:rect inView:cont.view animated:NO];
 
-            CGRect rect = CGRectMake(0, 0, 1000.0f, 150.0f);
-            CDVPluginResult* pluginResult = nil;
-            BOOL wasOpened = [docController presentOptionsMenuFromRect:rect inView:cont.view animated:NO];
-            //presentOptionsMenuFromRect
-            //presentOpenInMenuFromRect
-
-            if(wasOpened) {
-                pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: @""];
-                //NSLog(@"Success");
-            } else {
-                NSDictionary *jsonObj = [ [NSDictionary alloc]
-                                         initWithObjectsAndKeys :
-                                         @"9", @"status",
-                                         @"Could not handle UTI", @"message",
-                                         nil
-                                         ];
-                pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:jsonObj];
-                //NSLog(@"Could not handle UTI");
-            }
-            [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
-        });
+        if(wasOpened) {
+            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: @""];
+        } else {
+            NSDictionary *jsonObj = @{@"status" : @"9",
+                                      @"message" : @"Could not handle UTI"};
+            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
+                                         messageAsDictionary:jsonObj];
+        }
+        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
     });
 }
 

From 56b0c4ddd672a4bc168c3a50bbba53f1075594e7 Mon Sep 17 00:00:00 2001
From: Seamus Campbell <conform@gmail.com>
Date: Thu, 5 Mar 2015 17:58:39 -0800
Subject: [PATCH 2/4] Fix compile errors; add file-exists test and logging.

---
 src/ios/FileOpener2.m | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/ios/FileOpener2.m b/src/ios/FileOpener2.m
index 2b32e6d..b76083c 100644
--- a/src/ios/FileOpener2.m
+++ b/src/ios/FileOpener2.m
@@ -42,14 +42,21 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         NSArray *dotParts = [path componentsSeparatedByString:@"."];
         NSString *fileExt = [dotParts lastObject];
 
-        NSString *uti = (__bridge NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExt, NULL);
+        uti = (__bridge NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExt, NULL);
     }
 
     dispatch_async(dispatch_get_main_queue(), ^{
-        //NSLog(@"path %@, uti:%@", path, uti);
         NSURL *fileURL = [NSURL fileURLWithPath:path];
         
         localFile = fileURL.path;
+        
+        NSLog(@"looking for file at %@", fileURL);
+        NSFileManager *fm = [NSFileManager defaultManager];
+        if(![fm fileExistsAtPath:localFile]) {
+            NSLog(@"couldn't find file!");
+        } else {
+            NSLog(@"file located, handing off to UIDocumentInteractionController");
+        }
 
         self.controller = [UIDocumentInteractionController  interactionControllerWithURL:fileURL];
         self.controller.delegate = self;
@@ -57,7 +64,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
         CGRect rect = CGRectMake(0, 0, 1000.0f, 150.0f);
         CDVPluginResult* pluginResult = nil;
-        BOOL wasOpened = [docController presentOptionsMenuFromRect:rect inView:cont.view animated:NO];
+        BOOL wasOpened = [self.controller presentOptionsMenuFromRect:rect inView:cont.view animated:NO];
 
         if(wasOpened) {
             pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: @""];

From 6d712ad889e7a676443467cc05ed1fc5f06814a7 Mon Sep 17 00:00:00 2001
From: Seamus Campbell <conform@gmail.com>
Date: Sat, 7 Mar 2015 14:18:59 -0800
Subject: [PATCH 3/4] Basic functional file URI opening.

* does not take paths or cdvfile:// URIs.
* still exposes iOS 8 bug with UIDocumentInteractionController
	see http://openradar.appspot.com/radar?id=5800473659441152
---
 src/ios/FileOpener2.m | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/src/ios/FileOpener2.m b/src/ios/FileOpener2.m
index b76083c..8e9d611 100644
--- a/src/ios/FileOpener2.m
+++ b/src/ios/FileOpener2.m
@@ -30,32 +30,31 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 - (void) open: (CDVInvokedUrlCommand*)command {
 
-    NSString *path = [command.arguments objectAtIndex:0];
-    NSString *uti = nil;
-    if (command.arguments.count > 1) {
-        uti = [command.arguments objectAtIndex:1];
+    NSString *path = command.arguments[0];
+    NSString *uti = command.arguments[1];
+    if (!uti || (NSNull*)uti == [NSNull null]) {
+        NSArray *dotParts = [path componentsSeparatedByString:@"."];
+        NSString *fileExt = [dotParts lastObject];
+        
+        uti = (__bridge NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExt, NULL);
     }
 
     CDVViewController* cont = (CDVViewController*)[ super viewController ];
 
-    if (!uti) {
-        NSArray *dotParts = [path componentsSeparatedByString:@"."];
-        NSString *fileExt = [dotParts lastObject];
-
-        uti = (__bridge NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExt, NULL);
-    }
-
     dispatch_async(dispatch_get_main_queue(), ^{
-        NSURL *fileURL = [NSURL fileURLWithPath:path];
+        // TODO: test if this is a URI or a path
+        NSURL *fileURL = [NSURL URLWithString:path];
         
         localFile = fileURL.path;
         
         NSLog(@"looking for file at %@", fileURL);
         NSFileManager *fm = [NSFileManager defaultManager];
         if(![fm fileExistsAtPath:localFile]) {
-            NSLog(@"couldn't find file!");
-        } else {
-            NSLog(@"file located, handing off to UIDocumentInteractionController");
+            NSDictionary *jsonObj = @{@"status" : @"9",
+                                      @"message" : @"File does not exist"};
+            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
+                                         messageAsDictionary:jsonObj];
+            return;
         }
 
         self.controller = [UIDocumentInteractionController  interactionControllerWithURL:fileURL];

From caf3e6fda4f7230a58a3656105f5933a2eb5508c Mon Sep 17 00:00:00 2001
From: Seamus Campbell <conform@gmail.com>
Date: Sat, 7 Mar 2015 14:21:33 -0800
Subject: [PATCH 4/4] Make sure we send the error command if file not found.

---
 src/ios/FileOpener2.m | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/ios/FileOpener2.m b/src/ios/FileOpener2.m
index 8e9d611..b9f67fa 100644
--- a/src/ios/FileOpener2.m
+++ b/src/ios/FileOpener2.m
@@ -52,8 +52,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         if(![fm fileExistsAtPath:localFile]) {
             NSDictionary *jsonObj = @{@"status" : @"9",
                                       @"message" : @"File does not exist"};
-            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
-                                         messageAsDictionary:jsonObj];
+            CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
+                                                          messageAsDictionary:jsonObj];
+            [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
             return;
         }