迭代.plist dict。类型不匹配

时间:2015-04-12 13:50:29

标签: ios swift types plist

我正在尝试从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。如果带有注释错误的行无法解决,我是否应该为循环嵌套?感谢。

enter image description here

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,热爱你的博客!

1 个答案:

答案 0 :(得分:4)

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

您可能会发现在plist中包含另一个字典比使用数组更容易:

A plist of dictionaries inside arrays inside dictionaries

然后使用这样的条目:

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中,将有助于调试。