Bagaimana cara mengaitkan tipe file dengan aplikasi iPhone?

318

Mengenai mengaitkan aplikasi iPhone Anda dengan jenis file.

Dalam pertanyaan informatif ini saya mengetahui bahwa aplikasi dapat dikaitkan dengan protokol URL khusus.

Itu hampir satu tahun yang lalu dan sejak itu Apple memperkenalkan 'Dukungan Dokumen' yang melangkah lebih jauh dan memungkinkan aplikasi untuk dikaitkan dengan jenis file. Ada banyak pembicaraan dalam dokumentasi tentang cara mengatur aplikasi Anda untuk meluncurkan aplikasi lain yang sesuai ketika menemukan jenis file yang tidak dikenal. Ini berarti asosiasi tidak berfungsi di luar kotak untuk aplikasi apa pun, seperti yang dilakukan pendaftaran protokol URL.

Ini mengarahkan saya ke pertanyaan: apakah aplikasi sistem seperti Safari atau Mail menerapkan sistem ini untuk memilih aplikasi terkait, atau akankah mereka tidak melakukan apa pun, seperti sebelumnya?

Damian Mihai
sumber

Jawaban:

408

Penanganan tipe file baru dengan iPhone OS 3.2, dan berbeda dari skema URL khusus yang sudah ada. Anda dapat mendaftarkan aplikasi Anda untuk menangani jenis dokumen tertentu, dan aplikasi apa pun yang menggunakan pengontrol dokumen dapat menyerahkan pemrosesan dokumen ini ke aplikasi Anda sendiri.

Misalnya, Molekul aplikasi saya (yang menyediakan kode sumber) menangani jenis file .pdb dan .pdb.gz, jika diterima melalui email atau dalam aplikasi lain yang didukung.

Untuk mendaftar dukungan, Anda harus memiliki sesuatu seperti yang berikut ini di Info.plist Anda:

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

Dua gambar disediakan yang akan digunakan sebagai ikon untuk jenis yang didukung di Mail dan aplikasi lain yang mampu menunjukkan dokumen. The LSItemContentTypeskunci memungkinkan Anda memberikan serangkaian Jenis Identifier Uniform (ISK) bahwa aplikasi Anda dapat membuka. Untuk daftar ISK yang ditentukan sistem, lihat Referensi Jenis Seragam Pengidentifikasi Apple . Rincian lebih lanjut tentang ISK dapat ditemukan di Apple Uniform Type Identifiers Overview . Panduan tersebut berada di pusat pengembang Mac, karena kemampuan ini telah porting di seberang Mac.

Salah satu ISK yang digunakan dalam contoh di atas adalah sistem-didefinisikan, tetapi yang lain adalah ISK khusus aplikasi. ISK khusus aplikasi perlu diekspor sehingga aplikasi lain pada sistem dapat dibuat sadar akan hal itu. Untuk melakukan ini, Anda akan menambahkan bagian ke Info.plist Anda seperti berikut:

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

Contoh khusus ini mengekspor com.sunsetlakesoftware.molecules.pdbUTI dengan ekstensi file .pdb, sesuai dengan tipe MIME chemical/x-pdb.

Dengan ini, aplikasi Anda akan dapat menangani dokumen yang dilampirkan ke email atau dari aplikasi lain pada sistem. Di Mail, Anda dapat mengetuk dan menahan untuk memunculkan daftar aplikasi yang dapat membuka lampiran tertentu.

Ketika lampiran dibuka, aplikasi Anda akan dimulai dan Anda harus menangani pemrosesan file ini dalam -application:didFinishLaunchingWithOptions:metode delegasi aplikasi Anda . Tampaknya file yang dimuat dengan cara ini dari Mail disalin ke direktori Dokumen aplikasi Anda di bawah subdirektori yang sesuai dengan kotak email tempat mereka masuk. Anda bisa mendapatkan URL untuk file ini dalam metode delegasi aplikasi menggunakan kode seperti berikut:

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

Perhatikan bahwa ini adalah pendekatan yang sama yang kami gunakan untuk menangani skema URL khusus. Anda dapat memisahkan URL file dari yang lain dengan menggunakan kode seperti berikut:

if ([url isFileURL])
{
    // Handle file being passed in
}
else
{
    // Handle custom URL scheme
}
Brad Larson
sumber
9
Perlu dicatat bahwa -application:didFinishLaunchingWithOptions:dalam delegasi aplikasi hanya dipanggil jika aplikasi Anda tidak di-background ketika dibuka untuk menangani file.
peringatan
3
Menghindari QuickLook: raywenderlich.com/1980/…
TheLearner
4
Kita juga harus menggunakan - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)urliOS 4+
Dmitry
1
Bagaimana dengan kunci 'CFBundleTypeExtensions'? Cuplikan Anda tampaknya tidak mengaturnya. Apakah itu tidak wajib?
Bram
3
Saya telah mencoba semua metodologi yang disediakan di sini dan di tempat lain juga, tetapi saya masih berjuang untuk mendapatkan file PNG terbuka. Saya bekerja dengan iOS 7. Di beberapa tempat mereka mengatakan bahwa masalah ini dimulai dengan ios 6. Benarkah? Tidak bisakah kita membuka file png di kotak dialog "Buka di" dengan ios 7?
Kumar Aditya
24

Selain jawaban Brad yang sangat baik, saya telah menemukan bahwa (setidaknya di iOS 4.2.1) ketika membuka file khusus dari aplikasi Mail, aplikasi Anda tidak dipecat atau diberitahukan jika lampiran telah dibuka sebelumnya. Munculan "buka dengan ..." muncul, tetapi tidak melakukan apa pun.

Ini tampaknya diperbaiki dengan (kembali) memindahkan file dari direktori Inbox. Pendekatan yang aman tampaknya adalah untuk kedua (kembali) memindahkan file saat dibuka (in -(BOOL)application:openURL:sourceApplication:annotation:) serta melalui direktori Documents / Inbox, menghapus semua item, misalnya dalam applicationDidBecomeActive:. Tangkapan terakhir itu semua mungkin diperlukan untuk mendapatkan aplikasi dalam keadaan bersih lagi, seandainya impor sebelumnya menyebabkan kerusakan atau terganggu.

mvds
sumber
6
Saya tidak melihat perilaku ini. Jika aplikasi saya dilatar belakangi, -(BOOL)application:openURL:sourceApplication:annotation:selalu dipanggil, bahkan untuk lampiran yang sudah dibuka. Setiap kali tambahan lampiran dibuka, nomor suffixed ke nama file dan bertambah menjadi unik - test.text, test-1.txt, test-2.txt, dll.
memmons
Direktori Kotak Masuk saya kosong, tetapi saya memiliki tombol "Buka Masuk" yang tidak responsif di Safari yang Anda bicarakan. Bertahun-tahun yang lalu, aplikasi saya bekerja dengan baik, tetapi tiba-tiba berhenti berfungsi. Saya menduga Apple mengubah sesuatu di Safari.
Bram
18

PERINGATAN BESAR: Buat SATU SERATUS PERSEN yakin bahwa ekstensi Anda belum terikat ke beberapa jenis pantomim.

Kami menggunakan ekstensi '.icz' untuk file khusus kami untuk, pada dasarnya, dan Safari tidak akan pernah membiarkan Anda membukanya dengan mengatakan "Safari tidak dapat membuka file ini." tidak peduli apa yang kami lakukan atau coba dengan hal-hal UT di atas.

Akhirnya saya menyadari bahwa ada beberapa fungsi UT * C yang dapat Anda gunakan untuk menjelajahi berbagai hal, dan sementara .icz memberikan jawaban yang tepat (aplikasi kami):

Dalam aplikasi memuat di atas, lakukan saja ini ...

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

dan hancurkan garis itu dan lihat apa ISK dan Anda - dalam kasus kami, itu adalah pengidentifikasi kami seperti yang kami inginkan), dan url bundel (ur) bundel menunjuk ke folder aplikasi kami.

Tetapi tipe MIME yang diberikan Dropbox kepada kami untuk tautan kami, yang dapat Anda periksa dengan melakukan mis

$ 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

Jenis-Konten adalah apa yang kita inginkan. Dropbox mengklaim ini adalah entri teks / kalender. Bagus. Tetapi dalam kasus saya, saya sudah MENCOBA MENEMPATKAN teks / kalender ke dalam jenis pantomim aplikasi saya, dan itu masih tidak berfungsi. Sebaliknya, ketika saya mencoba untuk mendapatkan UTI dan bundel url untuk mimetype teks / kalender,

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

CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

Saya melihat "com.apple.ical.ics" sebagai UTI dan "... / MobileCoreTypes.bundle /" sebagai URL bundel. Bukan aplikasi kami, tapi Apple. Jadi saya mencoba memasukkan com.apple.ical.ics ke dalam LSItemContentTypes di samping milik saya, dan ke UTConformsTo dalam ekspor, tetapi jangan pergi.

Jadi pada dasarnya, jika Apple berpikir mereka ingin menangani suatu bentuk tipe file (yang dapat dibuat 10 tahun setelah aplikasi Anda aktif, ingatlah), Anda harus mengubah ekstensi karena mereka tidak akan membiarkan Anda menangani jenis file.

Kalle
sumber
Terima kasih atas peringatan yang bermanfaat!
RockSolid
0

Untuk menangani semua jenis file untuk aplikasi saya sendiri, saya menggunakan konfigurasi ini untuk 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>
SLdragon
sumber