在plist中更新和保存数据 [英] Updating and saving data in plist

查看:80
本文介绍了在plist中更新和保存数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作iOS游戏,需要保存玩家所达到的最高等级。我可以成功更改plist中的数据元素,但由于某种原因,每次游戏重新启动时,该数据都会恢复为原始值。以下是我的代码的基本流程:

I am making an iOS game and need to save the highest level the player has reached. I can successfully change a data element in a plist, but for some reason, that data keeps reverting to its original value every time the game restarts. Here is the basic flow of my code:

在游戏的初始化中,获得玩家达到的最高等级(原始值为1)

In the game's init, get the highest level the player has reached (the original value is 1)

pData = [[PlayerData alloc] init];
currentLevel = [[pData.data valueForKey:@"Highest Level"] intValue];
[self startNewLevel:currentLevel];

'data'是一个NSMutableDictionary,它在PlayerData中被初始化为:

'data' is an NSMutableDictionary that gets initialized like this in PlayerData:

self.data = [NSMutableDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"playerdata" ofType:@"plist"]];

稍后,如果玩家击败最高级别,我会增加最高级别值并写入通过在PlayerData中调用此函数来调用该文件:

later, if the player beats the highest level, I increment the 'highest level' value and write to the file by calling this function in PlayerData:

-(void) newHighestLevel:(NSString*)path :(int)level{
     [self.data setValue:[NSNumber numberWithInt:level] forKey:path];
     [self.data writeToFile:@"playerdata.plist" atomically:YES]

I知道这一切都有效,因为我有一个玩家可以在玩游戏时访问的关卡菜单。每次玩家按下关卡菜单按钮时,都会创建一个UITableView的子类,显示级别1到达最高级别。初始化如下所示:

I know all this is working because I have a level menu that the player can access while playing the game. Each time the player presses the level menu button, a subclass of a UITableView gets created that displays level 1 through the highest level reached. The initialization looks like this:

levelMenu = [[LevelMenu alloc] init:[[pData.data valueForKey:@"Highest Level"] intValue]];

级别菜单显示游戏中正确的等级数(例如,如果玩家没有击败任何级别并进入级别菜单,它只显示级别1;但如果玩家击败级别1并进入级别菜单,则显示级别1和级别2)。但是,每当应用程序被终止或用户退出游戏主菜单时,最高级别的值将恢复为1并且此代码:

The level menu displays the correct number of levels while in the game (e.g. if the player hasn't beat any levels and goes to the level menu, it just displays "level 1"; but if the player beats level 1 and goes to the level menu, it displays "level 1" and "level 2"). However, whenever the app gets terminated or the user quits to the games main menu, the value for 'highest level' reverts back to 1 and this code:

currentLevel = [[pData.data valueForKey:@"Highest Level"] intValue];

无论玩家在玩多少级别时,总是将currentLevel设置为1 。

always sets currentLevel to 1 when the player pushes start, no matter how many levels the user beat while playing.

为什么价值会改变?我错过了一些会使我的plist编辑成为永久性的东西吗?

Why is the value changing back? Am I missing something that would make my plist edits permanent?

编辑:

这是我的新'newHighestLevel '方法:

here is my new 'newHighestLevel' method:

-(void) newHighestLevel:(NSString*)path :(int)level{
    [self.data setValue:[NSNumber numberWithInt:level] forKey:path];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    NSString *docfilePath = [basePath stringByAppendingPathComponent:@"playerdata.plist"];
    [self.data writeToFile:docfilePath atomically:YES];
    self.data = [NSMutableDictionary dictionaryWithContentsOfFile:docfilePath];
    BOOL write = [self.data writeToFile:docfilePath atomically:YES];
}

写入设置为YES。如果我将'docfilePath'更改为@playerdata.plist,则将其设置为NO。在任何一种情况下,游戏似乎都没有改变。

write gets set to YES. If I change 'docfilePath' to @"playerdata.plist", it gets set to NO. Nothing seems to change with the game in either case.

解决方案:

-(void) newHighestLevel:(NSString*)path :(int)level{
      [self.data setValue:[NSNumber numberWithInt:level] forKey:path];
      NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
      NSString *docfilePath = [basePath stringByAppendingPathComponent:@"playerdata.plist"];
      [self.data writeToFile:docfilePath atomically:YES];
}

和init

-(id) init{

     NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
     NSString *docfilePath = [basePath stringByAppendingPathComponent:@"playerdata.plist"];
     NSFileManager *fileManager = [NSFileManager defaultManager];
     if (![fileManager fileExistsAtPath:docfilePath]){
         NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"playerdata" ofType:@"plist"];
         [fileManager copyItemAtPath:sourcePath toPath:docfilePath error:nil];
     }
     self.data = [NSMutableDictionary dictionaryWithContentsOfFile:docfilePath];
     return self;
}


推荐答案

创建一个最简单的方法plist中的字典是使用方法 dictionaryWithContentsOfFile:

The easiest way to create a dictionary from a plist is to use the method dictionaryWithContentsOfFile:,

例如,从资源加载plist:

For example, to load a plist from your resources:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"playerData" ofType:@"plist"];
NSMutableDictionary *plistdict = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];

写一个plistdict同样简单:

Writing a plistdict is equally simple:

[plistdict writeToFile:filePath atomically:YES];

注意您无法写入应用的资源,所以你我们必须创造一条不同的道路,例如在plist的Documents目录中。

Note that you can't write into your app's resources, so you'll have to create a different path, e.g. in your Documents directory for your plist.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *docfilePath = [basePath stringByAppendingPathComponent:@"playerData.plist"];
[plistdict writeToFile:docfilePath atomically:YES];

现在再次从plist中检索数据。

Now retrieve data from plist again.

 NSMutableDictionary *plistdict = [NSMutableDictionary dictionaryWithContentsOfFile:docfilePath];

在plistDict中添加您的内容并再次写入。

Add your content in plistDict and write it again.

这篇关于在plist中更新和保存数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆