чтение 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.