2010-09-26 6 views
1

Je suis en train de créer un module complémentaire pour mon application dans lequel l'utilisateur peut rechercher un élément dans une liste pré-remplie avec des données provenant d'un fichier .plist. C'est un NSDictionary. Si le terme, l'utilisateur recherché, n'existe pas, l'utilisateur peut appuyer sur un bouton + et l'ajouter afin qu'il soit là la prochaine fois. Tout d'abord, j'ai pensé que ce serait aussi simple que d'utiliser le NSUserDefaults, mais quelques problèmes se posent.Lecture/écriture dans un fichier plist fourni avec l'application

Pour avoir la liste incluse, je dois la placer dans le paquet, mais si elle est là, je ne peux pas y ajouter de nouvelles paires clé/valeur. Ce que je ne peux faire qu'avec des fichiers situés dans le dossier Documents.

Donc, je suppose que je dois regrouper le plist, puis lors de la première exécution je vais le déplacer dans le dossier des documents et y accéder.

Cela ouvre le problème quand j'ai besoin de mettre à jour l'application, je suppose que écrasera les valeurs que l'utilisateur mis en.

est-il un moyen sécurisé, facile à comprendre, à droite pour obtenir la fonctionnalité que je décris ?

Merci pour toute l'aide fournie :)

Edit: * ** * l'approche réelle, comme le suggère TheSquad et TomH * ** * *

+ (NSMutableDictionary*) genericProducts { 

    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [documentPaths objectAtIndex:0]; 
    NSString *documentPlistPath = [documentsDirectory stringByAppendingPathComponent:@"GenericProducts.plist"]; 

    NSString *bundlePath = [[NSBundle mainBundle] bundlePath]; 
    NSString *bundlePlistPath = [bundlePath stringByAppendingPathComponent:@"GenericProducts.plist"]; 


    if([fileManager fileExistsAtPath:documentPlistPath]){ 

     NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithContentsOfFile:documentPlistPath]; 
     return documentDict; 

    } else { 

     NSError *error; 
     BOOL success = [fileManager copyItemAtPath:bundlePlistPath toPath:documentPlistPath error:&error]; 

    if (success) { 
     NSMutableDictionary *newlySavedDict = [NSMutableDictionary dictionaryWithContentsOfFile:documentPlistPath]; 
     return newlySavedDict; 
    } 

    return nil; 
} 

}

Et pour ajouter un nouveau produit à la liste:

+ (void) addItemToGenericProducts:(NSString*) newProduct { 

    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [documentPaths objectAtIndex:0]; 
    NSString *documentPlistPath = [documentsDirectory stringByAppendingPathComponent:@"GenericProducts.plist"]; 
    NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithContentsOfFile:documentPlistPath]; 
    [documentDict setObject:newProduct forKey:[MD5Checksum cheksum:newProduct]]; 

    [documentDict writeToFile:documentPlistPath atomically:YES]; 

}

Répondre

2

J'ai eu les mêmes pensées avec ma base de données SQLite ...

je finis par faire exactement cela, copiez le groupé déposer dans des documents afin de pouvoir le modifier.

Ce que j'ai fait est de vérifier à chaque démarrage si le fichier existe, si ce n'est pas le cas, copiez-le. Si vous faites une mise à jour de votre application, le dossier des documents ne sera pas tactile, cela signifie que le fichier copié de la version précédente sera toujours présent.

Le seul problème est que si vous voulez que votre plist soit amélioré, vous devrez le gérer dans votre application. Si vous devez le faire, je vous suggère d'utiliser NSUserDefault pour vérifier si une version précédente de l'application existait avant ...

+0

Merci TheSquad :) J'ai rassemblé comme ébauche du code et l'ai mis dans ma réponse.Je travaille très bien. Je suppose que je ne devrais jamais écraser le plist car cela me conduirait à fusionner les choses que l'utilisateur a ajoutées avec les choses que j'ai ajoutées, en synchronisant je suppose. Beaucoup de travail pour un écrin de bord. Peut-être que je vais faire un peu d'horodatage dans le futur. – RickiG

+0

Essayez de mettre à jour votre fichier dans le document le moins que vous pouvez, c'est une vraie peine de le faire, croyez-moi! J'ai eu de mauvaises mises à jour à cause de ça, et bien sûr de mauvaises critiques qui vont avec ... Maintenant je garde une copie exacte de chaque version que j'ai publiée afin de tester la mise à jour d'une version à l'autre, je vous suggère de faire la même chose , ou vous le regretterez :-) – TheSquad

+0

Je serais tellement plus facile si je savais ce que je mettrais dans le plist à l'avenir :) – RickiG

2

Le contenu du répertoire de documents n'est pas modifié lorsqu'une application est mise à jour.

Le contenu du répertoire de documents est supprimé lorsque l'utilisateur supprime l'application. Lorsque l'application est exécutée la première fois, écrivez un indicateur à NSUserDefaults. Lors des prochaines étapes de l'application, vérifiez l'existence du drapeau. (alternativement, vous pouvez juste vérifier l'existence de la plist dans le répertoire de documents)

+0

Merci Tom :) Je suis allé avec votre suggestion sur le test si le fichier est trouvé dans le dossier des documents. C'est une action qui est rarement appelée, seulement dans le cas où un utilisateur va faire quelque chose en dehors de l'utilisation normale. Ainsi, le peu de frais qui provient des tests si le fichier existe est pondéré par la flexibilité. – RickiG

Questions connexes