2012-10-26 4 views
2

주위를 검색 한 후, 내가하고 싶은 부분의 많은 게시물을 발견했지만 모두 함께 작동하는 것은 없습니다.plist에서 읽고 다른 plist에 개체 저장 IOS

정적으로 plist 파일이 있습니다. 나는 그 내용을 바꾸고 싶지 않습니다. plist 파일은 plist에서 읽고 NSArray에 저장된 사전의 배열이며 데이터는 테이블에 표시됩니다. 이것은 완벽하게 작동하고 쉬운 부분입니다!

지금 내가하고 싶은 것은 정적 plist 배열에서 읽은 개체의 즐겨 찾기를 즐겨 찾기의 NSMutableArray에 저장하는 plist입니다. 이 배열은 사용자가 즐겨 찾기 섹션을 선택할 때마다 볼 수있는 즐겨 찾기 테이블로 읽어야합니다.

개념은 간단합니다. 사용자가 "즐겨 찾기에 추가"버튼을 누르면 사전 객체가 즐겨 찾기에 추가됩니다 배열,하지만 내 문제는 제대로 즐겨 찾기 plist 있는지 확인하고 있습니다. 그렇다면 해당 데이터를 즐겨 찾기 배열로 읽습니다. is가 존재하지 않으면 빈 plist를 작성하십시오.이 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

관련 문제