1

I have a Swift Package for a small feature that I'd like to use in multiple apps. All I want is to present the ViewController inside the Swift package from the app that uses it.

In the Swift Package I have this extension to get a view controller:

    public extension UIViewController{ 
    static func getStoryboardVC() -> UIViewController { 
      let storyboard = UIStoryboard(name: String(describing: self), bundle: Bundle.module) 
        return storyboard.instantiateInitialViewController()! 
    }  
}

the Swift Package is called ARMap and it has ARCameraVC view controller, in the app I present the SP's view controller like this:

     let vc = ARMap.ARCameraVC.getStoryboardVC()  
 present(vc, animated: true, completion: nil)

This works great when building in Xcode into a device, but when installing the app as an .ipa file, or submitting to the App Store it crashes with this error from the device logs:

Fatal error: unable to find bundle named ARMap_ARMap: file ARMap/resource_bundle_accessor.swift, line 27

There is something wrong with Bundle.model when getting the storyboard.

EDIT: Here is the auto generated resource_bundle_accessor.swift that will return Bundle.module and where the error comes from:

    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 = "ARMap_ARMap"

        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 ARMap_ARMap")
    }()
}

and here is the package manifest

    import PackageDescription

let package = Package(
    name: "ARMap",
    products: [
        .library(name: "ARMap", targets: ["ARMap"]),
    ],
    dependencies: [
    ],
    targets: [ 
        .target(
            name: "ARMap",
            dependencies: [],
            path: "Sources/ARMap",
            resources: [.process("Resources")]
        ),
        .testTarget(
            name: "ARMapTests",
            dependencies: ["ARMap"]),
    ]
)

and here how the package structure looks like:

enter image description here

fullmoon
  • 8,030
  • 5
  • 43
  • 58
  • Does it still work if you build clean (Command-Shift-K)? Could you also post the package manifest? – Allison Feb 15 '21 at 21:41
  • Yes it works perfect if I build in Xcode to a device, but after exporting the app to the App Store or creating an .ipa to install on phone, it generates that error. I edited the question. Thank you. – fullmoon Feb 16 '21 at 05:32

1 Answers1

0

I think it was a bug in Xcode. I ended up deleting the module and creating it from scratch. The error disappeared.

fullmoon
  • 8,030
  • 5
  • 43
  • 58
  • I have the same issue, but I can't afford to re-create the module. Which Xcode did you test with? – bonc Nov 11 '21 at 14:16
  • I took the package into a new test app just to use it there, and it worked there fine. I also tried to create a new package in the original app just to see if I can access its storyboards, and it worked fine too. It means something bad not letting the original app to access the package's storyboard I don't know what it is, so I just created a new package with the same name and copied the classes and code, then it worked fine. – fullmoon Nov 11 '21 at 16:22