web-dev-qa-db-fra.com

Dois-je utiliser NSUserDefaults ou un plist pour stocker des données?

Je vais stocker quelques chaînes (peut-être 10-20). Je ne sais pas si je dois utiliser NSUserDefaults pour les enregistrer ou les écrire dans une liste. Qu'est-ce qui est considéré comme la meilleure pratique? NSUserDefaults semble être moins de lignes de code, donc plus rapide à implémenter.

Je voudrais ajouter que ces valeurs de chaîne seront ajoutées/supprimées par l'utilisateur.

50
Sheehan Alam

Je suppose un tableau, mais cela fonctionnera également avec les dictionnaires.

Les défauts utilisateur, les données de base et les listes peuvent tous être lus/écrits, mais si vous utilisez une liste, vous devez faire attention dans quel dir vous l'avez mis. Voir la partie plist ci-dessous.

Core Data Je pense que c'est beaucoup trop exagéré, c'est juste des chaînes. Il est censé être utilisé lorsque vous souhaitez conserver des objets plus complexes.

NSUserDefaults:

C'est assez rapide et facile à faire, bien qu'il soit censé stocker uniquement les paramètres utilisateur. Pour les écrire dans les userdefaults:

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

Pour lire le dans les userdefaults:

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

Plist:

Si vos chaînes vont être modifiées, vous devrez écrire et lire une liste mais vous ne pouvez pas écrire dans les ressources de votre application.

  1. Pour avoir une liste de lecture/écriture, trouvez d'abord le répertoire des documents

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];
    
  2. Créez le tableau (je suppose que les chaînes sont string1, ...)

    NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil];
    
  3. Écrivez-le dans un fichier

    [stringsArray writeToFile:stringsPlistPath atomically:YES];
    

Pour lire le plist:

  1. Trouver le répertoire des documents

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

    NSArray *stringsArray = [NSArray arrayWithContentsOfFile:stringsPlistPath];
    
83
doppioslash

Si vous stockez 10 à 20 chaînes et que vous ne recherchez pas trop de lignes de code, les données de base sont certainement beaucoup trop lourdes. Je recommande d'aller avec le plist. Pas beaucoup de code:

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

iOS stocke finalement toutes les données NSUserDefaults dans un fichier plist. Cela n'affectera donc pas les performances si tel est votre souci. Personnellement, je préfère utiliser NSUserDefaults pour les petites données et plist pour un ensemble de données relativement important.

Remarque: Ne stockez jamais d'informations sensibles dans NSUserDefaults car tout le monde peut voir ces données.

8
atulkhatri

NSUserDefaults stockera les préférences de l'utilisateur dans un fichier dans le dossier Library/Preferences. En théorie, il ne sert qu'à stocker certaines propriétés d'application/utilisateur.

Les fichiers Plist sont utiles pour gérer un seul fichier. Si vous avez besoin de gérer davantage, vous devez utiliser les Coredata. Il n'y a aucune restriction quant à la taille du fichier plist. Sinon, vous devez être prudent avec le fichier plist car lorsque vous devez l'enregistrer ou le lire, tout le contenu du fichier sera chargé en mémoire.

5
Yannick Loriot

Cela dépend de ce que vous voulez stocker et pourquoi. NSUserDefaults est destiné au stockage des préférences utilisateur. Vous pouvez essayer de l'utiliser pour d'autres choses, mais vous ne devriez probablement pas.

Sinon, si vos besoins sont simples, un fichier plist est assez simple. Vous pouvez également utiliser les données de base ou créer votre propre format de fichier. En général, j'utilise plist pour des tâches simples, puis je passe aux données de base pour tout ce qui est plus complexe.

2
Tim Dean

en utilisant .plist

  1. Créer une liste à l'aide de Xcode

Écrivez une valeur à plist

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

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

Lire une valeur de plist

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

NSUSerDefaults est en effet rapide à implémenter, mais surtout au fur et à mesure que votre application se développe, vous souhaitez en stocker de plus en plus, je suis allé directement pour les fichiers plist.

La plupart du temps, les gens veulent stocker une liste de quelque chose, alors voici ma part sur la façon de le faire avec NSDictionary. Cela ne vous oblige pas à créer un fichier plist d'abord, il sera créé lors de la première sauvegarde de quelque chose

xcode 7 beta, Swift 2.0

sauvegarde

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

Petite note des docs:

NSDictionary.writeToFile (chemin: atomiquement:)

Cette méthode valide récursivement que tous les objets contenus sont des objets de liste de propriétés (instances de NSData, NSDate, NSNumber, NSString, NSArray , ou NSDictionary) avant d'écrire le fichier et renvoie NO si tous les objets ne sont pas des objets de liste de propriétés, car le fichier résultant ne serait pas une liste de propriétés valide.

Donc, tout ce que vous définissez sur dict.SetObject() devrait être l'un des types mentionnés ci-dessus.

chargement

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
}
2
CularBytes

L'utilisation d'un plist est un bon choix pour stocker vos chaînes si les chaînes ne sont pas uniquement des paramètres utilisateur pouvant aller dans NSUserDefaults. Comme cela a été mentionné, lorsque vous utilisez un plist, vous devez stocker votre plist dans le répertoire Documents pour y écrire, car vous ne pouvez pas écrire dans les ressources de votre propre application. Quand j'ai appris cela pour la première fois, je ne savais pas exactement où se trouvait le répertoire Bundle de votre propre application par rapport à l'emplacement du répertoire Documents, alors j'ai pensé publier un exemple de code ici qui copie d'abord un plist appelé "Strings.plist" (qui que vous avez déjà dans le répertoire Bundle de votre propre application) dans le répertoire Documents, puis y écrit et lit à partir de celui-ci.

// 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];
2
iCMS

La méthode recommandée pour conserver des données comme celle-ci est d'utiliser les données de base. Alors que NSUserDefaults peut être utilisé pour stocker plus ou moins tout ce qu'il est censé être utilisé pour stocker les préférences.

1
user858224