简体   繁体   中英

iOS share extension does not receive data from Safari

I have an iOS share extension that needs the URL of the opened web page. Everything works good, especially in a simulator. But on a real device I have around 20-30% cases where the extension does not receive any data ie:

NSExtensionItem *inputItem = self.extensionContext.inputItems.firstObject;
NSItemProvider *item = inputItem.attachments.firstObject;

[item loadItemForTypeIdentifier:(NSString *)kUTTypePropertyList options:nil completionHandler:^(NSDictionary *item, NSError *error) {
    // here the error is sometimes not nil and thus the _baseURI ends up nil
    _baseURI = [item[NSExtensionJavaScriptPreprocessingResultsKey] objectForKey:@"baseURI"];
}];

The error code is -100 with description "No item available for requested type identifier." . This happens mainly when I open the extension several times in a row without changing/refreshing the web page in the Safari.

In those situations I see a device log saying "iPhone kernel[0] : Sandbox: MobileSafari(7033) deny(1) file-read-data /private/var/containers/Bundle/Application/.../bundle.js" where the bundle.js is the javascript with the ExtensionPreprocessingJS object. The bundle.js declares the ExtensionPreprocessingJS object like this (extracted the relevant part):

ExtensionPreprocessingJS = {
  run: function(arguments){
      arguments.completionFunction({
        "baseURI": document.baseURI
      })
  },

  finalize: function(arguments){
  }
}

In this situation, it could some time happen that when the extension is closed the next time opening the share dialog in Safari shows my extension with no icon. This happens on my testing iPhone 5s and iPhone 6 with iOS 9.3.

I think that the missing data is because of the system could not read the extension's JavaScript file, but why could this happen?

If you read the documentation for:

loadItemForTypeIdentifier(_:options:completionHandler:)

You'll see that:

The type information for the first parameter of your completionHandler block should be set to the class of the expected type . For example, when requesting text data, you might set the type of the first parameter to NSString or NSAttributedString. An item provider can perform simple type conversions of the data to the class you specify, such as from NSURL to NSData or NSFileWrapper, or from NSData to UIImage (in iOS) or NSImage (in OS X). If the data could not be retrieved or coerced to the specified class, an error is passed to the completion block's.

Try this code to see what you recieve:

[item loadItemForTypeIdentifier:(NSString *)kUTTypePropertyList options:nil completionHandler:^(id item, NSError *error) {
// here the error is sometimes not nil and thus the _baseURI ends up nil
_baseURI = [item[NSExtensionJavaScriptPreprocessingResultsKey] objectForKey:@"baseURI"];
}];

Note that item is not set to NSDictionary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM