чтение NSDictionary из проблемы plist со значением BOOL

поэтому у меня есть следующий метод:

- (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 ответов


valueForKey возвращает идентификатор. Этого:

NSNumber * n = [self.data valueForKey:@"Arizona"];
BOOL value = [n boolValue];

- (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);

}

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

DTD яблока для 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 -->

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

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

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

и, конечно, для false:

    <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 является членом Протокол NSKeyValueCoding. Это доступно с каждым 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];
}

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