koen
koen

Reputation: 5729

Swift Package Manager - Type 'Bundle' has no member “module” error

Working on implementing SPM for a framework, and got stuck on the Type 'Bundle' has no member “module” error.

I have seen two other recent posts about this here and here, but following all the steps, it is still not working for me, no resource_bundle_accessor file is generated.

I asked about my Package.swift file here, and that has been answered and resolved. For completeness here's the file:

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "BioSwift",
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
        .library(
            name: "BioSwift",
            targets: ["BioSwift"]
        )
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
        .target(
            name: "BioSwift",
            dependencies: [],
            resources: [
                  .process("Resources")
                ]
        ),
        .testTarget(
            name: "BioSwiftTests",
            dependencies: ["BioSwift"]
        )
    ]
)

I get the Type 'Bundle' has no member “module” error when trying to access one of the resources in the bundle:

public let unimodURL = Bundle.module?.url(forResource: "unimod", withExtension: "xml")

The project is on GitHub here

Upvotes: 15

Views: 16384

Answers (7)

Kirow
Kirow

Reputation: 1210

Had same issue on .xcproject with local package added that includes .process("Resources/"). Simple Xcode restart fixed the issue.

Upvotes: 1

t.ios
t.ios

Reputation: 1042

What I did to access the Bundle.module object of my module outside of my Swift Package either in the app or another project was to create a publicly accessible variable inside the package i.e.

public static var myModuleNameBundle: Bundle { Bundle.module }

Replace the myModuleName of myModuleNameBundle with the name of your Swift Package

Upvotes: 0

Samson Sunny
Samson Sunny

Reputation: 121

Please check your Resources folder path. It should be kept inside the Sources/PackageNameFolder/{Resources}. enter image description here

Upvotes: 0

nico_dkd
nico_dkd

Reputation: 169

I had the same problem and I could solve it with the good ol' "did you try to turn it off and back on again?". No seriously, I simply used Bundle.module in my code (could also just be a one liner like print(Bundle.module)), closed Xcode completly and reopened the package via the Package.swift file and it worked.

Upvotes: 1

bhushan412
bhushan412

Reputation: 1

I had same issue (when i created fresh new package) ,what i did was i added new View file inside my package . And the error was gone .

Upvotes: 0

Mojtaba Hosseini
Mojtaba Hosseini

Reputation: 119302

Besides all errors in the test file, the only issue remains is that module is not an optional. To fix that, just change this:

public let unimodURL = Bundle.module?.url(forResource: "unimod", withExtension: "XML")

to:

public let unimodURL = Bundle.module.url(forResource: "unimod", withExtension: "xml")

Update:

If you use .xcodeproj file, you will continue seeing this error. You should consider opening it with the package.swift or import it as a package (instead of converting it to a project)!

by the way, here is the generated file, so you can add it as a development asset when you are working with the xcodeproject:

import class Foundation.Bundle

private class BundleFinder {}

extension Foundation.Bundle {
    /// Returns the resource bundle associated with the current Swift module.
    static var module: Bundle = {
        let bundleName = "BioSwift_BioSwift"

        let candidates = [
            // Bundle should be present here when the package is linked into an App.
            Bundle.main.resourceURL,

            // Bundle should be present here when the package is linked into a framework.
            Bundle(for: BundleFinder.self).resourceURL,

            // For command-line tools.
            Bundle.main.bundleURL,
        ]

        for candidate in candidates {
            let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle")
            if let bundle = bundlePath.flatMap(Bundle.init(url:)) {
                return bundle
            }
        }
        fatalError("unable to find bundle named BioSwift_BioSwift")
    }()
}

Upvotes: 11

raistlin
raistlin

Reputation: 261

If you follow the instructions on this video you will see that you need to define how you would like to include non-clear purpose files in a package. In this case your package manifest should be something like:

// swift-tools-version:5.3

import PackageDescription

let package = Package(
    name: "BioSwift",
    products: [
        // Products define the executables and libraries produced by a package, and make them visible to other packages.
        .library(
            name: "BioSwift",
            targets: ["BioSwift"]),
    ],
    dependencies: [],
    targets: [
        .target(
            name: "BioSwift",
            dependencies: [],
            resources: [
              .copy("Resources")
            ]),
        .testTarget(
            name: "BioSwiftTests",
            dependencies: ["BioSwift"]),
    ]
)

Please pay attention on using Swift 5.3 tools and that you need to declare the resources for the respective target. The copy action on resources will leave them unprocessed when they are added in the compiled bundle.

Upvotes: 2

Related Questions