在 Swift 中将 .plist 数据读入字典

Posted

技术标签:

【中文标题】在 Swift 中将 .plist 数据读入字典【英文标题】:Reading .plist data into a dictionary in Swift 【发布时间】:2015-11-30 18:15:34 【问题描述】:

我在将 plist 文件中的 XML 数据读入字典时遇到问题。问题包括 plist 未被识别为捆绑包的一部分,尽管正确的选项可以将其添加到导入时检查的项目中。

我正在寻找一种简单的方法来在程序启动时读取数据,然后通过访问数组的方法轻松获得它。数据不需要重写或更改,因此只需一次传输即可使程序运行。

这是.plist的数据结构示例(记录比实际文件少):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>Name</key>
        <string>19” HD Monitor</string>
        <key>Price</key>
        <integer>11999</integer>
        <key>ProdId</key>
        <integer>123</integer>
    </dict>
    <dict>
        <key>Name</key>
        <string>4GB RAM Module</string>
        <key>Price</key>
        <integer>2995</integer>
        <key>ProdId</key>
        <integer>456</integer>
    </dict>
    <dict>
        <key>Name</key>
        <string>Samsung 256GB SSD</string>
        <key>Price</key>
        <integer>11250</integer>
        <key>ProdId</key>
        <integer>789</integer>
    </dict>
</array>
</plist>

数据由产品名称(字符串)、以便士或美分表示的价格(整数)和唯一的产品 ID(整数)组成。它们的关键名称分别是“Name”、“Price”和“ProdID”。

这是我用来读取数据的代码。我使用一个简单的命令行程序以简单的形式隔离此操作,并通过测试查看数据是否已存储并从字典中检索。数据操作将在一个类中提供:

//
//  Datadump.swift
//  PListTester
//
//  Created by Kwangle on 30/11/2015.
//  Copyright (c) 2015 KwangCo All rights reserved.
//

import Foundation


class Datadump 


    //declare container array
    var dictArray: Array<Dictionary<String,AnyObject>>

    //reads data when class is constructed
    init () 

        let bundle = NSBundle(forClass: Datadump.self)
        //gets file location of 'Products.plist' from bundle
        let fileLocation = bundle.pathForResource("Hardware", ofType: "plist")

        //creates NSArray from contents of 'Hardware.plist'
        let productArray = NSArray(contentsOfFile: fileLocation!)
        //creates dictionary array from NSArray via force conversion
        dictArray = productArray as! Array<Dictionary<String,AnyObject>>

        for (var i = 0; i < dictArray.count; i++)
            dictArray.append(productArray!.objectAtIndex(i) as! Dictionary<String, AnyObject>)
        
    

//reads price value of matching ProdID  
        func priceFromID(pId: Int) -> Int
            var price = 0
            //iterate through array until relevant product is found
            for dict in dictArray
                //reads 'ProdId' key and compares it to pId function argument
                if dict["ProdId"] as! Int == pId
                    //if product ID is found price is set to its value
                    price = dict["Price"] as! Int
                    break
                
            

        return price;

    

//end class

Main 方法只是创建 DataDump 类的一个实例并使用与 ProdId 匹配的值运行 priceFromID 方法:

//
//  main.swift
//  PListTester
//
//  Created by Kwangle on 29/11/2015.
//  Copyright (c) 2015 KwangCo All rights reserved.
//

import Foundation

//creates instance of Datadump class
var myData = Datadump ()

//queries data
print (myData.priceFromID(123) )

我得到的错误是:

fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)

这与该行有关:

let productArray = NSArray(contentsOfFile: fileLocation!)

我也收到错误代码:

EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

对此的任何帮助将不胜感激!

非常感谢, 千瓦

【问题讨论】:

添加print(fileLocation) right below the line that sets the fileLocation`。我认为这是零。文件名是否正确? 是的,返回 nil。 是文件名Hardware.plist NSBundle(forClass: Datadump.self) 而不是通常的NSBundle.mainBundle() 的目的是什么? 是的,文件名是正确的,但表示 .plist 文件的目标成员身份为“PListTester”的复选框未选中,并且由于某种原因无法更改。我已经尝试重新导入文件,但这并没有改变。 【参考方案1】:

您不想将内容加载到数组中。你想要一本字典。

看这里;

How to read data structure from .plist file into NSArray

【讨论】:

fileLocation 为零。首先他/她必须解决这个问题。 :)]

以上是关于在 Swift 中将 .plist 数据读入字典的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中将两个数组合并为一个字典

如何在 swift 中读取数组和字典的 plist

将嵌套字典写入 plist (Swift) 时的类型问题

在 Swift 中将 JSON 字典导入核心数据

如何使用 Swift 将新数组数据添加到 plist 文件中的 NSDictionary

如何使用swift在pubnub中将数据发布为Any类型的字典?