ios - 遍历 .plist 字典。类型不匹配

标签 ios swift types plist

我正在尝试迭代 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 Velocitynhgrif 在评论中指出的那样,更新后的 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")
    }
}

顺便说一句,Airspeed Velocity,喜欢你的博客!

最佳答案

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

关于ios - 遍历 .plist 字典。类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29590172/

相关文章:

generics - 当组合泛型和非泛型类时,类型变量转义作用域

ios - Swift - 在 whereField 子句中传递多个参数以从 firebase 检索

ios - 什么时候使用 removeFromSuperview?

c 版本的类名

ios - recaptcha 验证后的空白页使用电话号码 Swift 在 iOS 上使用 Firebase 进行身份验证

objective-c - 如何将自定义 NSView 添加到使用 Interface Builder 构建的 UI?

C# 区分静态 GIF 和动画 GIF

ios - 在 SFSafariViewController 上设置完成按钮颜色

ios - 如何在 iOS objective-c 代码中使用 namespace ?

ios - Stripe 与 iOS 集成