Пользовательский файл расширения не открывается в iMessage

В моем приложении мне нужно отправить несколько пользовательских файлов данных с одного устройства на другое, и я пытаюсь сделать это с помощью Mail, iMessage/Message и Airdrop.

Это прекрасно работает с Mail и Airdrop, но с iMessage и работает нормально, но на принимающей стороне я не могу открыть файлы. Это просто не позволяет мне с этим что-то делать.

Есть идеи??

Вот как выглядит мой тип документа:

<key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>abc.png</string>
            <key>CFBundleTypeName</key>
            <string>ABC Custom Data type</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>Handler Rank</key>
            <string>Owner</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.company.abc.wd</string>
            </array>
        </dict>
    </array>

Вот как я отправляю данные:

NSMutableDictionary * dict = [NSMutableDictionary dictionary];
[dict setObject:currentDataSet forKey:@"actualData"];
NSData * meetingData = [NSKeyedArchiver archivedDataWithRootObject:dict];

Meeting * dataItem = [[Meeting alloc]initWithData:meetingData
               type:@"com.abc.xyz.wd" subject:@"Meeting"
          previewImage:[UIImage imageNamed:@"appIcon.png"]];

UIActivityViewController * activityController =
  [[UIActivityViewController alloc]initWithActivityItems:@[dataItem]
                                   applicationActivities:nil];

activityController.excludedActivityTypes =
       @[UIActivityTypePostToTwitter, UIActivityTypePostToWeibo];

[self presentViewController:activityController animated:YES completion:nil];

3 ответа

Этот ответ верен в том смысле, что пользовательский документ можно открыть из сообщений, если он соответствует public.text, Недостаток этого решения заключается в том, что документ предварительно просматривается в виде необработанного текста, что может быть нежелательным результатом.

Документы, соответствующие public.data можно открыть из приложения Сообщения без предварительного просмотра в виде необработанного текста, создав расширение для предварительного просмотра Quick Look. Существует не так много документации о том, как создать расширение Quick Look Preview, но это довольно просто:

  1. В Xcode выберите, File > New > Target,

  2. Выберите Quick Look Preview Extension, дайте вашему расширению имя и нажмите Finish.

  3. в info.plist для вновь созданного расширения добавьте новый элемент в NSExtension > NSExtensionAttributes > QLSupportedContentTypesи установите для этого элемента значение типа документа вашего приложения. Например:

    ...
    <key>NSExtension</key>
    <dict>
        <key>NSExtensionAttributes</key>
        <dict>
            <key>QLSupportedContentTypes</key>
            <array>
                <string>com.company.abc.wd</string>
            </array>
            <key>QLSupportsSearchableItems</key>
            <true/>
        </dict>
        <key>NSExtensionMainStoryboard</key>
        <string>MainInterface</string>
        <key>NSExtensionPointIdentifier</key>
        <string>com.apple.quicklook.preview</string>
    </dict>
    ...
    
  4. использование MainInterface.storyboard а также PreviewViewController чтобы определить макет вашего предварительного просмотра Quick Look. Более конкретно, прочитайте данные с URL, указанного в preparePreviewOfFile функции и заполнить ViewController соответственно. Краткий пример (в Swift 4):

    func preparePreviewOfFile(at url: URL, completionHandler handler: @escaping (Error?) -> Void) {
        do {
            let documentData = try Data(contentsOf: url)
    
            // Populate the ViewController with a preview of the document.
    
            handler(nil)
        } catch let error {
            handler(error)
        }
    }
    

Некоторые подводные камни, с которыми я столкнулся при создании своего расширения:

  • Экспортируемый идентификатор UTI должен был быть в нижнем регистре. Когда некоторые символы были в верхнем регистре, предварительный просмотр Quick Look никогда не отображался, хотя я использовал ту же заглавную букву в своем расширении Quick Look Preview.

  • Quick Look Preview Расширения не могут ссылаться на динамические библиотеки. Если динамическая библиотека связана, предварительный просмотр не будет загружен.

  • Quick Look ViewController не имеет кнопок. Если он содержит кнопку, предварительный просмотр не будет загружен.

Дополнительные ресурсы:

Я наткнулся на этот пост во время поиска аналогичного решения. Мне удалось отправить по электронной почте пользовательские файлы из моего приложения и открыть его по электронной почте или использовать с AirDrop. Если я отправлял его через iMessage, он даже появлялся с моим собственным значком, но когда я нажимал на него в iMessage, ничего не происходило.

Помните, что вам нужно что-то вроде следующего в вашем plist-файле (из Как связать типы файлов с приложением iPhone?)

<key>UTExportedTypeDeclarations</key>
<array>
    <dict>
        <key>UTTypeConformsTo</key>
    <array>
        <string>public.plain-text</string>
        <string>public.text</string>
    </array>
    <key>UTTypeDescription</key>
    <string>Molecules Structure File</string>
    <key>UTTypeIdentifier</key>
    <string>com.sunsetlakesoftware.molecules.pdb</string>
    <key>UTTypeTagSpecification</key>
    <dict>
        <key>public.filename-extension</key>
        <string>pdb</string>
        <key>public.mime-type</key>
        <string>chemical/x-pdb</string>
    </dict>
</dict>

ПРИМЕЧАНИЕ: у меня было что-то очень похожее для моего приложения, НО в UTTypeConforms, чтобы у меня был только public.data, так как мои файлы - это файлы данных в формате ZIP.

Я обнаружил, что добавив public.text в качестве второго элемента в массиве, он будет активен в iMessage. Кроме того, если я добавлю public.plain-text в качестве третьего элемента, мой файл будет иметь значок "Страницы" вместо значка (поэтому я удалил его)

Я надеюсь, что это помогает кому-то. Мне потребовались часы, чтобы докопаться до сути.

Значение в вашем Info.plist для LSItemContentTypes ключ должен равняться объему, объявленному вашим объектом Meeting.

Предположительно, ваш объект Meeting придерживается UIActivityItemSource протокол. Убедитесь, что значение, которое вы возвращаете (из метода делегата activityViewController:dataTypeIdentifierForActivityType:) соответствует значению, которое вы объявили как читаемое в вашем Info.plist,

Другие вопросы по тегам