我正在尝试从plist文件迭代嵌套的dict。分解内容时问题是类型不匹配。我总是得到NSObject,NSDict和其他NSstuff无法转换为字符串变量的错误,包括当我使用“(value)”时,string(),as ..如何分解plist dict子集将元组?(数组)转换为单独的变量?
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]
}
}
更新: 我用Dictionaries而不是Arrays更改了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")
}
}
Btw,Airspeed Velocity,热爱你的博客!
答案 0 :(得分:4)
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中,将有助于调试。