迭代 .plist 字典.类型不匹配 [英] Iterating over .plist dict. Type mismatch

查看:55
本文介绍了迭代 .plist 字典.类型不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从 plist 文件中迭代嵌套的 dict.问题在于分解内容时类型不匹配.我总是收到 NSObject、NSDict 和其他 NSstuff 无法转换为字符串变量的错误,包括当我使用(value)"、string() 时,作为 .. 如何将 plist dict 子集元组?(数组)分解为单独的变量?

I am trying to iterate over nested dict from plist file. Problem is with type mismatch while decomposing contents. I always get errors that NSObject, NSDict and other NSstuff cannot be translated to String variables including when I use "(value)", string(), as .. How to decompose a plist dict sub sets tuple?(array) into separate variables?

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 后确实变得更加混乱.如果带有注释错误的行不能解决它,我应该嵌套循环吗?谢谢.

UPDATED: I have altered the plist with Dictionaries instead of Arrays and updated the code, yet type mismatch persists. As Airspeed Velocity and nhgrif point out in comments, example did got messier with updated plist. Should I do nested for cycles if the line with the commented error does not solve it? Thanks.

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, love your blog!

推荐答案

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

Swift doesn’t allow you to destructure arrays into tuples like this – primarily because it isn’t guaranteed to work (the array might not have the right number of entries).

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

You may find it easier, rather than arrays, to have another dictionary inside the plist:

然后像这样使用这些条目:

And then to use those entries like so:

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 中的条目,然后默认它们:

Note, when you get those entries out, they will be optional. This is really another benefit of this approach – it means you can leave out entries in the plist, and then either default them:

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

Note, it is much more preferable to use if let rather than force-unwrapping things with !, even when you’re working from something like a plist that is configured at build-time and so in theory should never contain invalid entries – because this way, you can put in explicit error handling that will help debug if you ever accidentally put the wrong data in the plist.

这篇关于迭代 .plist 字典.类型不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆