项提供程序的 iOS 共享扩展问题无法从照片库中读取



我在共享图像库时使用了解决方案表单iOS共享扩展问题来获取照片应用程序的图像。这在模拟器中效果很好,但是在设备上,我会发现一个错误,我无法访问ItemProvider提供的NSURL:

2018-02-18 12:54:09.448148 0100 myApp [6281:1653186] [默认]-a2342edea04d/img_2784.jpg(s(由文件提供商管理

由陈述引起的:

[itemProvider loadItemForTypeIdentifier:itemProvider.registeredTypeIdentifiers.firstObject options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
}

搜索phasset的项目名称不是一个好的解决方案,因为用户必须再次访问照片库。

在didSelectPost中,您在处理InputItems阵列中的所有项目之前,不得放弃Shareextension ViewController。使用[super didSelectPost]或调用扩展上下文的完成方法来驳回视图controller。

这是我在代码中的解决方案:

- (void)didSelectPost {
__block NSInteger itemCount = ((NSExtensionItem*)self.extensionContext.inputItems[0]).attachments.count;
__block NSInteger processedCount = 0;
for (NSItemProvider* itemProvider in ((NSExtensionItem*)self.extensionContext.inputItems[0]).attachments ) {
    if([itemProvider hasItemConformingToTypeIdentifier:@"public.jpeg"]) {
        NSLog(@"itemprovider = %@", itemProvider);
        [itemProvider loadItemForTypeIdentifier:@"public.jpeg" options:nil completionHandler: ^(id<NSSecureCoding> item, NSError *error) {
            NSData *imgData;
            if([(NSObject*)item isKindOfClass:[NSURL class]]) {
                imgData = [NSData dataWithContentsOfURL:(NSURL*)item];
            }
            if([(NSObject*)item isKindOfClass:[UIImage class]]) {
                imgData = UIImagePNGRepresentation((UIImage*)item);
            }
            NSDictionary *dict = @{
                                   @"imgData" : imgData,
                                   @"name" : self.contentText
                                   };
            NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.share.extension1"];
            [defaults setObject:dict forKey:@"img"];
            [defaults synchronize];
            processedCount += 1;
            if (processedCount == itemCount)
                [super didSelectPost];
        }];
    }
}

loadItemForTypeIdentifier或swift loadItem方法是 asynchronous ,因此必须将UI解散为其completionHandler中的最后一件事。

例如,我有:

override func didSelectPost() {
    // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
    if let item = self.extensionContext?.inputItems[0] as? NSExtensionItem, let attachments = item.attachments {
        for provider in attachments {
            if provider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
                provider.loadItem(forTypeIdentifier: kUTTypeImage as String, options: nil, completionHandler: {item, error in
                    // do all you need to do here, i.e.
                    if let tmpURL = item as? URL {
                        // etc. etc.
                    }
                    // and, at the end, inside the completionHandler, call
                    // Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
                    self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
                })
            }
        }
    }
}

我可以通过:

来解散UI
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)

或通过:

super.didSelectPost()

async 方法loadItem之后的completionHandler之外,您将获得各种权限错误,此外,此错误可能是随机的,有时会发生,有时不行,这是因为有时您的 async 致电loadItem有机会在UI被解雇之前终止,有时不会。

只是把它留在这里,希望它能帮助某人。这个问题花了我几个小时。

最新更新