更新和plist中保存数据(Updating and saving data in plist)

2019-06-27 20:08发布

我想提出的是iOS游戏,需要保存的播放器已经达到了最高水平。 我可以成功地改变一个数据元素的plist中,但由于某些原因,这些数据不断每次恢复到其原始值游戏重新开始。 这里是我的代码的基本流程:

在游戏中的init,让玩家达到了最高水平(原值为1)

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

“数据”是获取PlayerData初始化这样一个NSMutableDictionary:

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

之后,如果玩家幸运的最高水平,我递增“最高级别”的值,并通过调用PlayerData此功能写入文件:

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

我知道这一切都是工作,因为我有在玩游戏的玩家可以访问一级菜单。 每当玩家按下水平菜单按钮,一个UITableView的一个子类被创建,显示通过达到最高级别1级。 初始化看起来是这样的:

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

该级菜单显示在游戏的同时水平的正确数量(例如,如果玩家没有击败任何水平,进入到一级菜单,它只是显示为“1级”;但如果玩家幸运1级转到级菜单中,显示“第1级”和“2级”)。 然而,每当应用程序被终止,或在用户退出到游戏主菜单,对“最高级别”的值将恢复为1,这样的代码:

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

始终将currentLevel 1当玩家按下开始,不管用户多少级打边玩。

为什么值变回? 我缺少的东西,这将使我的plist编辑永久的吗?

编辑:

这里是我的新newHighestLevel“的方法:

-(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。 一切似乎都在这两种情况下的游戏改变。

解:

-(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];
}

在初始化

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

Answer 1:

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

例如,从您的资源加载的plist:

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

写plistdict同样简单:

[plistdict writeToFile:filePath atomically:YES];

需要注意的是,你不能写入您的应用程序的资源,所以你必须创建一个不同的路径,例如在你的文档目录为您的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中再次检索数据。

 NSMutableDictionary *plistdict = [NSMutableDictionary dictionaryWithContentsOfFile:docfilePath];

添加您的内容plistDict和再写一遍。



Answer 2:

该方法writeToFile:atomically返回BOOL结果。 我猜的文件不被保存在所有。

为什么你的游戏正常工作的原因是因为应用程序读取数据Dictionary从(这是在启动填充一次),而不是直接plist文件每一次(而且也不应该)。

请检查返回值writeToFile:atomically的方法来确定是否文件实际上是被保存与否。



文章来源: Updating and saving data in plist