遍历.plist字典。 types不匹配

我正在试图从plist文件迭代嵌套的字典。 问题是在分解内容时types不匹配。 我总是得到NSObject,NSDict和其他NSstuff无法转换为stringvariables,包括当我使用“(价值)”,string(),作为..如何分解一个plist字典子集元组?(数组) ?

func LoadPlistContacts() { let path = NSBundle.mainBundle().pathForResource("ContactList", ofType: "plist") var AppContactsList = NSDictionary(contentsOfFile: path!) ListKeys = sorted(AppContactsList!.allKeys as! [String]) for key in ListKeys { var (AppPersonName, AppPersonSurname, AppPersonCompany, AppPersonPhone) = AppContactsList[key] } } 

更新:我用字典而不是数组更改了plist,并更新了代码,但types不匹配仍然存在。 正如Airspeed Velocitynhgrif在评论中指出的那样,更新后的plist的例子确实变得混乱了。 我应该做嵌套循环,如果与评论错误的行不能解决它? 谢谢。

在这里输入图像说明

 var ListKeys: [String]! var ListContacts: [String: String]! func LoadPlistContacts() { if let path = NSBundle.mainBundle().pathForResource("ContactList", ofType: "plist") { var AppContactsList = NSDictionary(contentsOfFile: path) ListKeys = sorted(AppContactsList!.allKeys as! [String]) ListContacts = sorted(AppContactsList!.allValues as [String:String]) { $0.0 < $1.0 } // I get an error [AnyObject] is not convertible to '[String:String]' for contact in ListContacts { let name = contact["Forename"] ?? "" let surname = contact["Surname"] ?? "" let address = contact["Company"] ?? "" let phone = contact["Phone"] ?? "" } } else { fatalError("Could not open Contacts plist") } } 

顺便说一句,空速,爱你的博客!

Swift不允许你像这样将数组解构成元组 – 主要是因为它不能保证工作(数组可能没有正确数量的条目)。

你可能会发现在plist里面有另外一个字典比在数组中更容易,

字典里的数组里面的字典

然后使用这样的条目:

 if let path = NSBundle.mainBundle().pathForResource("ContactList", ofType: "plist"), contacts = NSDictionary(contentsOfFile: path) as? [String:[[String:String]]] { let sortedContacts = sorted(contacts) { lhs,rhs in lhs.0 < rhs.0 } // destructuring works here because contacts is known // at compile time to be an array of (key,value) pairs for (section, contactArray) in sortedContacts { for contact in contactArray { let name = contact["Forename"] let surname = contact["Surname"] let address = contact["Company"] let phone = contact["Phone"] println(name,surname,address,phone) } } } else { fatalError("Could not open Contacts plist") } 

请注意,当您获得这些条目时,它们将是可选的。 这是这种方法的另一个好处 – 它意味着您可以在plist中省略条目,然后默认它们:

 // default to blank string for phone number let phone = contact["Phone"] ?? "" 

或者强制他们:

  for (section, contactArray) in contacts { for contact in contactArray { if let name = contact["Forename"], surname = contact["Surname"], address = contact["Company"], phone = contact["Phone"] { println(name,surname,address,phone) } else { fatalError("Missing entry for \(section)") } } } 

请注意, if let用力而不是用力打包东西,那更好用! ,甚至当你在像构build时configuration的plist那样工作的时候,理论上也不应该包含无效的条目 – 因为这样,你可以放入明确的error handling,这将有助于debugging,如果你不小心把错误的数据在plist中。