在Xcode 12项目中找不到*.json文件



我第一次尝试Swift(5.3(和Xcode(12(。任务是解析附近已经存在的*.json文件。

老实说,在Xcode项目中添加文件比实际解析它更棘手:无论我放在哪里,总是找不到它。这个答案没有帮助,因为File Inspector中没有Target Membership部分(我想,它在Xcode 12中被重命名或移动到了其他地方;也许我错了;无论如何,也找不到它(。

我还注意到,在创建新的项目与新的Swift包时,Target Membership部分的行为有所不同。如果是项目,则会显示目标成员身份。由于我已经创建了一个包,所以这个部分对我来说不可用

有人能帮我了解一下这里发生了什么吗?


  • 项目的结构(称为"TryParseJSON",它被组织为Swift包(如下:

    TryParseJSON/
    Package.swift
    Sources/
    TryParseJSON/
    main.swift # defines `findPath(to:)` and calls `findPath(to: "persons.json")`
    Person.swift
    persons.json # this file is not found
    
  • Package.swift文件的内容如下:

    // swift-tools-version:5.3
    import PackageDescription
    let package = Package(
    name: "TryParseJSON",
    products: [
    .executable(name: "TryParseJSON", targets: ["TryParseJSON"]),
    ],
    targets: [
    .target(
    name: "TryParseJSON",
    dependencies: [],
    resources: [
    .copy("persons.json"),
    ]
    ),
    ]
    )
    
  • .copy("persons.json")中的路径是相对于main.swift;如果我放一个相对于Package.swift(.copy("Sources/TryParseJSON/persons.json")(的路径,Xcode找不到JSON(显示"found 1 file(s) which are unhandled"警告(,包仍然不工作;.copy("persons.json")没有任何警告。

  • persons.json文件添加了file>新建>文件>quot;空的";(类别"其他"(>重命名为";persons.json";。

  • findPath功能:

    func findPath(to file: String) -> URL {
    guard
    let path = Bundle.main.url(forResource: file, withExtension: nil)
    else {
    fatalError("File (file) was not found") // this is called
    }
    return path
    }
    
  • 此函数在main.swift:中定义和调用

    let path = findPath(to: "persons.json")
    

我不知道这是怎么回事,我不知道我应该对";在目标中添加新成员";,我不知道目标和产品是什么,在Xcode中添加文件需要付出很多努力,这让我很沮丧。

使用Swift 5.3,包可以添加和处理非代码资源。但是,Package.swift必须明确定义它们。通过向目标添加资源来实现这一点:

targets: [
.target(
name: "TryParseJSON",
resources: [
.copy("persons.json")
]
)
]

这将把它复制到捆绑包中,希望在正确的位置。如果没有,则可能需要额外的配置。

请注意,路径是相对于包含目标源的目录的。Apple建议在源目录中创建一个名为Resources的子目录。如果你这样做,你需要

.copy("Resources/persons.json")

此外,请确保Package.swift在顶部定义Swift工具5.3,如下所示:

// swift-tools-version:5.3

当你需要访问文件时,如何提取文件的URL也很重要。根据苹果的文档,你必须始终使用Bundle.module.url(forResource:,withExtension:)来获取资源的URL。因此,在上述情况下使用

guard let resourceUrl = Bundle.module.url(forResource: "persons",withExtension: "json")
else { /* fail */ }

最新更新