iosswiftstoryboardswift-package-manager

Not able to present UIViewController with its Storyboard in a Swift Package


I'm building a separate feature as a swift package. There is a view controller and its storyboard in the package. I'm having a problem instantiating and presenting the view controller. I get this error:

Could not find a storyboard named 'MyIdCardVC' in bundle NSBundle ...

Both MyIdCardVC.swift and MyIdCardVC.storyboard are added to the package.

Here is part of the Package.swift declaration:

let package = Package(
name: "IDCard",
platforms: [
    .iOS(.v11)
],
products: [ 
    .library(name: "IDCard", targets: ["IDCard"]),
],

I'm presenting the package's view controller from my app like this:

import UIKit
import IDCard
 
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let vc = IDCard.MyIdCardVC.getStoryboardVC()
        present(vc, animated: true, completion: nil)
    }
 
}

the "getStoryboardVC" is a static extension method declared in the package

public extension UIViewController{

public static func getStoryboardVC() -> UIViewController {

    let storyboard = UIStoryboard(name: String(describing: self), bundle: nil)
    return storyboard.instantiateInitialViewController()!
}

and here how the MyIDCardVC.storyboard looks:

enter image description here


Solution

  • I solved it by using Bundle.module when instantiating the storyboard's view controller. Bundle.module refers to the containing package:

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

    Then in the app, I present the package view controller like this:

       @IBAction func openCard(){
            let vc = IDCard.MyIdCardVC.getStoryboardVC() as! IDCard.MyIdCardVC
            vc.personNo = "11111"
            vc.personId = "8888888"
            present(vc, animated: true, completion: nil)
        }
    

    and in the storyboard, specify the module and uncheck Inherit Module From Target enter image description here