我究竟做错了什么? NSFileManager很难过

时间:2011-11-03 15:09:08

标签: iphone objective-c nsdata nsfilemanager nscoding

我目前正在构建相当大的iPhone应用程序。无论如何,比我预期的要大。但这不是重点,应用程序的整体思想是从Web服务中获取JSON,将其全部排序为自定义的NSObject,它们链接在一起然后呈现。

这一切都很顺利。但是,因为我希望用户能够在没有互联网连接的情况下在设备上看到此信息,所以我需要将我呈现的信息保存到每个应用程序所具有的Documents文件夹中。

我基本上将NSCoding协议实现到需要它的所有自定义NSObject中,以便将其保存到Documents目录的子目录中。

这一切都是通过此功能实现的。

- (void)applicationDidEnterBackground:(UIApplication *)application
{

     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
     NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"Data"];
     NSString *dataFileString = [dataPath stringByAppendingPathComponent:@"Company.archive"];

     if (![[NSFileManager defaultManager] fileExistsAtPath:dataFileString]) //Does directory already exist?
     {

          MACompany *company = [MACompany sharedMACompany];

          NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
          NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
          NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"Data"];

          NSError *error;
          if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])  //Does directory already exist?
          {
               if (![[NSFileManager defaultManager] createDirectoryAtPath:dataPath
                                       withIntermediateDirectories:NO
                                                        attributes:nil
                                                             error:&error])
               {

            NSLog(@"Create directory error: %@", error);
               }
           }

           NSString *dataFileString = [dataPath stringByAppendingPathComponent:@"Company.archive"];

           NSMutableData *data = [[NSMutableData alloc] init];
           NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];          
           [archiver encodeObject:company forKey:@"MACompany"];
           [archiver finishEncoding];

           [[NSFileManager defaultManager] createFileAtPath:dataFileString
                                            contents:data
                                          attributes:nil];

           [archiver release];
           [data release];

     } else {

      NSLog(@"File already exists, no need to recreate, not yet anyway");

     }

}

当用户首次加载应用程序(application didFinishLaunchingWithOptions:)以及用户在后台(applicationWillEnterForeground:)后打开应用程序时,我会执行以下请求。

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"Data"];
NSString *dataFileString = [dataPath stringByAppendingPathComponent:@"Company.archive"];

if (![[NSFileManager defaultManager] fileExistsAtPath:dataFileString])  //Does directory already exist?
{
    NSLog(@"Create a new Company Request");

    MAWebRequests *companyReq = [[MAWebRequests alloc] init];
    [companyReq getCompanyDetails];
    [companyReq release];

} else {

    NSLog(@"Saved Company Needs to be Decoded applicationWillEnterForeground");

    MACompany *company = [MACompany sharedMACompany];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
    NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"Data"];

    NSString *dataFileString = [dataPath stringByAppendingPathComponent:@"Company.archive"];

    NSData *data = [[NSData alloc] initWithContentsOfFile:dataFileString];
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    [data release];

    company = [unarchiver decodeObjectForKey:@"MACompany"];
    [unarchiver finishDecoding];
    [unarchiver release];        


}

现在这一切都很好,我也可以从这个文件中提取。但是,当我将Xcode的调试器连接到应用程序时,我只能抓取存储在该文件中的数据。一旦停止,数据就会被破坏,并且不包含原始数据。

数据仍然存储在那里,我可以看到创建的文件,但存储在文件中的实际数据本身是错误的......

我是否应该使用上述逻辑将数据保存到文件中,然后拉动重新创建共享对象? 有没有其他人试图做这样的事情并取得了成功? 有什么理由说我为什么遇到这个奇怪的问题? 还有其他人有这个问题吗?

任何帮助将不胜感激,一直在尝试各种不同的方法让它工作,没有任何东西能够到达那里。我需要做的就是能够永久存储数据,直到我需要更新它...

1 个答案:

答案 0 :(得分:0)

我已经通过在applicationDidEnterBackground之前保存MACompany对象解决了这个问题:

非常感谢@OleBegemann帮助找到问题的嵌套位置。