WKWebView won’t show custom UIContextMenuConfiguration for images

1.5k views Asked by At

I’m trying to create a custom context menu for my WKWebView on iOS 13. I’m able to override the default context menu for normal links, however, when I tap and hold on an image, the default context menu shows.

Here is the code I have:

-(void) webView:(WKWebView *)webView 
contextMenuConfigurationForElement:(WKContextMenuElementInfo *)elementInfo 
completionHandler:(void (^)(UIContextMenuConfiguration *configuration))completionHandler {
    NSURL *url = elementInfo.linkURL;
    __block BOOL isURLImage;
    __block UIImage *image;
    if (url != nil) {
        UIAction *openURL = [UIAction actionWithTitle:@"Open URL" image:nil identifier:nil handler:^(UIAction *action) {
            [self.webView loadRequest:[NSURLRequest requestWithURL:url]];
        }];
        UIAction *openNewTab = [UIAction actionWithTitle:@"Open in new tab" image:nil identifier:nil handler:^(UIAction *action) {
            [self createNewTab:url];
        }];
        
        dispatch_async(dispatch_queue_create("getImage", NULL), ^(void) {
            NSData *data = [NSData dataWithContentsOfURL:url];
            image = [UIImage imageWithData:data];
            if (image == nil) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    UIContextMenuConfiguration *menuconfig = nil;
                    menuconfig = [UIContextMenuConfiguration configurationWithIdentifier:nil previewProvider:nil actionProvider:^(NSArray *suggestedAction) {
                        suggestedAction = nil;
                        return [UIMenu menuWithTitle:@"" children:@[openURL, openNewTab]];
                    }];
                    completionHandler(menuconfig);
                });
            }
            else {
                dispatch_async(dispatch_get_main_queue(), ^{
                    UIAction *saveImage = [UIAction actionWithTitle:@"Save image" image:nil identifier:nil handler:^(UIAction *action) {
                        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
                            PHAssetChangeRequest *assetRequest;
                            assetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
                        } completionHandler:^(BOOL success, NSError *error) {
                        }];
                    }];
                    UIContextMenuConfiguration *menuconfig = nil;
                    menuconfig = [UIContextMenuConfiguration configurationWithIdentifier:nil previewProvider:nil actionProvider:^(NSArray *suggestedAction) {
                        suggestedAction = nil;
                        return [UIMenu menuWithTitle:@"" children:@[openURL, openNewTab, saveImage]];
                    }];
                    completionHandler(menuconfig);
                });
            }
        });
    }
    else {
        completionHandler(nil);  
    }
}

Any help would be greatly appreciated.

Update:

While updating my application to support the default browser entitlement for iOS 14, I again ran into an issue related to saving images. For the entitlement, your application can only request write-only privileges using NSPhotoLibraryAddUsageDescription. This is a good idea for user privacy, but there is only one problem: the only way to save images on iOS 13 using only NSPhotoLibraryAddUsageDescription is UIImageWriteToSavedPhotosAlbum(). UIImageWriteToSavedPhotosAlbum() does not support saving animated gifs.

The interesting bit: Apples default context menu configuration for images (the one you can not override for saving images), will save gifs on iOS 13 even with just NSPhotoLibraryAddUsageDescription specified in your info.plist. Hopefully this information will help somebody in the future.

0

There are 0 answers