2011-11-03 62 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爲他的幫助找到問題嵌套的地方。