j3k0 / cordova-plugin-openwith

Get your Cordova App in the O.S. "Share" menu on iOS and Android
MIT License
138 stars 114 forks source link

loadItemForTypeIdentifier returns file url in iOS11 and file content in iOS12 #52

Open optimusprime13 opened 5 years ago

optimusprime13 commented 5 years ago

I see different behavior on iOS 11 vs 12.

On iOS 11 - I get the filepath of files shared in completion handler. On iOS 12 - I get a URL domain error. But if i handle it based on the type (eg: image), i get the file content.

Is this behaviour only on simulator or on device as well ?

benjdg16 commented 5 years ago

May I ask what are your changes for iOS 12 to make the images work? I don't seem to get the file content. Thanks in advance! :)

optimusprime13 commented 5 years ago

I had to do iOS native code changes(objective C).

- (void) handleShare {
    for (NSItemProvider* itemProvider in ((NSExtensionItem*)self.extensionContext.inputItems[0]).attachments) {
        self.bitsToLoad ++;

        NSItemProviderCompletionHandler imageHandler = ^(UIImage *item, NSError *error) {
            NSData *data = [[NSData alloc] init];
            if([(NSObject*)item isKindOfClass:[UIImage class]]) {
                data = UIImagePNGRepresentation((UIImage*)item);
            }

            [self handleData:data :itemProvider];
        };

        NSItemProviderCompletionHandler urlHandler = ^(NSURL *item, NSError *error) {
            NSData *data = [[NSData alloc] init];
            if([(NSObject*)item isKindOfClass:[NSURL class]]) {
                data = [NSData dataWithContentsOfURL:(NSURL*)item];
            }

            [self handleData:data :itemProvider];
        };

        if([itemProvider hasItemConformingToTypeIdentifier:@"public.image"]) {
            [itemProvider loadItemForTypeIdentifier:@"public.image" options:nil completionHandler:imageHandler];
        } else if([itemProvider hasItemConformingToTypeIdentifier:@"public.url"]) {
            [itemProvider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:urlHandler];
        } else if([itemProvider hasItemConformingToTypeIdentifier:@"public.movie"]) {
            [itemProvider loadItemForTypeIdentifier:@"public.movie" options:nil completionHandler:urlHandler];
        } else {
            [self debug:[NSString stringWithFormat:@"Unknown attachment type = %@", itemProvider]];
            [self dataFetched];
        }
    }
}
benjdg16 commented 5 years ago

I still can't get any response on my images. Although, I am using a different plugin which is a forked version of this one (cordova-plugin-openwith-ios).

There is a difference though, the plugin uses NSURL item and not UIImage item for imageHandler.

A bit curious, what does your handleData do? Thanks!

optimusprime13 commented 5 years ago

I haven't gone through (cordova-plugin-openwith-ios).

handleData is saving data as a file on shared directory and it is passing just the filepath to the call back handler in javascript. Guidelines suggest nsuserdefaults should not be used to store data.

In case you are trying to debug the project in xcode, check the optimisation flag in target > build settings. Set it to None for debugging purpose.