简体   繁体   English

存储和读取文档目录iOS 5中的文件

[英]Storing and reading files from Documents directory iOS 5

In my game, when a level is completed the app stores a "1" in a file in the Documents directory of the app. 在我的游戏中,当一个关卡完成后,应用程序会在应用程序的Documents目录中的文件中存储一个“1”。 When the game then loads, a player can only play a level if the previous level has been completed. 当游戏加载时,如果前一级别已经完成,则玩家只能玩级别。 When I test the game via Xcode and on a device the app works properly and a level cannot be played until the previous level has been completed. 当我通过Xcode和设备测试游戏时,应用程序正常工作,并且在上一级别完成之前无法播放级别。 However, when the app was approved and released on the App Store, the app behaves as if each level has been completed (no locked levels). 但是,当应用程序在App Store上获得批准和发布时,应用程序的行为就像每个级别都已完成(没有锁定级别)。 I can't figure this one out and would appreciate someone's help! 我无法想出这一个,并希望得到别人的帮助! The devices I'm testing on are all iOs 5.0 or higher. 我正在测试的设备都是iOs 5.0或更高版本。

Below is the code that saves the completed level in the Documents directory: 下面是将完成的级别保存在Documents目录中的代码:

 NSMutableData* data = [[NSMutableData alloc] init];
        NSKeyedArchiver* coder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
        NSString *levelString = [NSString stringWithFormat:@"Level%d",level];
        [coder encodeInteger:1 forKey:levelString];
        [coder finishEncoding];
        NSString *levelString2 = [NSString stringWithFormat:@"Level%d.save",level];
        ///
        NSFileManager *filemgr;
        NSString *dataFile;
        NSString *docsDir;
        NSArray *dirPaths;

        filemgr = [NSFileManager defaultManager];

        // Identify the documents directory
        dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        docsDir = [dirPaths objectAtIndex:0];

        // Build the path to the data file
        dataFile = [docsDir stringByAppendingPathComponent:levelString2];

        // Check if the file already exists
        if ([filemgr fileExistsAtPath: dataFile])
        {
            [[NSFileManager defaultManager] removeItemAtPath:dataFile error:nil];
        }
        [data writeToFile:dataFile atomically:YES];
        [coder release];
        [data release];
    }
    @catch (NSException* ex) 
    {
        CCLOG(@"level save failed: %@", ex);
    }

Below is the code that reads the Document directory to see if the level has been completed: 下面是读取Document目录以查看级别是否已完成的代码:

if ([self loadCompletedLevels:6] == 1) { //// level gets unlocked **** }

-(int) loadCompletedLevels:(int)theLevel; {

int isLevelCompleted;  //1 = completed

NSString* kSaveFile = [NSString stringWithFormat:@"Level%d.save",theLevel];
NSString *levelString = [NSString stringWithFormat:@"Level%d",theLevel];

@try
{

    NSFileManager *filemgr;
    NSString *dataFile;
    NSString *docsDir;
    NSArray *dirPaths;

    filemgr = [NSFileManager defaultManager];

    // Identify the documents directory
    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    docsDir = [dirPaths objectAtIndex:0];

    // Build the path to the data file
    dataFile = [docsDir stringByAppendingPathComponent:kSaveFile];


    if ([[NSFileManager defaultManager] fileExistsAtPath:dataFile])
    {
        NSData* data = [[NSData alloc] initWithContentsOfFile:dataFile];

        if (data && [data length] > 0)
        {
            NSKeyedUnarchiver* decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
            isLevelCompleted = [decoder decodeIntForKey:levelString];

            [decoder release];
        }

        [data release];
    }
    if (isLevelCompleted == 1) {
        levelCompleted = YES;

    }
}
@catch (NSException* ex) 
{

    levelCompleted = NO;
}
return isLevelCompleted; }

You should probably use a different approach for storing your data, but the real problem is that you are not initializing the return value, isLevelCompleted. 您应该使用不同的方法来存储数据,但真正的问题是您没有初始化返回值isLevelCompleted。 It is on the stack, and does not have a default value. 它位于堆栈上,没有默认值。 It starts out with whatever happens to be at that stack location. 它开始于堆栈位置发生的任何事情。

So, if you don't set it, it will have an arbitrary value. 因此,如果您不设置它,它将具有任意值。

Also, you should probably use BOOL for a boolean value, but if you make this: 此外,您应该使用BOOL作为布尔值,但如果您这样做:

int isLevelCompleted = 0;  //1 = completed

you will initialize it to "false" so it must be explicitly changed to "true" by your code. 您将它初始化为“false”,因此必须通过代码将其显式更改为“true”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM