我已经查看Parse Plist (NSString) into NSDictionary并认为它是不重复,因为该问题及其答案并未解决我的疑虑。
我在文件系统中有一个.plist
文件,结构如下:
此.plist
文件的源代码如下所示:
{
"My App" = {
"Side Panel" = {
Items = {
Price = "#123ABC";
};
};
};
}
我知道如何在Root
中获取这样的项目:
[[NSBundle mainBundle] pathForResource:@"filename" ofType:@"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSString value = [dict objectForKey:@"key"]);
但是,如果结构像我一样,有分层词典怎么办? 如何获得Price
的价值?
我想在一种方法中完成所有这些,理想情况如下:
调用
NSString *hexString = [self getColorForKey:@"My App.Side Panel.Items.Price"];
定义
- (NSString *) getColorForKey: (NSString *)key
{
NSArray *path = [key componentsSeparatedByString:@"."];
NSDictionary *colors = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Colors" ofType:@"plist"]];
NSString *color = @"#FFFFFF"; // white is our backup
// What do I put here to get the color?
return color;
}
答案 0 :(得分:0)
以下是适用于我的解决方案:
+ (NSString*) getHexColorForKey:(NSString*)key
{
NSArray *path = [key componentsSeparatedByString:@"."];
NSDictionary *colors = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Colors" ofType:@"plist"]];
NSString *color = @"#FFFFFF";
for (NSString *location in path) {
NSObject *subdict = colors[location];
if ([subdict isKindOfClass:[NSString class]])
{
color = (NSString*)subdict;
break;
}
else if ([subdict isKindOfClass:[NSDictionary class]])
{
colors = (NSDictionary*)subdict; // if it's a dictinoary, our color may be inside it
}
else
{
[SilverLog level:SilverLogLevelError message:@"Unexpected type of dictinoary entry: %@", [subdict class]];
return color;
}
}
return color;
}
其中key
是与NSString
匹配的/^[^.]+(\.[^.]+)*$/
,这意味着它看起来像我的目标@"My App.Side Panel.Items.Price"
。
答案 1 :(得分:0)
是的,我理解你想要完成的事情;谢谢你的澄清。但是我会补充一点,我写的资源和建议确实提供了解决问题的必要信息。
也就是说,以下内容获取您的字典:
NSURL *plistURL = [[NSBundle mainBundle] URLForResource:@"Info" withExtension:@"plist"];
NSData *plistData = [NSData dataWithContentsOfURL:plistURL];
NSDictionary *tieredPlistData = [NSPropertyListSerialization propertyListWithData:plistData
options:kCFPropertyListImmutable
format:NULL
error:nil];
然后,如果我们对Items
NSDictionary *allItemsDictionary = tieredPlistData[@"My App"][@"Side Panel"][@"Items"];
假设Items
将包含许多对象,您可以使用
NSArray *keys = [allItems allKeys];
for(NSString *key in keys){
NSString *colorValue = allItemsDictionary[key];
// do something with said color value and key
}
或者,如果您需要一个值,那么只需引用该键
NSString *colorForPriceText = allItemsDictionary[@"Price"];
但有一些提示:
NSBundle
加载您的调用。在您的示例中,每次需要颜色时,最终都会重新访问NSBundle
并堆积在不需要的内存分配上。一种方法是将plist加载到iVar NSDictionary
中,然后NSDictionary
将由另一种方法单独使用。