我是第一次在iOS上创建UIDocumentPicker扩展。我用适当的方法填充了UIDocumentPickerExtensionViewController
子类。在我的UI中,当用户从我的扩展程序中选择文档时,我能够成功地将有问题的图像复制到文档目录中。相关代码:
NSURL *sourceURL = [item imageUrlWithPath:image.fullSizeImagePath];
NSString *filename = [NSString stringWithFormat:@"%@.jpg", item.title ?: NSLocalizedString(@"NO_TITLE", nil)];
NSURL *targetURL = [self.documentStorageURL URLByAppendingPathComponent:filename];
NSError *copyError = nil;
BOOL success = [fm copyItemAtURL:sourceURL toURL:targetURL error:©Error];
if (success) {
[self dismissGrantingAccessToURL:targetURL];
} else {
NSLog(@"Error! %@", copyError);
}
根据上面的代码路径,这一切都很顺利,但是,在做出选择并调用dismissGrantingAccessToURL:
后,UI被取消,但我从主机应用程序收到警报(在此case,Pages)说无法插入图像,因为"此图像属于不支持的类型。"
我尝试过的事情:
一切都无济于事。为什么其他应用程序无法读取我的文件?
答案 0 :(得分:0)
当您创建新的文档提供程序扩展(至少在Xcode 8中)时,Apple会创建一个名为文件提供程序的附加扩展。这是一个独立于UI的独立扩展,用于从远程服务(如服务器)获取文件。这在文件不是物理上在设备上但您仍希望用户能够将其导入主机应用程序的情况下非常有用。
这种不幸的副作用是Apple还编写了一些存根代码,NSFileProviderExtension
的子类。如果您找到此类(默认为FileProvider
),则会有一个方法startProvidingItemAtURL:completionHandler:
。这种方法有一些苹果公司放在那里的固有代码:
- (void)startProvidingItemAtURL:(NSURL *)url completionHandler:(void (^)(NSError *))completionHandler {
// Should ensure that the actual file is in the position returned by URLForItemWithIdentifier:, then call the completion handler
NSError *fileError = nil;
// TODO: get the contents of file at <url> from model
NSData *fileData = [NSData data];
[fileData writeToURL:url options:0 error:&fileError];
if (completionHandler) {
completionHandler(nil);
}
}
正如在此代码中看到的那样,如果文件实际上已经存在于上一个选择器扩展中,它们将完全覆盖您可能已经编写的文件。救援的示例代码......直到它以静默方式清除您的文件。这个问题的一个解决方案是注释掉这个方法中的所有代码行,除了对完成处理程序的调用:
- (void)startProvidingItemAtURL:(NSURL *)url completionHandler:(void (^)(NSError *))completionHandler {
if (completionHandler) {
completionHandler(nil);
}
}
有了这个,你的文件提供者就像下雨一样。