Совместное использование PDF-файла из Safari с ошибкой расширения расширения в Swift 4.2 Xcode 10
Я пишу приложение с включенной возможностью "Группы приложений". Расширение Action в этом приложении открыто для файлов PDF и доступно, когда веб-страница, загруженная в Safari, открывается в режиме чтения и затем преобразуется в PDF.
Короче говоря, приложение может принимать веб-страницу, преобразованную в файл PDF из Safari. Он работал нормально до обновления до Swift 4.2. После загрузки Xcode 10 он перестал работать со следующей ошибкой:
(Error Domain=NSItemProviderErrorDomain Code=-1000 "Cannot load
representation of type com.adobe.pdf" UserInfo
{NSLocalizedDescription=Cannot load representation of type
com.adobe.pdf, NSUnderlyingError=0x600002dd9a70 {Error
Domain=NSPOSIXErrorDomain Code=22 "Invalid argument" UserInfo=
{NSLocalizedDescription=Cannot issue a sandbox extension for file
"/Users/xxx/Library/Developer/CoreSimulator/Devices/FE5463C2-FAA3-
41A9938B-C1C234EA966A/data"/Containers/Data/Application/B6FB42C6-B4E3-
46D8-B9F95856FF88F0B6/tmp//Safari - Sep 22, 2018 at 10:00 PM.pdf":
Invalid argument}}})`
Может ли кто-нибудь пролить свет на происходящее? И приложение, и его расширение относятся к одной группе приложений. Расширение действия содержит следующие записи в info.plist:
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<string>
SUBQUERY (
extensionItems,
$extensionItem,
SUBQUERY (
$extensionItem.attachments,
$attachment,
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.adobe.pdf" ||
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.file-url"
).@count == $extensionItem.attachments.@count
).@count == 1
</string>
</dict>
<key>NSExtensionMainStoryboard</key>
<string>MainInterface</string>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.ui-services</string>
</dict>
2 ответа
Похоже, что это ошибка только в Xcode 10 iOS 12 Simulator.
Ошибка равна нулю на реальном устройстве iOS 12, и расширение общего доступа работает как на устройствах iOS 11, так и на устройствах iOS 12.
Я столкнулся с этим вопросом на нашем проекте. Общее расширение перестало работать под симуляторами iOS 12, но оно все еще работает под симуляторами iOS 11 в Xcode 10.
itemProvider.loadItem(forTypeIdentifier: typeIdentifier, options: nil) { secureCoding, error in
}
Я потратил больше половины дня, пробуя разные параметры в соответствии с документом: https://developer.apple.com/documentation/foundation/nsitemprovider/completionhandler
Ничего не помогло - всегда одна и та же ошибка от "loadItem NSItemProvider" под iOS 12 Симуляторы:
"Cannot load representation of type public.jpeg" "Invalid argument"
Ошибка Domain=NSItemProviderErrorDomain Code=-1000 "Невозможно загрузить представление типа public.jpeg" UserInfo={NSLocalizedDescription= Невозможно загрузить представление типа public.jpeg, NSUnderlyingError=0x6000005e1fe0 {Ошибка Domain=NSPOSIXErrorDomain Code=22 "Неверный аргумент" 22 NSLocalizedDescription = Невозможно выдать расширение "песочницы" для файла "/Users/ Пользователь / Библиотека / Разработчик /CoreSimulator/Devices/4771D8A8-E366-43CB-8A2E-7FF397E4CF6A/data/Media/PhotoData/OutgoingTemp/82644FB8-E3B8-4572D-56FFFF060D-0D0 /IMG_0003.JPG": Неверный аргумент}}}
Но потом я решил проверить это на реальном устройстве под iOS 12.
Все отлично работает на устройстве!
Решение работает для меня, iOS прекратила такую поддержку в iOS12, и я решила эту проблему. Ранее я использовал этот обработчик завершения для этого метода loadItemForTypeIdentifier
completionHandler:^(id <NSSecureCoding> urlItem, NSError *error)
Информация о типе для первого параметра вашего блока Завершения должна быть установлена для класса ожидаемого типа. Например, при запросе текстовых данных вы можете установить тип первого параметра в NSString или NSAttributedString. Поставщик элементов может выполнять простые преобразования типов данных в указанный класс, например, из NSURL в NSData или NSFileWrapper или из NSData в UIImage (в iOS) или NSImage (в macOS). Если данные не могут быть извлечены или приведены к указанному классу, ошибка передается в блок завершения.
- (void)getFilelist :(NSItemProvider *)itemProvider
setPublicIdentifier:(NSString *)indentifier
:(void (^)(void))complete {
[itemProvider loadItemForTypeIdentifier:indentifier options:nil completionHandler:^(NSURL * _Nullable item, NSError * _Null_unspecified error) {
dispatch_async(dispatch_get_main_queue(), ^{
NSURL *selectURl = (NSURL*)item;
if ([[selectURl pathExtension] isEqualToString:@"pdf"] || [[selectURl pathExtension] isEqualToString:@"xlsx"] || [[selectURl pathExtension] isEqualToString:@"csv"]) {
int randomID = arc4random() % 9000 + 1000;
NSString *filename = [[(NSURL*)item path] lastPathComponent];
if ([filename isEqualToString:@"FullSizeRender.jpg"]) {
filename = [NSString stringWithFormat:@"MD%d.jpg",randomID];
}
[_items addObject:selectURl.absoluteString];
complete();
}
});
}];
}
Назовите это так
for (NSItemProvider *itemProvider in item.attachments) {
if([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeText]) {
[self getFilelist:itemProvider
setPublicIdentifier:(NSString *)kUTTypeText
:^{
openFile(self, i, totalnt);
}];
}
if([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypePDF]) {
[self getFilelist:itemProvider
setPublicIdentifier:(NSString *)kUTTypePDF
:^{
openFile(self, i, totalnt);
}];
}
if([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeSpreadsheet]) {
[self getFilelist:itemProvider
setPublicIdentifier:(NSString *)kUTTypeSpreadsheet
:^{
openFile(self, i, totalnt);
}];
}
}