2011-11-03 66 views
1

我目前正在建设一个相当大的iPhone应用程序。反正比我预想的要大。但这没有关系,应用程序的总体思路是从Web服务中获取JSON,将它们全部分类为自定义的NSObject,它们被链接在一起然后呈现。我在做什么错? NSFileManager的灾难

这一切都很好。但是,因为我希望用户能够在没有Internet连接的情况下在设备上看到此信息,所以我需要将我呈现的信息保存到每个应用程序所拥有的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的调试器连接到应用程序时,我只能获取存储在此文件中的数据。一旦停止,数据将被破坏并且不包含原始数据。

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

我现在不使用上述逻辑来保存数据到文件,然后重新创建共享对象? 有没有人试图做这样的事情,并取得成功? 有什么理由为什么我会遇到这个奇怪的问题? 有没有其他人有这个问题?

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

+2

'[MAWebRequests alloc];'听起来很糟糕。你忘了'init'吗?另外,如果您需要在启动之间持续保存大量数据,则应考虑使用CoreData或SQLite ... – Yuji

+0

我确实忘记了init,谢谢!清理了这一点,但仍然无法解决我的问题...已经跟踪了我所节省的数据大小,3kb,根本不大! :) –

+0

好的,请相应地更新您的文章。无论如何,你已经粘贴在这里的代码看起来不错。你需要发布编码和解码事物的代码。您还应该在Xcode中运行“分析”(在“生成”菜单下可用)并更正您的代码以删除所有警告。 – Yuji

回答

0

我已经保存MACompany applicationDidEnterBackground之前反对很好地解决这个问题:

主要得益于到@OleBegemann为他的帮助找到问题嵌套的地方。