чтение NSDictionary из вопроса plist со значением BOOL - PullRequest
9 голосов
/ 06 октября 2011

Итак, у меня есть следующий метод:

- (void)readPlist
{

    NSString *path = [[NSBundle mainBundle] pathForResource:@"States" ofType:@"plist"];    
    self.data = [[NSMutableDictionary alloc] initWithContentsOfFile:path];

    BOOL value = (BOOL)[self.data valueForKey:@"Arizona"];
    NSLog(@"VALUE IS %d", value);

}

Он отлично читает plist, он может обнаружить, что у него 7 ключей, однако, когда я пытаюсь распечатать значение, он дает мне 32, если это нет, и 24, если это да. Что я делаю не так?

Ответы [ 3 ]

23 голосов
/ 07 октября 2011

valueForKey возвращает идентификатор. Сделайте это:

NSNumber * n = [self.data valueForKey:@"Arizona"];
BOOL value = [n boolValue];
1 голос
/ 07 октября 2011
- (void)readPlist
{

NSString *path = [[NSBundle mainBundle] pathForResource:@"States" ofType:@"plist"];    
self.data = [[NSMutableDictionary alloc] initWithContentsOfFile:path];

BOOL value = [[self.data valueForKey:@"Arizona"] intValue];
NSLog(@"VALUE IS %i", value);

}
0 голосов
/ 19 сентября 2013

Думал, что скину на это. Во-первых, как свойство определить значение BOOL в вашем списке?

DTD Apple для plist дает приличную подсказку:

<!ENTITY % plistObject "(array | data | date | dict | real | integer | string | true | false )" >

и позже:

<!-- Numerical primitives -->
<!ELEMENT true EMPTY>  <!-- Boolean constant true -->
<!ELEMENT false EMPTY> <!-- Boolean constant false -->

Все отлично, но как это выглядит в списке?

Ну, для истинного значения это будет:

    <dict>
        <key>employeeId</key>
        <integer>1</integer>
        <key>name</key>
        <string>Joe Smith</string>
        <key>worksRemotely</key>
        <true/>
    </dict>

и, конечно, для ложных:

    <dict>
        <key>employeeId</key>
        <integer>1</integer>
        <key>name</key>
        <string>Joe Smith</string>
        <key>worksRemotely</key>
        <false/>
    </dict>

Чтобы создать объект из plist, как увлеченный пользователь Objectify , я черпаю вдохновение в их фабричных классах. Мой класс Employee будет иметь следующие методы:

+ (Employee *)instanceFromDictionary:(NSDictionary *)aDictionary {

    Employee *instance = [[Employee alloc] init];

    [instance setAttributesFromDictionary:aDictionary];
    return instance;
}

что в свою очередь вызывает:

- (void)setAttributesFromDictionary:(NSDictionary *)aDictionary {

    if (![aDictionary isKindOfClass:[NSDictionary class]]) {
        return;
    }

    [self setValuesForKeysWithDictionary:aDictionary];

}

setValuesForKeysWithDictionary:aDictionary является членом протокола кодирования NSKeyValue . Это доступно с каждым NSObject, что означает, что как подкласс NSObject, наш Employee класс получает это бесплатно.

Пока свойства моего класса Employee совпадают со значениями ключей, указанными в plist, а именно employeeId, name и worksRemotely, мне больше ничего не нужно делать. Этот метод преобразует логическое значение worksRemotely, указанное в plist, в правильное значение в моем экземпляре класса:

@property (assign, nonatomic, getter = isWorkingRemotely) BOOL worksRemotely;

Осталось только перебрать содержимое plist, создать экземпляры моего желаемого класса, включая bool:

NSString *plistPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"employees" ofType:@"plist"];
NSArray *employeeDictionaries = [NSArray arrayWithContentsOfFile:plistPath];
for (NSDictionary *employeeDict in employeeDictionaries) {
     Employee *employee = [Employee instanceFromDictionary:employeeDict];
     [employees addObject:employee];
}

Нет сомнений, что я немного перебрал ответ на конкретный вопрос. Однако, надеюсь, это может пригодиться кому-то еще, кто наткнулся на этот вопрос, пытаясь сделать то, что я пытался, то есть создать класс с логическим значением в листе.

...