【问题标题】:Swift 4 .plist handlingSwift 4 .plist 处理
【发布时间】:2018-06-26 12:24:53
【问题描述】:

我有一个 .plist 文件,我将在其中存储用户以后可以读取/修改的不同位置。但我似乎无法让代码工作......

我的 .plist:

<dict>
    <key>MAIN TITLE</key>
    <array>
        <dict>
            <key>name</key>
            <string>NAME IN TABLECELL</string>
        </dict>
        <dict>
            <key>name</key>
            <string>X</string>
        </dict>
    </array>
</dict>

我想让MAIN TITLE 成为该部分的标题。 我的代码是:

func readPlist() {
        guard let fileUrl = Bundle.main.url(forResource: "SavedPlaces", withExtension: "plist") else { return }
        do {
            let data = try Data.init(contentsOf: fileUrl)
            let plist = try! PropertyListSerialization.propertyList(from:data, options: [], format: nil) as! [[String:Any]]
            print(plist)

        } catch {
            print(error.localizedDescription)
        }
    }

但这会引发几个错误,其中:

Thread 1: signal SIGABRT
Could not cast value of type '__NSCFDictionary' (0x10b39ddd8) to 'NSArray' (0x10b39e008).

有没有一种方法可以在不使用 NSArray、NSDictionary 等的情况下获取所有值?

谢谢。

【问题讨论】:

  • 您的 plist 是顶层的 Dictionary(开头是 &lt;dict&gt;),而不是 Array。而[[String:Any]]ArrayDictionaries,所以无法进行转换。

标签: ios swift uitableview plist


【解决方案1】:

改变这一行

let plist = try! PropertyListSerialization.propertyList(from:data, options: [], format: nil) as! [[String:Any]]

let plist = try! PropertyListSerialization.propertyList(from:data, options: [], format: nil) as! [String:Any]

【讨论】:

    【解决方案2】:

    如前所述,plist 文件的根对象是 &lt;dict&gt;ionary - 它仍然比 JSON 更容易识别?

    要摆脱集合类型数组和字典,请使用Decodable 协议和两个自定义结构和PropertyListDecoder

    struct SavedPlaces: Decodable {
        private enum CodingKeys : String, CodingKey { case mainTitle = "MAIN TITLE" }
    
        let mainTitle : [Title]
    }
    
    struct Title: Decodable {
        let name : String
    }
    

    func readPlist() {
        let fileUrl = Bundle.main.url(forResource: "SavedPlaces", withExtension: "plist")!
        let data = try! Data(contentsOf: fileUrl)
        let plist = try! PropertyListDecoder().decode(SavedPlaces.self, from: data)
        print(plist.mainTitle)
    }
    

    感叹号是有意的。由于文件位于捆绑包中,因此它是不可变的,并且代码不得崩溃。是你犯了设计错误。

    【讨论】:

      【解决方案3】:

      .plist 文件是一个字典,您将其强制转换为字典数组[[String:Any]]

      从您的代码中替换以下行:

      let plist = try! PropertyListSerialization.propertyList(from:data, options: [], format: nil) as! [[String:Any]]
      

      与:

      if let plist = try! PropertyListSerialization.propertyList(from:data, options: [], format: nil) as? [String:Any] {
                  print(plist)
      }
      

      使用if let 将是一个额外的优势,因为它将帮助您检查 PropertyListSerialization 响应的空值。

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-11
        • 1970-01-01
        • 1970-01-01
        • 2020-12-02
        • 2018-03-21
        • 1970-01-01
        • 2019-12-12
        • 1970-01-01
        相关资源
        最近更新 更多