web-dev-qa-db-fra.com

Comment écrire des données dans plist?

J'ai créé save.plist dans un dossier de ressources. J'ai écrit des données directement dans cela (sans utiliser de codage). Je suis capable de lire ces données mais je ne peux pas écrire avec le code dans le même fichier save.plist. En utilisant le code suivant, j'essaie d'écrire les données mais elles sont stockées dans mon plist .app. Le code est ici

NSString *errorDesc = nil;

NSPropertyListFormat format;

NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"save" ofType:@"plist"];

NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];

NSMutableDictionary *temp = (NSMutableDictionary *)[NSPropertyListSerialization
                     propertyListFromData:plistXML
                              mutabilityOption:NSPropertyListMutableContainersAndLeaves
                  format:&format errorDescription:&errorDesc];

if (!temp) {

    NSLog(errorDesc);

    [errorDesc release];        
    }
    //  [temp setValue:@"123" forKey:@"line1"];
    //  [temp writeToFile:plistPath atomically: YES];

    //Reading data from save.plist
    NSLog([temp objectForKey:@"name"]);
    NSLog([temp objectForKey:@"wish"]);
    NSNumber *num=[temp valueForKey:@"roll"];
    int i=[num intValue];
    printf("%d",i);
        //writitng the data in save.plist

    [temp setValue:@"green" forKey:@"color"];
    [temp writeToFile:plistPath atomically: NO];
    NSMutableDictionary *temp1 = (NSMutableDictionary *)[NSPropertyListSerialization
                propertyListFromData:plistXML                                                            
                                mutabilityOption:NSPropertyListMutableContainersAndLeaves
                format:&format errorDescription:&errorDesc];

    NSLog([temp objectForKey:@"color"]);

Je veux que, les données que je veux écrire ne soient écrites que dans save.plist qui est stocké dans des références. Je suis nouveau avec ce concept. Donc, si quelqu'un le sait, aidez-moi s'il vous plaît. Merci d'avance. :-)

16
Jyotsna

Je ne sais pas si je comprends votre question, mais si vous voulez écrire dans une liste .plist dans votre bundle .app, vous faites probablement quelque chose de mal. Si vous souhaitez stocker les préférences, vous devriez envisager d'utiliser NSUserDefaults .
Si vous voulez vraiment modifier une liste .plist, voici du code:

NSString *plistPath = nil;
NSFileManager *manager = [NSFileManager defaultManager];
if (plistPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Contents/Info.plist"]) 
{
    if ([manager isWritableFileAtPath:plistPath]) 
    {
        NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
        [infoDict setObject:[NSNumber numberWithBool:hidden] forKey:@"LSUIElement"];
        [infoDict writeToFile:plistPath atomically:NO];
        [manager changeFileAttributes:[NSDictionary dictionaryWithObject:[NSDate date] forKey:NSFileModificationDate] atPath: [[NSBundle mainBundle] bundlePath]];
    }
}

Mise à jour:
Nate Flink a souligné que certaines des méthodes de NSFileManager utilisées ci-dessus sont obsolètes. Il a posté une réponse avec les méthodes de remplacement ci-dessous: https://stackoverflow.com/ a/12428472/100848

26
Thomas Zoechling

Version mise à jour de l'exemple génial original de Weichsel (merci!). Xcode a lancé plusieurs avertissements dont l’une est une méthode déconseillée sur NSFileManager. Mis à jour ici avec des méthodes non obsolètes d'iOS 5.1

    NSString *plistPath = nil;
NSFileManager *manager = [NSFileManager defaultManager];
if ((plistPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"mySpecial/PathTo.plist"])) 
{
    if ([manager isWritableFileAtPath:plistPath]) 
    {
        NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
        [infoDict setObject:@"foo object" forKey:@"fookey"];
        [infoDict writeToFile:plistPath atomically:NO];
        [manager setAttributes:[NSDictionary dictionaryWithObject:[NSDate date] forKey:NSFileModificationDate] ofItemAtPath:[[NSBundle mainBundle] bundlePath] error:nil];
    }
}
9
Nate Flink

Pour résumer certaines des autres réponses:

Votre problème est que vous essayez d'écrire le fichier dans le dossier qui contient votre application. Ce dossier n'est pas accessible en écriture au moment de l'exécution. Tout ce que vous faites va bien, il vous suffit de choisir un emplacement différent pour écrire votre fichier. 

Vous pouvez utiliser la fonction NSSearchPathForDirectoriesInDomains pour trouver un dossier plus approprié pour ces données. (Comme le dossier @ "Documents".)

4
Jon Hess

Lorsque vous créez l'application, un fichier exécutable "appName.app" est créé et tous les fichiers sont intégrés à l'ensemble. Par conséquent, vous ne pouvez pas accéder au dossier de ressources lorsque l'application est en cours d'exécution, car toutes les données sont dans l'ensemble (pas dans le dossier).

Cependant, vous pouvez accéder à un dossier temporaire contenant des informations sur l'application. Vous pouvez trouver le dossier temporaire ici: Ouvrez le Finder - cliquez sur votre nom d’utilisateur (sous PLACES) - Bibliothèque - Support d’application - iPhone Simulator - Utilisateur - Applications - (vous trouverez ici tous les dossiers temporaires de vos applications iPhone)

Vous pouvez accéder à ce dossier temporaire par:


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

Si vous nommez votre fichier save.plist, vous pouvez y accéder comme ceci:

NSString *filePath = [documentsDirectory stringByAppendingString:@"_save.plist"];

Ensuite, vous venez de sauvegarder votre fichier sur ce chemin de fichiers et il apparaîtra dans le dossier temporaire nommé "Documents_save.plist".

* Notez que le nom du dossier temporaire varie chaque fois que vous exécutez l'application.

Je vous recommande un livre: 《Début du développement sur iPhone - Exploration du kit de développement logiciel (SDK) pour iPhone. Au chapitre 11, vous pouvez trouver ce que vous voulez. 

4
Chilly Zhong

essaye ça:

-(void)add:(NSRunningApplication *) app { 
   if ([self contains:app]) return; 
   [self.apps addObject:app.localizedName]; 
   [self.apps writeToFile:self.dataFile atomically:YES];
}

de "Programmation Cacao".

1
Texada

vous devez copier votre plist dans le répertoire de document ... car vous ne pouvez rien enregistrer sans enregistrer dans le fichier de document .... lorsque vous l'avez copié, vous pourrez écrire/modifier sur plist

0
Syed Sami ul Ahbab