我正在Swift中为特定类型的数据编写xml解析器库。在我的项目中,有两种导入xml数据的方法,一种是使用web,另一种是提供本地xml文件。第一个很好,但我对第二个有困难。下面是我的代码示例:
import Foundation
class PnmlParser: NSObject, XMLParserDelegate {
// DOES NOT WORK
func loadPN(filePath: String) {
print(Bundle.main)
let xmlResponseData = Bundle.main.getFileData(filePath)
let parser = XMLParser(data: xmlResponseData)
parser.delegate = self
parser.parse()
}
// WORK
func loadPN(url: URL) {
let parser = XMLParser(contentsOf: url)!
parser.delegate = self
parser.parse()
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
// Some code
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
// Some code
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
// Some code
}
func parserDidEndDocument(_ parser: XMLParser) {
// Some code
}
}
extension Bundle {
func getFileData(_ file: String) -> Data {
guard let url = self.url(forResource: file, withExtension: nil) else {
fatalError("Failed to locate \(file) in bundle")
}
guard let data = try? Data(contentsOf: url) else {
fatalError("Failed to load \(file) in bundle")
}
return data
}
}loadPN有两个函数,但是只有loadPN(filePath: String)不能工作,因为它找不到我的loadPN(filePath: String)文件。
我使用Swift软件包管理器而不是XCode来插入资源。我已经了解了如何使用XCode使用build phase和copy bundle resources来实现它,但是它不适用于我的情况。
我正在编写SWIFT5.6,我已经看到我应该调整我的Package.swift以插入想要的资源。这是我的Package.swift
// swift-tools-version: 5.6
import PackageDescription
let package = Package(
name: "swift-xml-import-test",
...
targets: [
.target(
name: "swift-xml-import-test",
dependencies: [],
resources: [.process("Resources/data.xml")]
),
.testTarget(
name: "swift-xml-import-testTests",
dependencies: ["swift-xml-import-test"],
resources: [.process("ResourcesTests/dataTests.xml")]
),
]
)一个示例GitHub项目显示了数据结构和遇到的问题:我的GitHub项目示例创建了两个文件夹,分别是Resources (Sources/swift-xml-import-test/Resources)和ResourcesTests (Tests/swift-xml-import-testTests/ResourcesTests),其中每个文件夹中都有一个xml数据文件。
我创建了一个测试来尝试它:
final class swift_xml_import_testTests: XCTestCase {
func testWork() {
let p = PnmlParser()
if let url = URL(string: "https://www.pnml.org/version-2009/examples/philo.pnml") {
p.loadPN(url: url)
}
}
func testDoesNotWork() {
let p = PnmlParser()
p.loadPN(filePath: "dataTests.xml")
}
}当我启动我的测试testDoesNotWork()时,我得到以下错误:来自我之前的扩展的Thread 1: Fatal error: Failed to locate dataTests.xml in bundle。如果有人能帮我,我不明白我错过了什么。如果您想测试自己,您可以使用上面示例项目的GitHub链接。
发布于 2022-08-23 14:34:07
在SWIFT5.3中,可以使用Package.swift添加资源,这是在代码中完成的。
要调用添加的资源,需要使用:
Bundle.module.url(forResource: myFile, withExtension: myExtension)但是,在以前的扩展中,这是不可能的,因为扩展是self.url。因此,我删除了扩展并将函数loadPN(filePath: String)更改为:
func loadPN(filePath: String) {
if let url = Bundle.module.url(forResource: filePath, withExtension: nil) {
let parser = XMLParser(contentsOf: url)!
parser.delegate = self
parser.parse()
}
}testDoesNotWork测试终于通过。
https://stackoverflow.com/questions/73444920
复制相似问题