2009-10-14 10 views
73

Estoy publicando esta pregunta porque tuve una respuesta completa para esta publicación escrita para otra publicación, cuando descubrí que no se aplicaba al original, pero pensé que era demasiado útil como para desperdiciarla. Por lo tanto, también he convertido esta wiki en una comunidad, para que otros puedan formular preguntas y respuestas. Si encuentra la respuesta útil, vote la pregunta: ser un wiki de la comunidad No debería obtener puntos para esta votación, pero ayudará a otros a encontrarlo¿Cómo puedo obtener una ruta de escritura en el iPhone?

¿Cómo puedo obtener una ruta en la que se permiten escrituras de archivos? ¿el iphone? Usted puede (engañosamente) escribir en cualquier lugar que desee en el simulador, pero en el iPhone solo puede escribir en ubicaciones específicas.

Respuesta

184

Hay tres tipos de caminos de escritura a tener en cuenta - el primero es Documentos, donde se almacenan las cosas que desea conservar y poner a disposición del usuario a través de iTunes (a partir de 3,2):

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

En segundo lugar, y muy similar al directorio de Documentos, existe la carpeta Biblioteca, donde almacena archivos de configuración y bases de datos grabables que también desea conservar, pero no desea que el usuario pueda meterse con iTunes:

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

Tenga en cuenta que, aunque el usuario no puede ver archivos en iTunes usando un dispositivo anterior a 3.2 (el iPad), la constante NSLibraryDirectory ha estado disponible desde iPhoneOS 2.0 y, por lo tanto, se puede usar para compilaciones que tengan como objetivo 3.0 (o incluso antes si aún lo hace). Además, el usuario no podrá ver nada a menos que marque una aplicación como permitir que los usuarios modifiquen documentos, por lo que si está utilizando documentos hoy está bien siempre y cuando cambie de ubicación al actualizar para soporte de documentos de usuario.

Última existe un directorio de caché, donde se puede poner imágenes que no se preocupan existe para el largo plazo o no (el teléfono puede eliminarlos en algún momento):

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

Tenga en cuenta que tiene que crear realmente el directorio Caches allí, así que cuando escriba debe verificar y crear cada vez! Es un poco doloroso, pero así es como es.

Entonces, cuando usted tiene un camino de escritura, que acaba de agregar un nombre de archivo en él de este modo:

NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"SomeDirectory/SomeFile.txt"]; 

o

NSString *filePath = [cachePath stringByAppendingPathComponent:@"SomeTmpFile.png"]; 

Use ese camino para lectura o escritura.

Tenga en cuenta que puede crear subdirectorios en cualquiera de esas rutas de escritura, que una de las cadenas de ejemplos anteriores está utilizando (suponiendo que se haya creado una).

Si está intentando escribir una imagen en la biblioteca de fotos, no puede usar las llamadas al sistema de archivos para hacer esto; en su lugar, debe tener un UIImage en memoria y usar la llamada de función UIImageWriteToSavedPhotosAlbum() definida por UIKit. No tiene control sobre el formato de destino o los niveles de compresión, y no puede adjuntar ningún EXIF ​​de esta manera.

+6

No construir el camino hacia Caches usted mismo. Use la misma función 'NSSearchPathForDirectoriesInDomain()', pero en lugar de usar 'NSDocumentDirectory', use' NSCachesDirectory'. –

+0

Respuesta editada para usar 'NSCachesDirectory' –

+0

Gracias, es bueno saberlo. –

5

Gracias a Kendall & Dave, arriba, y pensé que esta enmienda era útil para que aparezca.Cuando se utiliza para depurar el código de una sola vez, utilicé this trick de Mike Ash NSBlog para eliminar las variables temporales isdir & de error, reduciendo al mínimo el número de líneas y hacer que el nivel de detalle casi soportable:

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

if (dumpFileHandle) [dumpFileHandle writeData:blah]; 
Cuestiones relacionadas