如何从 plist iOS 中读取数组

Posted

技术标签:

【中文标题】如何从 plist iOS 中读取数组【英文标题】:How to read Array from plist iOS 【发布时间】:2013-04-28 23:25:57 【问题描述】:

我正在尝试读取包含数组的 plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>key1</key>
<string>value1</string>
<key>key2</key>
<string>value2</string>
<key>keyarray1</key>
<array>
    <string>keyitem1</string>
    <string>keyitem2</string>
</array>
</dict>
</plist>

当我尝试读取 valueForKey:@"keyarray1" 时,我得到空值。 我试图读取为字符串和数组,螺母没有用。

我的代码

NSDictionary * values=[[NSDictionary alloc] initWithContentsOfFile:@"values.plist"];
NSArray *arrayValues=[[NSArray alloc] initWithArray:[values valueForKey:@"keyarray1"]];

【问题讨论】:

您能否向我们展示您读取 plist 的完整代码? 我可以读取 key1 和 key2 但无法读取数组。 发送您的 plist 的屏幕截图 How to read data structure from .plist file into NSArray 的可能重复项 【参考方案1】:

首先检查您的 plist 看起来像:

现在在您访问 plist 的地方写下以下几行

目标-C:

NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Values" ofType:@"plist"]];
NSArray *array = [dictionary objectForKey:@"keyarray1"];
NSLog(@"dictionary = %@ \narray = %@", dictionary, array);

这是我的工作窗口的完整屏幕截图(带有日志输出):

斯威夫特:

let dictionary = NSDictionary(contentsOfFile: Bundle.main.pathForResource("Values", ofType: "plist")!);
let array = dictionary?["arrayKey"] as! NSArray
print("dictionary=",  dictionary, "\narray =",  array)

【讨论】:

【参考方案2】:

我知道这个问题太老了,我只想为最近遇到这个问题的人添加更多信息。

在我的例子中,我创建了一个作为数组的 plist(plist 默认是带有键“Root”的字典)。

那么 xml 看起来像这样:

在我的视图控制器上,我直接初始化 Array 而不是初始化 Dictionary 然后获取键“Root”的对象:

注意:我只想添加此信息,因为我只看到初始化 Dictionary 然后获取键的对象。希望它会帮助你们。

【讨论】:

【参考方案3】:

plist 存储在哪里?它在应用程序包中吗?如果是这样,您可能希望使用[[NSBundle mainBundle] pathForResource:@"values" ofType:@"plist"] 来获取路径,而不是硬编码@"values.plist"

在正确设置路径后,您可以毫无问题地从字典中获取数组,例如[values objectForKey:@"keyarray"]

最后说明:objectForKey:valueForKey: 之间存在差异。您当前正在使用valueForkey:,它是NSKeyValueCoding 的一部分,这是一个NSDictionary 恰好符合的协议。您应该改用objectForKey:(或语法糖访问器,即dictionary[@"key"]),因为它们是从字典中访问值的正确方法。

【讨论】:

我尝试使用objectforkey,但没有用。我确实得到了 0。 如果你 NSLog(@"values: %@", values); 会发生什么?有什么东西被打印出来,或者,你看到“(null)”吗?【参考方案4】:

你能试试下面的代码吗?

NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"values" ofType:@"plist"];
NSDictionary * values=[[NSDictionary alloc] initWithContentsOfFile:plistPath];
NSArray *arrayValues=[[NSArray alloc] initWithArray:[values valueForKey:@"keyarray1"]];
NSLog(@"arrayValues = %@",arrayValues);

我在日志中得到以下输出:-

arrayValues = (
    keyitem1,
    keyitem2
)

【讨论】:

【参考方案5】:

斯威夫特 4

在 Swift 4 中,您可以使用 codable 和 PropertyListDecoder

func setData() 
  // location of plist file
  if let settingsURL = Bundle.main.path(forResource: "JsonPlist", ofType: "plist") 
    do 
      var settings: MySettings?
      let data = try Data(contentsOf: URL(fileURLWithPath: settingsURL))
      let decoder = PropertyListDecoder()
      settings = try decoder.decode(MySettings.self, from: data)
      print("array  is \(settings?.keyarray1 ?? [""])")//prints ["keyitem1", "keyitem2"]
     catch 
      print(error)
    
  


struct MySettings: Codable 
  var keyarray1: [String]?

  init(from decoder: Decoder) throws 
    let values = try decoder.container(keyedBy: CodingKeys.self)
    keyarray1 = try values.decodeIfPresent([String].self, forKey: .keyarray1)
  

更多信息请看How to read from a plist with Swift 3 ios app

【讨论】:

【参考方案6】:

试试这个

NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:@"values.plist"];
NSMutableDictionary *dict =[NSMutableDictionary dictionaryWithContentsOfFile:finalPath];
NSArray *arr =[dict valueForKey:@"keyarray1"];
NSLog(@"%@",arr);

【讨论】:

这是在 app bundle 中查找项目路径的错误方法。不要以为它会是一个扁平的捆绑包,基本上。此外,从 NSDictionary 访问值时,您不应使用 valueForKey: 那么从 NSDictionary 访问值时我应该使用什么? -objectForKey:。在这个问题中查看我对@ram2013 的回答:***.com/a/16269368/162361 NSString path = [[NSBundle mainBundle] bundlePath]; NSString *finalPath = [路径 stringByAppendingPathComponent:@"values.plist"];或 NSString plistPath = [[NSBundle mainBundle] pathForResource:@"values" ofType:@"plist"];您能否解释在应用程序包中查找项目路径的错误方法 使用stringByAppendingPathComponent:——正如你的回答所做的那样——假设资源的路径将是一个比捆绑包低一级的平面文件。情况可能并非如此。例如,在将来的某个时候,资源可能会被移动到 Resources/ 文件夹中(就像在 Mac 上一样)。 pathForResource:ofType: 是一种更正确的获取路径的方法,但不是您在答案中使用的方法。

以上是关于如何从 plist iOS 中读取数组的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发,如何替换plist这个数组下数据

用触动怎么读取plist的数组?

如何从 plist 数组中读取一个条目

从 plist 读取,然后将对象保存到不同的 plist iOS

从 iOS 的 UITests 中读取 Info.plist?

如何在 swift 中读取数组和字典的 plist