iOS 8 Share extension loadItemForTypeIdentifier:options:completionHandler: completion closure not executing

后端 未结 6 1823
一向
一向 2020-12-24 09:07

I\'m using the loadItemForTypeIdentifier:options:completionHandler: method on an NSItemProvider object to extract a url from Safari via a Share extension in iOS 8.

6条回答
  •  失恋的感觉
    2020-12-24 09:53

    I was never managed completionHandler to work properly for Share extension with no user interface (in such case extension's class is a subclass on NSObject).

    Despite the [itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeURL] returns YES the completionHandler is never called both on the device or simulator.

    After trying different approaches I ended up with workaround based on javascript passing URL back to extension (sorry as I use ObjC not Swift for my example).

    Info.plist NSExtension portion:

    NSExtension
    
        NSExtensionAttributes
        
            NSExtensionActivationRule
            
                NSExtensionActivationSupportsWebURLWithMaxCount
                1
            
            NSExtensionJavaScriptPreprocessingFile
            Action
        
        NSExtensionPointIdentifier
        com.apple.services
        NSExtensionPrincipalClass
        ActionRequestHandler
    
    

    Javascript Action.js file:

    var Action = function() {};
    Action.prototype = {
        run: function(arguments) {
            arguments.completionFunction({ "currentURL" : window.location.href })
        },
        finalize: function(arguments) {
        }
    };
    var ExtensionPreprocessingJS = new Action
    

    ActionRequestHandler.h header file:

    @interface ActionRequestHandler : NSObject 
    
    @end
    

    ActionRequestHandler.m based on default Action extension template:

    #import "ActionRequestHandler.h"
    #import 
    
    @interface ActionRequestHandler ()
    
    @property (nonatomic, strong) NSExtensionContext *extensionContext;
    
    @end
    
    @implementation ActionRequestHandler
    
    - (void)beginRequestWithExtensionContext:(NSExtensionContext *)context {
        // Do not call super in an Action extension with no user interface
        self.extensionContext = context;
    
        BOOL found = NO;
    
        // Find the item containing the results from the JavaScript preprocessing.
        for (NSExtensionItem *item in self.extensionContext.inputItems) {
            for (NSItemProvider *itemProvider in item.attachments) {
                if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypePropertyList]) {
                    [itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypePropertyList options:nil completionHandler:^(NSDictionary *dictionary, NSError *error) {
                        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                            [self itemLoadCompletedWithPreprocessingResults:dictionary[NSExtensionJavaScriptPreprocessingResultsKey]];
                        }];
                    }];
                    found = YES;
                }
                break;
            }
            if (found) {
                break;
            }
        }
    
        if (!found) {
            // We did not find anything - signal that we're done
            [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
            // Don't hold on to this after we finished with it
            self.extensionContext = nil;
        }
    }
    
    - (void)itemLoadCompletedWithPreprocessingResults:(NSDictionary *)javaScriptPreprocessingResults
    {
        // Get the URL
        if ([javaScriptPreprocessingResults[@"currentURL"] length] != 0) {
            NSLog(@"*** URL: %@", javaScriptPreprocessingResults[@"currentURL"]);
        }
    
        // Signal that we're done
        [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
        // Don't hold on to this after we finished with it
        self.extensionContext = nil;
    }
    
    @end
    

    Hope it will help somebody to save couple of hours struggling with the completionHandler issue.

提交回复
热议问题