Comment associer des types de fichiers à une application iPhone?


318

Au sujet de l'association de votre application iPhone avec des types de fichiers.

Dans cette question informative, j'ai appris que les applications pouvaient être associées à des protocoles URL personnalisés.

C'était il y a presque un an et depuis lors, Apple a introduit le `` Document Support '' qui va plus loin et permet aux applications de s'associer aux types de fichiers. Il y a beaucoup de discussions dans la documentation sur la façon de configurer votre application pour lancer d'autres applications appropriées lorsqu'elle rencontre un type de fichier inconnu. Cela signifie que l'association ne fonctionne pas prête à l'emploi pour n'importe quelle application, comme l'a fait l'enregistrement du protocole URL.

Cela m'amène à la question: les applications système comme Safari ou Mail ont-elles implémenté ce système pour choisir les applications associées, ou ne feront-elles rien, comme avant?

Réponses:


408

La gestion des types de fichiers est nouvelle avec iPhone OS 3.2 et diffère des schémas d'URL personnalisés déjà existants. Vous pouvez enregistrer votre application pour gérer des types de documents particuliers, et toute application utilisant un contrôleur de documents peut transférer le traitement de ces documents à votre propre application.

Par exemple, mon application Molecules (pour laquelle le code source est disponible) gère les types de fichiers .pdb et .pdb.gz, s'ils sont reçus par e-mail ou dans une autre application prise en charge.

Pour enregistrer le support, vous aurez besoin d'avoir quelque chose comme ce qui suit dans votre 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>

Deux images sont fournies qui seront utilisées comme icônes pour les types pris en charge dans Mail et d'autres applications capables d'afficher des documents. La LSItemContentTypesclé vous permet de fournir un tableau d'identificateurs de type uniforme (UTI) que votre application peut ouvrir. Pour obtenir une liste des UTI définies par le système, voir la référence des identificateurs de type uniforme d'Apple . Encore plus de détails sur les UTI peuvent être trouvés dans la vue d'ensemble des identificateurs de type uniforme d'Apple . Ces guides résident dans le centre de développement Mac, car cette capacité a été portée en face du Mac.

L'un des UTI utilisé dans l'exemple ci-dessus était défini par le système, mais l'autre était un UTI spécifique à l'application. L'UTI spécifique à l'application devra être exportée afin que les autres applications du système puissent en être informées. Pour ce faire, vous devez ajouter une section à votre Info.plist comme suit:

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

Cet exemple particulier exporte l' com.sunsetlakesoftware.molecules.pdbUTI avec l'extension de fichier .pdb, correspondant au type MIME chemical/x-pdb.

Avec cela en place, votre application sera en mesure de gérer les documents joints aux e-mails ou à partir d'autres applications sur le système. Dans Mail, vous pouvez appuyer et maintenir pour afficher une liste d'applications pouvant ouvrir une pièce jointe particulière.

Lorsque la pièce jointe est ouverte, votre application sera démarrée et vous devrez gérer le traitement de ce fichier dans votre -application:didFinishLaunchingWithOptions:méthode de délégué d'application. Il semble que les fichiers chargés de cette manière à partir de Mail soient copiés dans le répertoire Documents de votre application sous un sous-répertoire correspondant à la boîte aux lettres dans laquelle ils sont arrivés. Vous pouvez obtenir l'URL de ce fichier dans la méthode de délégué d'application en utilisant du code comme celui-ci:

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

Notez que c'est la même approche que nous avons utilisée pour gérer les schémas d'URL personnalisés. Vous pouvez séparer les URL de fichier des autres en utilisant un code comme celui-ci:

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

9
Il convient de noter que -application:didFinishLaunchingWithOptions:dans l'application, le délégué n'est appelé que si votre application n'était pas en arrière-plan lorsqu'elle est ouverte pour gérer un fichier.
memmons

3
Éviter QuickLook: raywenderlich.com/1980/…
TheLearner

4
Nous devrions - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)urlégalement utiliser sur iOS 4+
Dmitry

1
Qu'en est-il de la clé «CFBundleTypeExtensions»? Votre extrait ne semble pas le définir. N'est-ce pas nécessaire?
Bram

3
J'ai essayé toutes les méthodes fournies ici et ailleurs, mais j'ai toujours du mal à obtenir des fichiers PNG ouverts. Je travaille avec iOS 7. À certains endroits, ils disent que ce problème commence avec iOS 6. Est-ce vrai? Ne pouvons-nous pas ouvrir des fichiers png dans la boîte de dialogue "Ouvrir dans" avec ios 7?
Kumar Aditya

24

En plus de l'excellente réponse de Brad, j'ai découvert que (sur iOS 4.2.1 au moins) lors de l'ouverture de fichiers personnalisés à partir de l'application Mail, votre application n'est pas déclenchée ou notifiée si la pièce jointe a été ouverte auparavant. La fenêtre contextuelle "Ouvrir avec ..." apparaît, mais ne fait rien.

Cela semble être résolu en (re) déplaçant le fichier du répertoire Inbox. Une approche sûre semble être à la fois de (re) déplacer le fichier lorsqu'il est ouvert (dans -(BOOL)application:openURL:sourceApplication:annotation:) ainsi que de parcourir le répertoire Documents / Inbox, en supprimant tous les éléments, par exemple dans applicationDidBecomeActive:. Ce dernier fourre-tout peut être nécessaire pour remettre l'application dans un état propre, au cas où une importation précédente provoquerait un crash ou serait interrompue.


6
Je ne vois pas ce comportement. Si mon application est en arrière-plan, elle -(BOOL)application:openURL:sourceApplication:annotation:est toujours appelée, même pour les pièces jointes déjà ouvertes. Chaque fois que la pièce jointe est ouverte, un nombre est suffixé au nom de fichier et incrémenté pour être unique - test.text, test-1.txt, test-2.txt, etc.
memmons

Mon répertoire de boîte de réception est vide, mais j'ai pourtant le bouton "Ouvrir dans" qui ne répond pas dans Safari dont vous parlez. Il y a des années, mon application fonctionnait bien, mais elle a soudainement cessé de fonctionner. Je soupçonne qu'Apple a changé quelque chose dans Safari.
Bram

18

GRAND AVERTISSEMENT: assurez-vous UN CENT POUR CENT que votre extension n'est pas déjà liée à un type MIME.

Nous avons utilisé l'extension «.icz» pour nos fichiers personnalisés pour, fondamentalement, jamais, et Safari ne vous laissait jamais les ouvrir en disant «Safari ne peut pas ouvrir ce fichier». peu importe ce que nous avons fait ou essayé avec les trucs UT ci-dessus.

Finalement, j'ai réalisé qu'il existe certaines fonctions UT * C que vous pouvez utiliser pour explorer diverses choses, et tandis que .icz donne la bonne réponse (notre application):

Dans l'application, il s'est chargé en haut, faites-le ...

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

et mettre une pause après cette ligne et voir ce que UTI et ur sont - dans notre cas, c'était notre identifiant comme nous le voulions), et le bundle url (ur) pointait vers le dossier de notre application.

Mais le type MIME que Dropbox nous donne en retour pour notre lien, que vous pouvez vérifier en faisant par exemple

$ 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

Le Content-Type est ce que nous voulons. Dropbox prétend qu'il s'agit d'une entrée de texte / calendrier. Génial. Mais dans mon cas, j'ai DÉJÀ ESSAYÉ DE METTRE du texte / calendrier dans les types MIME de mon application, et cela ne fonctionne toujours pas. Au lieu de cela, lorsque j'essaie d'obtenir l'URI et l'URL de l'ensemble pour le type de mime texte / calendrier,

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

CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

Je vois "com.apple.ical.ics" comme UTI et "... / MobileCoreTypes.bundle /" comme URL de bundle. Pas notre application, mais Apple. J'essaie donc de mettre com.apple.ical.ics dans les LSItemContentTypes à côté des miens, et dans UTConformsTo dans l'exportation, mais pas la peine.

Donc, fondamentalement, si Apple pense vouloir à un moment donné gérer une certaine forme de type de fichier (qui pourrait être créé 10 ans après la mise en ligne de votre application, pensez-vous), vous devrez changer d'extension car ils ne vous laisseront tout simplement pas gérer le type de fichier.


Merci pour l'avertissement utile!
RockSolid

0

Pour gérer tout type de fichiers pour ma propre APP, j'utilise cette configuration pour 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>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.