2011-08-14 10 views
48

Conserverò alcune stringhe (forse 10-20). Non sono sicuro se dovrei usare NSUserDefaults per salvarli o scriverli in un plist. Qual è considerata la migliore pratica? NSUserDefaults sembra che sia meno linee di codice, quindi più veloce da implementare.Devo usare NSUserDefaults o un plist per memorizzare i dati?

Vorrei aggiungere che questi valori di stringa verranno aggiunti/rimossi dall'utente.

risposta

82

Sto presupponendo un array, ma funzionerà anche con i dizionari.

Userdefaults, Core Data e Plists possono essere tutti letti/scritti, ma se si utilizza un plist è necessario prestare attenzione in quale direzione lo si inserisce. Vedi la parte plist in basso.

Dati di base Penso che sia troppo eccessivo, è solo archi. Dovrebbe essere usato quando si desidera mantenere oggetti più complessi.

NSUserDefaults:

E 'abbastanza veloce e facile da fare, anche se si suppone di memorizzare solo le impostazioni utente. A loro scrivere ai userdefaults:

NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil]; 
[[NSUserDefaults standardUserDefaults] setObject:stringsArray forKey:@"MyStrings"]; 
[[NSUserDefaults standardUserDefaults] synchronize]; 

Per leggere l'dalle userdefaults:

NSArray *stringsArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"MyStrings"]; 

Plist:

Se le stringhe stanno per essere modificate è necessario scrivere e leggi un plist ma non puoi scrivere nelle risorse della tua app.

  1. Per avere un plist di lettura/scrittura in primo luogo trovare la directory di documenti

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"]; 
    
  2. creare l'array (Io parto dal presupposto le stringhe sono string1, ...)

    NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil]; 
    
  3. Scrivilo in archivio

    [stringsArray writeToFile:stringsPlistPath atomically:YES]; 
    

Per leggere il plist:

  1. trovare la directory documenti

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"]; 
    
  2. leggerlo in:

    NSArray *stringsArray = [NSArray arrayWithContentsOfFile:stringsPlistPath]; 
    
+1

Ho implementato la soluzione PList per un elenco di URL utilizzati di recente. Sembra che PList sia l'approccio corretto per il mio problema. Ma devo dire che dopo aver fatto lo stesso su Android, questo è stato sorprendentemente molto più coinvolto per quanto riguarda una curva di apprendimento e lo sforzo complessivo. Quindi devo commentare e dire grazie mille per il codice di esempio sopra ... – user574771

+2

Domanda ... quando dici "non puoi scrivere nelle risorse delle tue app" intendi che non possiamo scrivere su un plist che creiamo e popoliamo da dentro xcode? – crazyCoder

+1

Puoi solo scrivere nella directory Documenti della tua app. Quindi è possibile copiare quel plist dalla directory Resources alla directory Documents in fase di esecuzione e quindi modificarlo. – doppioslash

1

Il metodo consigliato per mantenere i dati in questo modo è l'utilizzo dei dati principali. Mentre NSUserDefaults può essere usato per memorizzare più o meno qualsiasi cosa, si suppone che debba essere usato per memorizzare le preferenze.

+1

Perché sarebbe Core Data essere preferibile un plist per una manciata di corde? – jlehr

+0

Perché allora il quadro si prenderà cura di tutti i dettagli come la gestione dei file, la sincronizzazione e la gestione degli errori. –

+0

@MarcusKarlsson NSUserDefaults fornirà anche questa gestione per l'OP. Il piccolo numero di stringhe degli elenchi OP mi sembra più equivalente alle preferenze degli utenti, anche se più informazioni sarebbero utili per guidare qui. –

2

Dipende da cosa si desidera memorizzare e perché. NSUserDefaults è pensato per memorizzare le preferenze dell'utente. Puoi provare a usarlo per altre cose, ma probabilmente non dovresti.

In caso contrario, se le vostre esigenze sono semplici, un file plist è piuttosto semplice. Puoi anche utilizzare i dati di base o creare il tuo formato di file. In generale, io uso plist per compiti semplici e poi passare ai dati di base per qualcosa di più complesso.

7

Se si memorizzano le stringhe 10-20 e si cercano non troppe righe di codice, i dati di base sono certamente troppo sovraccarichi. Raccomando di andare con il plist. Non molto codice:

NSURL *plistURL = [[NSBundle mainBundle] URLForResource:@"MyStrings" withExtension:@"plist"]; 
NSArray *stringArray = [NSArray arrayWithContentsOfURL:plistURL]; 
4

NSUserDefaults memorizzerà le preferenze dell'utente in un file nella cartella Libreria/Preferenze. In teoria serve solo a memorizzare alcune proprietà dell'applicazione/utente.

I file di plist sono utili per gestire un singolo file. Se hai bisogno di gestire di più dovresti usare il Coredata. Non ci sono restrizioni sulla dimensione del file plist. Altrimenti bisogna stare attenti con il file plist perché quando è necessario salvarlo o leggerlo l'intero contenuto del file verrà caricato in memoria.

2

Utilizzando un plist è una buona scelta per memorizzare le stringhe se le stringhe sono non solo le impostazioni dell'utente che possono andare in NSUserDefaults. Come accennato, quando si utilizza un plist è necessario memorizzare il plist nella directory Documenti per poter scrivere su di esso, perché non è possibile scrivere nelle risorse della propria app. Quando ho appreso per la prima volta, non ero chiaro su dove fosse la directory Bundle della tua app e dove fosse la directory Documents, quindi ho pensato di pubblicare qui un codice di esempio che prima copia un plist chiamato "Strings.plist" (che hai già nella directory Bundle della tua app) nella directory Documenti, quindi ti scrive e legge da essa.

// Make a path to the plist in the Documents directory 
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *stringsPlistPathIndDoc = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"]; 

// Make a path to the plist in your app's Bundle directory 
NSString *stringsPlistPathInBundle = [[NSBundle mainBundle] pathForResource:@"Strings" ofType:@".plist"]; 

NSFileManager *fileManager = [NSFileManager defaultManager]; 

// Check first that you haven't already copied this plist to the Documents directory 
if (![fileManager fileExistsAtPath:stringsPlistPathIndDoc]) 
{ 
    NSError *error; 

    // Copy the plist from the Bundle directory to the Documents directory 
    [fileManager copyItemAtPath:stringsPlistPathInBundle toPath:stringsPlistPathIndDoc error:&error]; 
} 

// Write your array out to the plist in the Documents directory 
NSMutableArray *stringsArray = [[NSMutableArray alloc] initWithObjects:@"string1", @"string2", @"string3", nil]; 
[stringsArray writeToFile:stringsPlistPathIndDoc atomically:YES]; 

// Later if you want to read it: 
stringsArray = [[NSMutableArray alloc] initWithContentsOfFile:stringsPlistPathIndDoc]; 
7

iOS memorizza in ultima analisi, tutti i dati NSUserDefaults in un file plist. Quindi non influenzerà le prestazioni se questa è la tua preoccupazione. Personalmente preferisco usare NSUserDefaults per piccoli dati e plistare per un set di dati relativamente grande.

Nota: Non memorizzare mai alcuna informazione sensibile in NSUserDefaults come chiunque può vedere quei dati.

1

Utilizzando .plist

  1. Creare un plist utilizzando Xcode

Scrivi un valore di plist

NSURL *plistURL = [[NSBundle mainBundle] URLForResource:@"settings" withExtension:@"plist"]; 

NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfURL:plistURL]; 
[dict setValue:@"value" forKey:@"key"]; 
[dict writeToURL:plistURL atomically:YES]; 

leggere un valore da plist

NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfURL:plistURL]; 
NSString *myValue = [dict valueForKey:@"key"]; 
2

NSUSerDefaults è davvero veloce da implementare, ma soprattutto con l'aumentare della domanda, si desidera memorizzare sempre di più, sono andato direttamente per i file plist.

Per lo più, le persone vogliono archiviare un elenco di qualcosa, quindi ecco la mia condivisione su come farlo con NSDictionary.Questo non richiede di creare un file plist prima, verrà creata la prima volta risparmiando qualcosa

Xcode 7 beta, Swift 2,0

risparmio

func SaveItemFavorites(items : Array<ItemFavorite>) -> Bool 
{ 
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray 
    let docuDir = paths.firstObject as! String 
    let path = docuDir.stringByAppendingPathComponent(ItemFavoritesFilePath) 
    let filemanager = NSFileManager.defaultManager() 

    let array = NSMutableArray()   

    for var i = 0 ; i < items.count ; i++ 
    { 
     let dict = NSMutableDictionary() 
     let ItemCode = items[i].ItemCode as NSString 

     dict.setObject(ItemCode, forKey: "ItemCode") 
     //add any aditional.. 
     array[i] = dict 
    } 

    let favoritesDictionary = NSDictionary(object: array, forKey: "favorites") 
    //check if file exists 
    if(!filemanager.fileExistsAtPath(path)) 
    { 
     let created = filemanager.createFileAtPath(path, contents: nil, attributes: nil) 
     if(created) 
     { 
      let succeeded = favoritesDictionary.writeToFile(path, atomically: true) 
      return succeeded 
     } 
     return false 
    } 
    else 
    { 
     let succeeded = notificationDictionary.writeToFile(path, atomically: true) 
     return succeeded 
    } 
} 

piccola nota dai documenti:

NSDictionary.writeToFile (percorso: atomicamente :)

Questo metodo convalida in modo ricorsivo che tutti gli oggetti contenuti sono oggetti elenco delle proprietà (istanze di NSData, NSDate, NSNumber, NSString, NSArray, o NSDictionary) prima di scrivere fuori il file, e non ha prodotto alcun se tutti gli oggetti non sono di proprietà elenca gli oggetti, poiché il file risultante non sarebbe un elenco di proprietà valido.

Quindi qualsiasi cosa si imposta su dict.SetObject() dovrebbe essere uno dei tipi sopra menzionati.

carico

private let ItemFavoritesFilePath = "ItemFavorites.plist" 

func LoadItemFavorites() -> Array<ItemFavorite> 
{ 
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray 
    let docuDir = paths.firstObject as! String 
    let path = docuDir.stringByAppendingPathComponent(ItemFavoritesFilePath) 
    let dict = NSDictionary(contentsOfFile: path) 
    let dictitems : AnyObject? = dict?.objectForKey("favorites") 

    var favoriteItemsList = Array<ItemFavorite>() 

    if let arrayitems = dictitems as? NSArray 
    { 
     for var i = 0;i<arrayitems.count;i++ 
     { 
      if let itemDict = arrayitems[i] as? NSDictionary 
      { 
       let ItemCode = itemDict.objectForKey("ItemCode") as? String 
       //get any additional 

       let ItemFavorite = ItemFavorite(item: ItemCode) 
       favoriteItemsList.append(ItemFavorite) 
      } 
     } 
    } 

    return favoriteItemsList 
}