Як я пов’язую типи файлів із додатком iPhone?


318

Що стосується асоціації вашого додатка iPhone з типами файлів.

У цьому інформативному запитанні я дізнався, що програми можуть бути пов’язані зі спеціальними протоколами URL-адрес.

Це було майже рік тому, і з тих пір Apple представила «Підтримку документів», яка йде на крок далі і дозволяє програмам зв’язуватися з типами файлів. Існує багато розмов в документації про те , як налаштувати додаток для запуску інших додатків , відповідних коли він зустрічає невідомий тип файлу. Це означає, що асоціація не спрацьовує для будь-якого додатка, як, наприклад, реєстрація протоколів URL.

Це підштовхує мене до питання: чи реалізовували цю систему системні програми, такі як Safari або Mail, для вибору пов'язаних програм, або вони нічого не робитимуть, як раніше?

Відповіді:


408

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

Наприклад, моє додаток Молекули (для яких доступний вихідний код) обробляє .pdb і .pdb.gz типи файлів, якщо вони будуть отримані по електронній пошті або в іншому підтримуваному додатку.

Щоб зареєструвати підтримку, вам потрібно буде мати щось подібне у своєму Info.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>

Надано два зображення, які будуть використовуватися як піктограми для підтримуваних типів у Пошті та інших програмах, здатних показувати документи. LSItemContentTypesКлюч дозволяє забезпечити ряд однакових типу ідентифікаторів (ІМП) , що ваш додаток може відкрити. Щоб переглянути список визначених системою UTI, див . Посилання на уніфіковані ідентифікатори типу Apple . Ще детальніше про UTI можна знайти в Огляді Apple Uniform Type Identifier . Ці посібники перебувають у центрі розробників Mac, оскільки ця можливість перенесена через Mac.

Один з UTI, використаних у наведеному вище прикладі, був визначений системою, а інший - UTI, що стосується додатків. Необхідно експортувати UTI, що відповідає додатку, щоб інші програми в системі могли знати про це. Для цього вам слід додати розділ до свого Info.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.pdbUTI з розширенням файлу .pdb, що відповідає типу MIME chemical/x-pdb.

Якщо це на місці, ваша програма зможе обробляти документи, приєднані до електронних листів або інших програм у системі. У пошті можна натиснути і утримувати, щоб відкрити список програм, які можуть відкрити певне вкладення.

Коли вкладення буде відкрито, ваша програма буде запущена, і вам потрібно буде обробити цей файл у -application:didFinishLaunchingWithOptions:способі делегування програми. Здається, що файли, завантажені таким чином з Пошти, копіюються в каталог Документів вашої програми під підкаталогом, відповідним до того, до якого вікна електронної пошти вони надійшли. Ви можете отримати URL-адресу цього файлу в методі делегування програми, використовуючи такий код:

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

Зауважте, що це той самий підхід, який ми використовували для обробки користувацьких схем URL-адрес. Ви можете відокремити URL-адреси файлів від інших, скориставшись таким кодом:

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

9
Слід зазначити, що -application:didFinishLaunchingWithOptions:делегат додатка викликається лише в тому випадку, якщо ваш додаток не було фоновим режимом при відкритті для обробки файлу.
memmons

3
Уникнення QuickLook: raywenderlich.com/1980/…
TheLearner

4
Ми також повинні використовувати - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)urlна iOS 4+
Дмитро

1
Що з ключовим "CFBundleTypeExtensions"? Схоже, ваш фрагмент не встановлює його. Це не потрібно?
Брем

3
Я перепробував всю методологію, надану тут, і в інших місцях, але я все ще намагаюся отримати відкриті файли PNG. Я працюю з iOS 7. Десь вони кажуть, що ця проблема починається з ios 6. Це правда? Чи не можемо ми відкрити файли png у діалоговому вікні "Відкрити в" за допомогою ios 7?
Кумар Адітя

24

Окрім відмінної відповіді Бреда, я з’ясував, що (принаймні, на iOS 4.2.1), коли відкриваєте власні файли з програми Mail, ваш додаток не звільняється та не повідомляється, якщо вкладення було відкрито раніше. З'являється спливаюче вікно "відкрити з ...", але просто нічого не робить.

Це, здається, виправлено (пере) переміщенням файлу з папки Вхідні. Здається, що безпечним підходом є як (пере) переміщення файлу під час його відкриття (в -(BOOL)application:openURL:sourceApplication:annotation:), так і проходження через каталог Документи / Вхідні, видалення всіх елементів, наприклад в applicationDidBecomeActive:. Цей останній улов може знадобитися, щоб знову застосувати додаток у чистому стані, якщо попередній імпорт спричинить збій або буде перервано.


6
Я не бачу такої поведінки. Якщо мій додаток є фоновим, -(BOOL)application:openURL:sourceApplication:annotation:завжди викликається, навіть для вкладених файлів, які вже були відкриті. Кожен додатковий раз, коли вкладення відкриваються, до назви файлу додається число і збільшується, щоб бути унікальним - test.text, test-1.txt, test-2.txt тощо
пам’ятки

У моїй папці "Вхідні" порожнє, але все ж у мене є невідповідна кнопка "Відкрити" на Safari, про яку ви говорите. Роки тому мій додаток працював чудово, але раптом він перестав працювати. Я підозрюю, що Apple щось змінила в Safari.
Брам

18

ВЕЛИЧЕ ПОПЕРЕДЖЕННЯ: Переконайтесь, що ОДНЕ СТОРОНУВАННЯ переконайтесь, що ваше розширення вже не прив'язане до якогось типу mime.

Ми використовували розширення '.icz' для своїх власних файлів для, в основному, коли-небудь, і Safari просто ніколи не дозволить вам відкрити їх, кажучи: "Safari не може відкрити цей файл". незалежно від того, що ми робили або намагалися з вищевказаними матеріалами.

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

У додатку ви завантажилися вгорі, просто зробіть це ...

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

і поставте перерву після цього рядка і подивіться, що таке UTI та ур - у нашому випадку це був наш ідентифікатор, як ми хотіли), а URL-адреса пакета (ур) вказувала на папку нашого додатка.

Але тип 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 свого додатка, і він все ще не працює. Натомість, коли я намагаюся отримати UTI та URL-адресу пакету для текстового / календарного міметипу,

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

CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

Я бачу "com.apple.ical.ics" як UTI та "... / MobileCoreTypes.bundle /" як URL-адресу пакета. Не наш додаток, а Apple. Тому я намагаюся ввести com.apple.ical.ics у LSItemContentTypes поряд із моїми власними та в UTConformsTo при експорті, але не йду.

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


Дякуємо за корисне попередження!
RockSolid

0

Для обробки будь-якого типу файлів для мого власного додатка я використовую цю конфігурацію для CFBundleDocumentTypes:

    <key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeName</key>
            <string>IPA</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.item</string>
                <string>public.content</string>
                <string>public.data</string>
                <string>public.database</string>
                <string>public.composite-content</string>
                <string>public.contact</string>
                <string>public.archive</string>
                <string>public.url-name</string>
                <string>public.text</string>
                <string>public.plain-text</string>
                <string>public.source-code</string>
                <string>public.executable</string>
                <string>public.script</string>
                <string>public.shell-script</string>
                <string>public.xml</string>
                <string>public.symlink</string>
                <string>org.gnu.gnu-zip-archve</string>
                <string>org.gnu.gnu-tar-archive</string>
                <string>public.image</string>
                <string>public.movie</string>
                <string>public.audiovisual-​content</string>
                <string>public.audio</string>
                <string>public.directory</string>
                <string>public.folder</string>
                <string>com.apple.bundle</string>
                <string>com.apple.package</string>
                <string>com.apple.plugin</string>
                <string>com.apple.application-​bundle</string>
                <string>com.pkware.zip-archive</string>
                <string>public.filename-extension</string>
                <string>public.mime-type</string>
                <string>com.apple.ostype</string>
                <string>com.apple.nspboard-typ</string>
                <string>com.adobe.pdf</string>
                <string>com.adobe.postscript</string>
                <string>com.adobe.encapsulated-​postscript</string>
                <string>com.adobe.photoshop-​image</string>
                <string>com.adobe.illustrator.ai-​image</string>
                <string>com.compuserve.gif</string>
                <string>com.microsoft.word.doc</string>
                <string>com.microsoft.excel.xls</string>
                <string>com.microsoft.powerpoint.​ppt</string>
                <string>com.microsoft.waveform-​audio</string>
                <string>com.microsoft.advanced-​systems-format</string>
                <string>com.microsoft.advanced-​stream-redirector</string>
                <string>com.microsoft.windows-​media-wmv</string>
                <string>com.microsoft.windows-​media-wmp</string>
                <string>com.microsoft.windows-​media-wma</string>
                <string>com.apple.keynote.key</string>
                <string>com.apple.keynote.kth</string>
                <string>com.truevision.tga-image</string>
            </array>
            <key>CFBundleTypeIconFiles</key>
            <array>
                <string>Icon-76@2x</string>
            </array>
        </dict>
    </array>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.