Search code examples
jsonswiftswift-package-manager

Problem loading JSON resource in SWIFT package


I am trying to load a JSON file that is bundled with a Swift package I am working on.

The JSON file is called config.json and it is located in my project under /Sources/<Target>/data/config.json

UPDATE: I have also added the resource to the target in the Package Description as follows:

...
.target(
    name: "MyPackage",
    resources: [
        .process("data/config.json")
    ]
),
...

I am trying to load it using the following code:

guard let sourcesURL = Bundle.main.url(forResource: "config", withExtension: "json") else {
    fatalError("Could not find config.json")
}

... but I keep getting nil. Has anyone had an issue like this? Any idea what I'm doing wrong?


Solution

  • You should use module

    Bundle.module.url(forResource: "config", withExtension: "json")
    

    And you need to make sure the file is included when building by adding below to your target in Package.swift

    resources: [
        .copy("data/config.json") //This could also be .process
    ])
    

    The above assumes that the resource is loaded from within the same package, if you want to load a resource from another package you can use the following general solution.

    First define a constant in the package that holds the bundle identifier for the package, for instance in an extension to Bundle

    extension Bundle {
        public static let myPackageNameBundleIdentifier = Bundle.module.bundleIdentifier!
    }
    

    And then create an instance of that Bundle when loading the resource in another package or the app

    if let bundle = Bundle(identifier: Bundle.myPackageNameBundleIdentifier) {
        let url = bundle.url(forResource: "config", withExtension: "json")
        // ...
    }