2012-10-26 92 views
2

經過搜索後,我發現了大量關於我想要做的事情的小部件,但沒有任何工作都在一起。從plist中讀取然後將對象保存到不同的plist iOS

低音我有一個靜態的plist文件。我不想改變它的內容。 plist文件是從plist中讀取並存儲在NSArray中的數組字典,數據顯示在表中。這是完整的工作和簡單的部分!

我現在想要做的是有一個plist,它將從靜態plist數組讀取的對象的用戶收藏存儲到收藏夾的NSMutableArray中。這個數組需要被讀入用戶選擇收藏夾部分時隨時查看的收藏夾表

這個概念真的很簡單,用戶將按下「添加到收藏夾按鈕」,字典對象將被添加到收藏夾數組,但我的問題是正確檢查收藏夾plist是否存在。如果有,請將該數據讀入收藏夾陣列。如果is不存在,則創建空plist,它仍會讀入收藏夾數組,但它將爲空。

我不確定從哪裏開始這個特定的情況,有什麼想法?非常感謝!

回答

0

剛剛碰到這個自己,同時嘗試第一次做同樣的事情。主要問題是你不能寫信給不存在的plist。所以你需要在你的軟件包中創建一個,並將其複製到你需要的位置,「如果它不存在」。這是一個例子。這比「最小」多一點,但我認爲它解釋了這些問題。其結果是通過將某些內容存儲在文檔目錄中某處的「data.plist」中,從一次運行轉移到另一次運行。

ViewController.m(例如):

#import "ViewController.h" 

@interface ViewController() 

@end 

@implementation ViewController 

//////////////////////////// 
// BIG NOTE: 
// In order for ANY of this to work, you need to make a data.plist in your supporting files, in your project, 
// before compiling and running 
// The plist should, at very least, have a single row with key "key1" and value "value1" 
//////////////////////////// 

// returns path where plist file is 
// "internal" means whether we want from one baked into the app (which is read-only, by the way), or one in our documents dir 
-(NSString *)localPathForPlist:(NSString *)name internal:(bool)internal 
{ 
    if(internal) return [[NSBundle mainBundle] pathForResource:name ofType:@"plist"]; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    return [documentsDirectory 
       // this just adds name and ".plist" to make a filename something like "data.plist" 
       stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%@", name, @".plist"] 
      ]; 
} 

// write value to key, either in internal plist or not 
-(void) writeToPlist:(NSString *)key setValue:(NSString *)value internal:(bool)internal 
{ 
    NSString* path = [ self localPathForPlist:@"data" internal:internal ]; 
    NSMutableDictionary *plistData = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; 
    [plistData setObject:value forKey:key]; 
    [plistData writeToFile:path atomically:YES]; 
} 

// read value from key, either in internal plist or not 
-(NSString *) readFromPlist:(NSString *)key internal:(bool)internal 
{ 
    NSString* path = [ self localPathForPlist:@"data" internal:internal ]; 
    NSMutableDictionary *plistData = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; 
    return (NSString *)[plistData valueForKey:key]; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // here we go through all the different cases, trying to edit things internally and in externally, 
    // and copying the internal one to the external location, towards the end, if it's not already there 

    NSString *localPath = [self localPathForPlist:@"data" internal:FALSE]; 
    NSString *internalPath = [self localPathForPlist:@"data" internal:TRUE]; 

    NSLog(@"local path=%@", localPath); 

    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    BOOL localPlistExists = [fileManager fileExistsAtPath:localPath]; 

    // the first time you run this, it'll do one, then the other for all other runs: 
    if(localPlistExists) NSLog(@"local plist exists"); 
    else     NSLog(@"local plist does NOT exist"); 

    NSLog(@"key1's value from internal=%@", [self readFromPlist:@"key1" internal:TRUE ]); 
    NSLog(@"key1's value from external=%@", [self readFromPlist:@"key1" internal:FALSE]); 

    NSLog(@"setting internal key1 to new-value1"); 
    [self writeToPlist:@"key1" setValue:@"new-value1" internal:TRUE ]; 

    NSLog(@"setting external key1 to new-value1"); 
    [self writeToPlist:@"key1" setValue:@"new-value1" internal:FALSE]; 

    NSLog(@"key1's value from internal=%@", [self readFromPlist:@"key1" internal:TRUE ]); 
    NSLog(@"key1's value from external=%@", [self readFromPlist:@"key1" internal:FALSE]); 

    // the first time you run this, it'll do one, then the other for all other runs: 
    if(localPlistExists) NSLog(@"since local plist exists, leaving alone"); 
    else 
    { 
     NSLog(@"since local plist does NOT exist, cloning from internal copy"); 
     [fileManager copyItemAtPath:internalPath toPath:localPath error:nil]; 
    } 

    NSLog(@"key1's value from internal=%@", [self readFromPlist:@"key1" internal:TRUE ]); 
    NSLog(@"key1's value from external=%@", [self readFromPlist:@"key1" internal:FALSE]); 

    NSLog(@"setting internal key1 to new-value1"); 
    [self writeToPlist:@"key1" setValue:@"new-value1" internal:TRUE ]; 

    NSLog(@"setting external key1 to new-value1"); 
    [self writeToPlist:@"key1" setValue:@"new-value1" internal:FALSE]; 

    NSLog(@"key1's value from internal=%@", [self readFromPlist:@"key1" internal:TRUE ]); 
    NSLog(@"key1's value from external=%@", [self readFromPlist:@"key1" internal:FALSE]); 

    // notice that from one run to another, changes to the internal one don't "carry over", because it's read-only 
    // but ones in the external one do 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

@end 

實施例的屏幕截圖的第一次運行它:First Execution

實施例的屏幕截圖爲連續運行:Later Executions