首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用SPM在Swift程序中导入本地xml文件?

如何使用SPM在Swift程序中导入本地xml文件?
EN

Stack Overflow用户
提问于 2022-08-22 12:11:02
回答 1查看 144关注 0票数 0

我正在Swift中为特定类型的数据编写xml解析器库。在我的项目中,有两种导入xml数据的方法,一种是使用web,另一种是提供本地xml文件。第一个很好,但我对第二个有困难。下面是我的代码示例:

代码语言:javascript
复制
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 phasecopy bundle resources来实现它,但是它不适用于我的情况。

我正在编写SWIFT5.6,我已经看到我应该调整我的Package.swift以插入想要的资源。这是我的Package.swift

代码语言:javascript
复制
// 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数据文件。

我创建了一个测试来尝试它:

代码语言:javascript
复制
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链接。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-23 14:34:07

在SWIFT5.3中,可以使用Package.swift添加资源,这是在代码中完成的。

要调用添加的资源,需要使用:

代码语言:javascript
复制
Bundle.module.url(forResource: myFile, withExtension: myExtension)

但是,在以前的扩展中,这是不可能的,因为扩展是self.url。因此,我删除了扩展并将函数loadPN(filePath: String)更改为:

代码语言:javascript
复制
  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测试终于通过。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73444920

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档