6

我正在使用共享扩展从图库中共享图像数组。我可以使用在共享扩展中获取图像

- (void)getImageFromExtension:(NSExtensionItem *)extensionItem
{
    for(NSItemProvider *attachment in extensionItem.attachments)
    {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            if([attachment hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage])
            {
                [attachment loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
                    NSURL *image = (NSURL *)item;
                    if(error)
                    {
                        NSLog(@"Error retrieving image");
                    } else {
                        dispatch_async(dispatch_get_main_queue(), ^{
                            NSLog(@"*** ### %@",[UIImage imageWithData:[NSData dataWithContentsOfURL:image]]);
                        });
                    }
                }];
            }
        });
    }
}

我真正需要的是,我需要将图像 url 传递给容器应用程序。但无法从该 URL 获取图像。网址格式为file:///var/mobile/Media/DCIM/101APPLE/IMG_1705.JPG

此 url 中的数据始终为空。如何从此 URL 获取图像?

4

1 回答 1

4

您可能getImageFromExtensiondidSelectPost. 最后,didSelectPost您应该打电话completeRequestReturningItems:completionHandler:告诉主机应用程序使用一系列结果项来完成应用程序扩展请求。当调用该方法时,整个 ShareViewController 将被解除并释放。当您在 结束时调用它时didSelectPost,它会在NSItemProvider检索图像 URL 之前执行。因为那是异步发生的。要解决此问题,您必须在检索到 imageURLcompleteRequestReturningItems:completionHandler:后调用。NSItemProvider

这是它应该如何工作的:

- (void)didSelectPost {
    NSString *typeIdentifier = (NSString *)kUTTypeImage
    NSExtensionItem *item = self.extensionContext.inputItems.firstObject;
    NSItemProvider *itemProvider = item.attachments.firstObject;
    if ([itemProvider hasItemConformingToTypeIdentifier:typeIdentifier]) {
        [itemProvider loadItemForTypeIdentifier:typeIdentifier
                                        options:nil
                              completionHandler:^(NSURL *url, NSError *error) {
                                  NSURL *imageURL = (NSURL *)item
                                  self.saveImage(imageURL)
                                  [self.extensionContext completeRequestReturningItems:@[]         
                                                                     completionHandler:nil];
                              }];
    }
}

顺便说一句,dispatch_async与 NSItemProvider 一起工作时不需要使用,因为提供者已经在异步完成他的工作。

我已经写了一篇关于这个的博客文章,如果你想阅读更多关于这个的内容。

编辑

您现在可以使用刚刚检索的文件路径加载图像。这仅在扩展中有效!如果您想从包含的应用程序访问图像,则不能使用刚刚检索到的文件 URL。共享扩展将所选图像保存在包含应用程序无法访问的文件夹中。

要使包含应用程序的图像可用,您必须App Groups在包含应用程序和扩展程序中激活。然后扩展程序将图像保存到共享容器中,并且包含的​​应用程序可以检索它:

func saveImage(url: NSURL) {
    guard let imageData = NSData(contentsOfURL: url) else { return }
    let selectedImage = UIImage(data: imageData)

    let fileManager = NSFileManager.defaultManager()
    if let sharedContainer = fileManager.containerURLForSecurityApplicationGroupIdentifier("YOUR_GROUP_IDENTIFIER") {
        if let dirPath = sharedContainer.path {
            let sharedImageFilePath = dirPath + "/image.png"
            let binaryImageData = UIImagePNGRepresentation(selectedImage!)
            binaryImageData?.writeToFile(sharedImageFilePath, atomically: true)
            // send the sharedImageFilePath to the containing app
        }
    }
}
于 2015-10-16T06:35:52.037 回答