【问题标题】:Swift unable to locate and read property list (.plist) fileSwift 无法定位和读取属性列表 (.plist) 文件
【发布时间】:2015-12-06 17:38:27
【问题描述】:

我在让一个简单的命令行 OSX Swift 程序从一个简单的 .plist XML 文件中读取数据时遇到了一个真正的问题——事实上,尽管该文件似乎存在并复制到了捆绑。

数据由一个类处理,该类用于读取 plist 数据并将其复制到一个数组中,无需再次查询 plist 即可检索该数组:

//  Datadump.swift

import Foundation

class Datadump {

    //array of dictionaries containing string keys and any datatype of value
    var dataArray : Array<Dictionary<String,AnyObject>>

    init () {
        //copies data from plist
        let bundle = NSBundle.mainBundle()
        let path = bundle.pathForResource("Hardware", ofType: "plist")
        //check file located
        print("File Location: \(path)   " )
        let productArray = NSArray(contentsOfFile: path!)

        dataArray = productArray as! Array<Dictionary<String,AnyObject>>
        }

    //returns tuple based on product id
    func getData(prodId: Int) -> (String, Int) {

        //returned vars
        var price = 0
        var name : String = ""

        //iterate through array until relevant product is found
        for dict in dataArray{
            if dict["ProdId"] as! Int == prodId{
                price = dict["Price"] as! Int
                name = dict["Name"] as! String
                break
            }
        }
        return (name, price);
    }

}

但是,一旦出现以下情况,程序就会失败并出现致命错误:

 let productArray = NSArray(contentsOfFile: path!)

到达行,输出:

文件位置:nil 致命错误:在展开可选值时意外发现 nil

打印语句确认程序找不到Hardware.plist文件。

主程序只是创建了类的实例并运行了一个函数,但如上所述,一旦类的init()运行显然就会失败:

//  main.swift

import Foundation

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

//queries data, copies result to tuple
let (nam, pri) = myData.getData(123)
print ("Name: \(nam)  Price: \(pri)")

Hardware.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>Intel i7 CPU</string>
        <key>Price</key>
        <integer>13995</integer>
        <key>ProdId</key>
        <integer>123</integer>
    </dict>
    <dict>
        <key>Name</key>
        <string>19&quot; Monitor</string>
        <key>Price</key>
        <integer>9995</integer>
        <key>ProdId</key>
        <integer>456</integer>
    </dict>
    <dict>
        <key>Name</key>
        <string>8GB DDR Ram</string>
        <key>Price</key>
        <integer>4595</integer>
        <key>ProdId</key>
        <integer>789</integer>
    </dict>
</array>
</plist>

我已经尝试了所有我能想到的方法,包括查看 .plist 文件的设置并以不同的方式重新导入它。

任何帮助将不胜感激!

非常感谢, 光乐

【问题讨论】:

  • “尽管它看似存在并复制到包中”但是没有“看似”。是还是不是?我敢打赌,事实并非如此。您可以打开构建的应用程序并直接查看它并查看。
  • 它在文件导航器中可见,我使用了“添加文件”功能并将其直接拖到项目窗口中。我将如何明确地检查这个?感谢您的帮助。
  • "我使用了 bot 的 'Add File' 功能并直接将其拖到项目窗口中" 将其添加到 project,但不一定将其添加到 应用目标.
  • 这里是文件列表截屏的链接:imgur.com/hMgLoHI
  • 如何正确地将 .plist 文件添加到应用程序中?尽管进行了数小时的研究和实验,但我一直无法找到有关如何执行此操作的任何信息。感谢您的帮助。

标签: swift


【解决方案1】:

通常情况下,您会这样做:

在项目导航器(左侧)中,选择 plist 文件。在文件检查器(右侧)中,检查目标成员资格设置。您可能会发现应用程序目标未选中 。这意味着 plist 文件在您构建时不会被复制到应用程序包中。检查应用目标,一切都会好起来的。

但你不能这样做,因为这是一个命令行程序。它是一个可执行文件,仅此而已。没有可复制的捆绑包。你试图做的事在形而上学上是不可能的。 ?

【讨论】:

  • 在这里比较我的答案(屏幕截图):stackoverflow.com/a/30146303/341994
  • 是的,但是应用复选框是灰色的,无法选中。
  • 这是 plist 文件信息的屏幕截图,请注意无法更改的灰色复选框:imgur.com/ghMjagl
  • 哇,@Kwangle,我以前从未见过。不过,我说的是对的;您必须选中该复选框,否则在构建时文件最终不会复制到应用程序中。我建议你从一个全新的文件开始:在 Xcode 中创建一个空白文本文件,然后将 plist 内容复制到其中。
  • 我知道。这让我疯狂。似乎我缺少一些基本的东西或需要正确设置的设置。我虽然可能是因为该应用程序是一个命令行程序(可能与 .plist 文件不兼容),但我认为情况并非如此。我真的很难过,因为这是我第二次发布这个,没有成功,我认为它真的很奇怪。大概在文本编辑器中编写 XML 文件并在程序之间复制它们是正常的。非常感谢您查看此内容。
【解决方案2】:

在 Swift 3.0 中

获取 .plist 路径

func getPath() -> String {
        let plistFileName = "fileName.plist"
        let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
        let documentPath = paths[0] as NSString
        let plistPath = documentPath.appendingPathComponent(plistFileName)
        return plistPath
}

检查Documents目录中是否存在.plist文件。

  let plistPath = self.getPath()
        if FileManager.default.fileExists(atPath: plistPath) {
           //fileName.plist Found
        }

【讨论】:

  • 那么我们必须将 plist 存储在哪里才能使用它?用户/文件?这行得通!但是这怎么可能被放到生产代码中呢?
  • 文件系统编程指南和FileManager?我想在文档(或其他地方)中创建一个文件夹来存储每个项目的 plist。
猜你喜欢
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 2022-06-29
相关资源
最近更新 更多