2009-10-14 11 views
73

Sto postando questa domanda perché ho avuto una risposta completa per questo scritto per un altro post, quando ho trovato che non si applicava all'originale ma pensavo fosse troppo utile sprecare. Così ho anche reso questo un wiki della comunità, in modo che altri possano dare una risposta alle domande e alle risposte. Se trovi utile la risposta, per favore vota la questione - essere un wiki della comunità Non dovrei ottenere punti per questo voto ma aiuterà gli altri a trovarloCome posso ottenere un percorso scrivibile su iPhone?

Come posso ottenere un percorso in cui sono consentite le scritture di file l'iPhone? Puoi (in modo fuorviante) scrivere ovunque sul simulatore, ma su iPhone ti è permesso solo di scrivere in posizioni specifiche.

risposta

184

ci sono tre tipi di percorsi scrivibili da considerare - la prima è Documenti, dove memorizzare le cose che si desidera conservare e rendere disponibile per l'utente attraverso iTunes (a partire da 3,2):

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

In secondo luogo, e molto simile alla directory Documenti, c'è la cartella Libreria, dove si archiviano i file di configurazione e i database scrivibili che si desidera mantenere, ma non si vuole che l'utente sia in grado di fare confusione con iTunes:

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

Si noti che anche se l'utente non è possibile visualizzare i file in iTunes utilizzando un dispositivo più vecchio di 3,2 (l'iPad), la costante NSLibraryDirectory è disponibile da iPhoneOS 2.0, e quindi può essere utilizzata per il targeting di build 3.0 (o anche prima se lo si sta ancora facendo). Inoltre, l'utente non sarà in grado di vedere nulla a meno che non si contrassegna un'app che consenta agli utenti di modificare i documenti, quindi se si sta utilizzando Documenti oggi si ha la certezza di cambiare posizione durante l'aggiornamento per il supporto dei documenti dell'utente.

scorso c'è una directory di cache, dove si può mettere le immagini che non si cura esiste per il lungo termine o meno (il telefono potrebbe cancellarli ad un certo punto):

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]; 
} 

Si noti che è devo effettivamente creare la directory Caches lì, quindi quando scrivi devi controllare e creare ogni volta! Una specie di dolore, ma è così.

Poi, quando si dispone di un percorso scrivibile, basta aggiungere un nome di file su di esso in questo modo:

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

o

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

utilizzare quel percorso per la lettura o la scrittura.

Si noti che è possibile creare sottodirectory in uno di questi percorsi scrivibili, che utilizza una delle stringhe di esempio sopra riportate (supponendo che ne sia stata creata una).

Se si sta tentando di scrivere un'immagine nella libreria di foto, non è possibile utilizzare le chiamate del sistema file per farlo - invece, è necessario avere una memoria UII in memoria e utilizzare la chiamata di funzione UIImageWriteToSavedPhotosAlbum() definita da UIKit. Non hai il controllo sul formato di destinazione o sui livelli di compressione e non puoi allegare EXIF ​​in questo modo.

+6

Non costruire il percorso Ti memorizza in cache. Utilizzare la stessa funzione 'NSSearchPathForDirectoriesInDomain()', ma invece di usare 'NSDocumentDirectory', usare' NSCachesDirectory'. –

+0

Risposta modificata per usare 'NSCachesDirectory' –

+0

Grazie, buono a sapersi. –

5

Grazie a Kendall & Dave, sopra, e ho pensato che questo emendamento fosse utile da illustrare.Quando si utilizza per una tantum codice di debug, ho usato this trick da Mike Ash NSBlog per eliminare le variabili temporanee isdir & errore, riducendo al minimo il numero di linee e rendendo la verbosità quasi sopportabile:

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]; 
Problemi correlati