我正在尝试迭代 plist 文件中的嵌套字典。问题是分解内容时类型不匹配。我总是收到 NSObject、NSDict 和其他 NSstuff 无法转换为 String 变量的错误,包括当我使用“(值)”、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 并更新了代码,但类型不匹配仍然存在。正如 Airspeed Velocity 和 nhgrif 在评论中指出的那样,更新后的 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")
}
}
顺便说一句,Airspeed Velocity,喜欢你的博客!
最佳答案
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
比使用 !
强制解包要好得多,即使您正在使用类似 plist 的东西在构建时配置,因此理论上永远不应包含无效条目——因为这样,您可以进行显式错误处理,如果您不小心将错误数据放入 plist 中,这将有助于调试。
关于ios - 遍历 .plist 字典。类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29590172/