Как связать типы файлов с приложением iPhone?

по вопросу о связывании вашего приложения iPhone с типами файлов.

на этой информативный вопрос я узнал, что приложения могут быть связаны с пользовательскими протоколами URL.

Это было почти год назад, и с тех пор Apple представила "поддержку документов", которая идет дальше и позволяет приложениям связываться с типами файлов. В документация о том, как настроить приложение для запуска других соответствующих приложений при обнаружении неизвестного типа файла. Это означает, что ассоциация не работает "из коробки" для любого приложения, как адрес регистрации в протоколе.

Это приводит меня к вопросу: есть ли системные приложения, такие как Safari или Mail, реализовали эту систему для выбора связанных приложений, или они ничего не будут делать, как и раньше?

3 ответов


обработка типов файлов является новой с iPhone OS 3.2 и отличается от уже существующих пользовательских схем URL. Вы можете зарегистрировать приложение для обработки определенных типов документов, и любое приложение, использующее контроллер документов, может передать обработку этих документов в ваше собственное приложение.

например, мое приложение молекулы (для которых доступен исходный код) обрабатывает .pdb и .распределительная плата.типы файлов gz, если они получены по электронной почте или в другое поддерживаемое приложение.

чтобы зарегистрировать поддержку, вам нужно будет иметь что-то вроде следующего в вашей информации.файл plist:

<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeIconFiles</key>
        <array>
            <string>Document-molecules-320.png</string>
            <string>Document-molecules-64.png</string>
        </array>
        <key>CFBundleTypeName</key>
        <string>Molecules Structure File</string>
        <key>CFBundleTypeRole</key>
        <string>Viewer</string>
        <key>LSHandlerRank</key>
        <string>Owner</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>com.sunsetlakesoftware.molecules.pdb</string>
            <string>org.gnu.gnu-zip-archive</string>
        </array>
    </dict>
</array>

предусмотрены два изображения, которые будут использоваться в качестве значков для поддерживаемых типов в Почте и других приложениях, способных отображать документы. The LSItemContentTypes key позволяет предоставить массив идентификаторов однородных типов (UTIs), которые может открыть приложение. Список системных UTIs см. В разделе Единообразные Идентификаторы Типов Ссылка. Еще более подробно об UTIs можно найти в Apple Обзор Идентификаторов Единого Типа. Эти руководства находятся в Центре разработчиков Mac, поскольку эта возможность была перенесена через Mac.

один из UTI, используемых в приведенном выше примере, был определен системой, но другой был специфичным для приложения UTI. Для того чтобы другие приложения в системе могли быть осведомлены об этом, необходимо экспортировать UTI для конкретного приложения. Для этого вам добавить раздел к вашей информации.plist нравится следующее:

<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>
</array>

этот конкретный пример экспортирует com.sunsetlakesoftware.molecules.pdb UTI с .pdb расширение файла, соответствующее типу MIME chemical/x-pdb.

С этим на месте, ваше приложение сможет обрабатывать документы, прикрепленные к электронной почте или из других приложений в системе. В Mail можно нажать и удерживать, чтобы открыть список приложений, которые могут открыть конкретное вложение.

когда приложение открыто, ваше приложение будет запущено, и вам нужно будет обработать этот файл в вашем -application:didFinishLaunchingWithOptions: метод делегата приложения. Похоже, что файлы, загруженные таким образом из почты, копируются в каталог документов вашего приложения в подкаталоге, соответствующем почтовому ящику, в котором они прибыли. Вы можете получить URL-адрес этого файла в методе делегата приложения, используя следующий код:

NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];

обратите внимание, что это тот же подход, который мы использовали для обработки пользовательских схем URL. Вы можете отделить URL-адреса файлов от других, используя следующий код:

if ([url isFileURL])
{
    // Handle file being passed in
}
else
{
    // Handle custom URL scheme
}

в дополнение к отличному ответу Брэда я обнаружил, что (по крайней мере, на iOS 4.2.1) при открытии пользовательских файлов из почтового приложения ваше приложение не запускается или не уведомляется, если вложение было открыто раньше. Появляется всплывающее окно " открыть с...", но ничего не делает.

это, кажется, исправлено путем (re)перемещения файла из папки "Входящие". Безопасный подход, по-видимому, заключается в том, чтобы (re)переместить файл по мере его открытия (в -(BOOL)application:openURL:sourceApplication:annotation:), а также просматривая документы / входящие каталог, удаляющий все элементы, например в applicationDidBecomeActive:. Эта последняя уловка может потребоваться, чтобы снова получить приложение в чистом состоянии, если предыдущий импорт вызывает сбой или прерывается.


большое предупреждение: убедитесь на сто процентов, что ваше расширение еще не привязано к некоторому типу mime.

мы использовали расширение '.icz ' для наших пользовательских файлов, в основном, когда-либо, и Safari просто никогда не позволит вам открыть их, говоря "Safari не может открыть этот файл."независимо от того, что мы сделали или попробовали с материалом UT выше.

В конце концов я понял, что есть некоторые функции UT* C, которые вы можете использовать для изучения различных вещей, и в то время как .компанией дает правильный ответ (наш app):

в приложении действительно загружается сверху, просто сделайте это...

NSString * UTI = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, 
                                                                   (CFStringRef)@"icz", 
                                                                   NULL);
CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

и поставить перерыв после этой строки и посмотреть, что UTI и ur-в нашем случае это был наш идентификатор, как мы хотели), и URL-адрес пакета (ur) указывал на папку нашего приложения.

но тип MIME, который Dropbox возвращает нам для нашей ссылки, которую вы можете проверить, например

$ curl -D headers THEURLGOESHERE > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 27393  100 27393    0     0  24983      0  0:00:01  0:00:01 --:--:-- 28926
$ cat headers
HTTP/1.1 200 OK
accept-ranges: bytes
cache-control: max-age=0
content-disposition: attachment; filename="123.icz"
Content-Type: text/calendar
Date: Fri, 24 May 2013 17:41:28 GMT
etag: 872926d
pragma: public
Server: nginx
x-dropbox-request-id: 13bd327248d90fde
X-RequestId: bf9adc56934eff0bfb68a01d526eba1f
x-server-response-time: 379
Content-Length: 27393
Connection: keep-alive

тип контента-это то, что мы хотим. Dropbox утверждает, что это текст/запись календаря. Отличный. Но в моей случай, я уже пытался поместить текст / календарь в типы mime моего приложения, и он все еще не работает. Вместо этого, когда я пытаюсь получить url UTI и bundle для типа текста / календаря,

NSString * UTI = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,
                                                                   (CFStringRef)@"text/calendar", 
                                                                   NULL);

CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

Я вижу " com.яблоко.программа iCal.ics " как UTI и ".../ MobileCoreTypes.bundle / " в качестве URL-адреса пакета. Не наше приложение, а Apple. Поэтому я пытаюсь поставить com.яблоко.программа iCal.ics в LSItemContentTypes рядом с моим собственным и в UTConformsTo в экспорте, но не идет.

Так в основном, если Apple думает, что они хотят в какой-то момент обрабатывать некоторую форму типа файла (который может быть создан через 10 лет после того, как ваше приложение будет жить, имейте в виду), вам придется изменить расширение, потому что они просто не позволят вам обрабатывать тип файла.