323 votes

Comment associer des types de fichiers à une application iPhone ?

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

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

C'était il y a près d'un an et depuis, Apple a introduit la "prise en charge des documents", qui va un peu plus loin et permet aux applications de s'associer à des types de fichiers. Il y a beaucoup de discussions dans le documentation sur la façon de configurer votre application pour qu'elle lance d'autres applications appropriées lorsqu'elle rencontre un type de fichier inconnu. Cela signifie que l'association ne fonctionne pas d'emblée pour toutes les applications, comme le faisait l'enregistrement du protocole URL.

Cela m'amène à la question suivante : les applications système comme Safari ou Mail ont-elles mis en place ce système de choix des applications associées, ou ne feront-elles rien, comme avant ?

412voto

Brad Larson Points 122629

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

Par exemple, mon application Molécules (pour lequel le code source est disponible) gère les types de fichiers .pdb et .pdb.gz, s'ils sont reçus par courrier électronique ou dans une autre application prise en charge.

Pour enregistrer le support, vous devez 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. Le site LSItemContentTypes vous permet de fournir un tableau d'identifiants de type uniforme (UTI) que votre application peut ouvrir. Pour obtenir une liste des UTIs définis par le système, consultez le site Web d'Apple. Référence des identificateurs de type uniforme . Vous trouverez encore plus de détails sur les infections urinaires dans le document Apple's Aperçu des identificateurs de type uniforme . Ces guides se trouvent dans le centre de développement Mac, car cette fonctionnalité a été transférée du Mac.

L'une des UTI utilisées dans l'exemple ci-dessus était définie par le système, mais l'autre était une UTI spécifique à une application. L'UTI spécifique à l'application devra être exportée pour que les autres applications du système puissent en prendre connaissance. 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 le com.sunsetlakesoftware.molecules.pdb UTI avec l'extension de fichier .pdb, correspondant au type MIME chemical/x-pdb .

Ainsi, votre application sera en mesure de traiter les documents joints aux courriers électroniques ou provenant d'autres applications du système. Dans Mail, vous pouvez appuyer et maintenir pour faire apparaître une liste d'applications qui peuvent ouvrir une pièce jointe particulière.

Lorsque la pièce jointe sera ouverte, votre application sera lancée et vous devrez gérer le traitement de ce fichier dans votre application -application:didFinishLaunchingWithOptions: méthode de délégation de l'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 électronique dans laquelle ils sont arrivés. Vous pouvez obtenir l'URL de ce fichier dans la méthode du délégué d'application en utilisant un code comme le suivant :

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 fichiers des autres en utilisant un code comme le suivant :

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

0 votes

Je ne suis pas en mesure d'essayer ceci sur le simulateur iPad/iPhone. J'ai téléchargé l'application molécules et Safari ne peut pas ouvrir les fichiers .pdb ou même .gz comme le prétend le fichier Info.plist. Il indique simplement : "Safari ne peut pas télécharger le fichier".

0 votes

@HyLian - Oui, il y a un bogue dans l'application impliquant la façon dont elle télécharge les PDB situées sur certains serveurs que je n'ai pas encore trouvé. C'est indépendant de la gestion des fichiers et des schémas d'URL personnalisés, cependant.

0 votes

@Brad - Excellente réponse - merci. J'ai suivi vos instructions car j'essaie d'enregistrer une application qui ouvrira les fichiers png et jpeg, hélas je n'ai pas réussi à faire en sorte que mail affiche une option d'ouverture dans... pour ces pièces jointes dans mail. Est-il possible d'adopter la même approche et de faire en sorte que mail ouvre les images dans mon application ?

24voto

mvds Points 26475

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 popup "ouvrir avec " apparaît, mais ne fait rien.

Ce problème semble être résolu en (re)déplaçant le fichier du répertoire Inbox. Une approche sûre semble être de (re)déplacer le fichier au fur et à mesure qu'il est ouvert (dans la boîte de réception). -(BOOL)application:openURL:sourceApplication:annotation: ) ainsi qu'en parcourant le répertoire Documents/Inbox, en supprimant tous les éléments, par exemple dans applicationDidBecomeActive: . Ce dernier point 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 votes

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

0 votes

Le répertoire de ma boîte de réception est vide, mais le bouton "Ouvrir dans" de Safari dont vous parlez ne répond pas. Il y a quelques années, mon application fonctionnait bien, mais elle a soudainement cessé de fonctionner. Je soupçonne Apple d'avoir modifié quelque chose dans Safari.

19voto

Kalle Points 6804

GROS AVERTISSEMENT : Assurez-vous à cent pour cent que votre extension n'est pas déjà liée à un type de mime.

Nous avons toujours utilisé l'extension '.icz' pour nos fichiers personnalisés, et Safari ne nous laissait jamais les ouvrir en nous disant "Safari ne peut pas ouvrir ce fichier", peu importe ce que nous faisions ou essayions avec le truc UT ci-dessus.

J'ai fini par me rendre compte qu'il existe des fonctions UT* C que l'on peut utiliser pour explorer diverses choses, et que si .icz donne la bonne réponse (notre application) :

Dans l'application, il y a un chargement en haut, il suffit de faire ça...

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

et mettre break après cette ligne et voir ce que sont UTI et ur -- 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 renvoie pour notre lien, que vous pouvez vérifier en faisant par ex.

$ 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 affirme qu'il s'agit d'une entrée de texte/calendrier. Très bien. Mais dans mon cas, j'ai DÉJÀ ESSAYÉ d'insérer text/calendar dans les types de mime de mon application, et cela ne fonctionne toujours pas. Au lieu de cela, lorsque j'essaie d'obtenir l'UTI et le bundle url pour le mimetype text/calendar,

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 du bundle. Pas notre application, mais Apple. J'essaie donc de mettre com.apple.ical.ics dans le LSItemContentTypes à côté du mien, et dans UTConformsTo dans l'exportation, mais sans succès.

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

0 votes

Merci pour cet avertissement utile !

0voto

SLdragon Points 520

Pour traiter tout type de fichiers pour mon 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>

0 votes

Quel pourrait être le "LSItemContentTypes" pour le fichier TIFF ? Pourriez-vous m'aider ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X