Comment puis-je obtenir un chemin accessible en écriture sur l’iPhone?

Je publie cette question parce que j’avais une réponse complète à cette question pour un autre article, quand j’ai trouvé que cela ne s’appliquait pas à l’original mais que je pensais que c’était trop utile pour perdre. Ainsi, j’ai également fait de ceci un wiki de communauté, afin que d’autres puissent étoffer les questions et les réponses. Si vous trouvez la réponse utile, votez pour la question – étant un wiki communautaire, je ne devrais pas obtenir de points pour ce vote mais cela aidera les autres à le trouver

Comment puis-je obtenir un chemin d’access aux écritures de fichiers autorisées sur l’iPhone? Vous pouvez (à la légère) écrire n’importe où sur le simulateur, mais sur l’iPhone, vous ne pouvez écrire que dans des endroits spécifiques.

Il existe trois types de chemins inscriptibles à prendre en compte: le premier est Documents, où vous stockez les éléments que vous souhaitez conserver et mettre à la disposition de l’utilisateur via iTunes (à partir de 3.2):

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSSsortingng *documentsDirectory = [paths objectAtIndex:0]; 

Deuxièmement, et très similaire au répertoire Documents, il y a le dossier Library, où vous stockez les fichiers de configuration et les bases de données inscriptibles que vous souhaitez conserver, mais vous ne voulez pas que l’utilisateur puisse utiliser iTunes:

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); NSSsortingng *libraryDirectory = [paths objectAtIndex:0]; 

Notez que même si l’utilisateur ne peut pas voir les fichiers dans iTunes en utilisant un périphérique antérieur à 3.2 (l’iPad), la constante NSLibraryDirectory est disponible depuis iPhoneOS 2.0 et peut donc être utilisée pour cibler les versions 3.0 (ou même plus tôt si vous le faites encore) cette). De plus, l’utilisateur ne pourra rien voir, sauf si vous marquez une application comme permettant aux utilisateurs de modifier des documents. Ainsi, si vous utilisez Documents aujourd’hui, vous êtes satisfait du moment que vous changez d’emplacement lors de la mise à jour.

Enfin, il existe un répertoire de cache où vous pouvez placer des images qui ne vous intéressent pas pour le long terme (le téléphone peut les supprimer à un moment donné):

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); NSSsortingng *cachePath = [paths objectAtIndex:0]; BOOL isDir = NO; NSError *error; if (! [[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&isDir] && isDir == NO) { [[NSFileManager defaultManager] createDirectoryAtPath:cachePath withIntermediateDirectories:NO atsortingbutes:nil error:&error]; } 

Notez que vous devez créer le répertoire Caches pour cela, donc lorsque vous écrivez, vous devez vérifier et créer à chaque fois! Une sorte de douleur, mais c’est comme ça.

Ensuite, lorsque vous avez un chemin accessible en écriture, vous ajoutez simplement un nom de fichier comme ceci:

 NSSsortingng *filePath = [documentsDirectory ssortingngByAppendingPathComponent:@"SomeDirectory/SomeFile.txt"]; 

ou

 NSSsortingng *filePath = [cachePath ssortingngByAppendingPathComponent:@"SomeTmpFile.png"]; 

Utilisez ce chemin pour lire ou écrire.

Notez que vous pouvez créer des sous-répertoires dans l’un ou l’autre de ces chemins inscriptibles, celui de la chaîne d’exemple ci-dessus utilisant (en supposant qu’un ait été créé).

Si vous essayez d’écrire une image dans la photothèque, vous ne pouvez pas utiliser les appels du système de fichiers pour cela – vous devez plutôt avoir un UIImage en mémoire et utiliser l’appel de la fonction UIImageWriteToSavedPhotosAlbum() défini par UIKit. Vous n’avez aucun contrôle sur le format de destination ou les niveaux de compression, et vous ne pouvez pas joindre de fichier EXIF ​​de cette manière.

Merci à Kendall & Dave, ci-dessus, et je pensais que cet amendement était utile. Lors de l’utilisation du code de débogage unique, j’ai utilisé cette astuce du NSBlog de Mike Ash pour éliminer les variables temporaires isDir & error, minimisant le nombre de lignes et rendant le verbosité presque supportable:

 NSFileHandle *dumpFileHandle = nil; #ifdef DEBUG NSSsortingng *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]; if (![[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&(BOOL){0}]) [[NSFileManager defaultManager] createDirectoryAtPath:cachePath withIntermediateDirectories:YES atsortingbutes:nil error:&(NSError*){nil}]; NSSsortingng *dumpPath = [cachePath ssortingngByAppendingPathComponent:@"dump.txt"]; [[NSFileManager defaultManager] createFileAtPath:dumpPath contents:nil atsortingbutes:nil]; [(dumpFileHandle = [NSFileHandle fileHandleForWritingAtPath:dumpPath]) truncateFileAtOffset:0]; #endif if (dumpFileHandle) [dumpFileHandle writeData:blah];