Swinject: Initialise default view controller, with initialiser, programatically with swinject

Created on 4 Mar 2018  路  5Comments  路  Source: Swinject/Swinject

I see that Swinject can initialise view controllers that have an initialiser without using SwinjectStoryboard. But I can't figure out how to initialise a default view controller programatically.

AppDelegate Container Setup

var container: Container = {
    let container = Container()

    container.autoregister(MyObject.self, initializer: MyObject.init)

    container.register(StartViewController) { r in
        return StartViewController(withMyObject: r.resolve(MyObject.self)!)
    }

    return container
}()

Controller with initialiser

class StartViewController: UIViewController
{
    private let myObject: MyObject

    init(withMyObject obj: MyObject) 
    {
        self.myObject = obj
    }

    // This method has to exist for some reason, because of my init above
    required init?(coder: NSCoder) 
    {
        fatalError("init(coder:) is not supported")
    }
}

Important points:

  • No storyboard is marked as "Is Initial View Controller", because I will decide this programatically at runtime
  • My controller has it's own initialiser
  • I do have the autowiring component imported
  • I would prefer not to use SwinjectStoryboard, but if I have to that's fine

I get the following error:

Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set?

What am I doing wrong, and how can I achieve what I want?

Most helpful comment

I'm glad you got it to work 馃憤 - and really appreciate the feedback 馃槃 That's what keeps the motivation up 馃槈

All 5 comments

The error message suggests that you still have Main.storyboard defined as a default interface - check General > Deployment Info > Main Interface, or Info.plist file.

Common pattern to explicitly define initial view controller is something like:

func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {

        let window = UIWindow()
        window.makeKeyAndVisible()
        self.window = window

        window.rootViewController = container.resolve(StartViewController.self)

        return true
    }

I'm linking this through to https://github.com/Swinject/SwinjectStoryboard/issues/83.

Many thanks for your container.resolve on the view controller, worked perfectly. Here's my container configuration:

container!.register(MyViewController.self) { r in
    let c = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MyViewController") as! MyViewController

    // Resolve any extra dependencies and add them to c then return c
    return c
}

I'm now using the above to create my view controllers instead of SwinjectStoryboard and I have no issues, and I can even inject other VCs that I will segue to into the main VC.

Thanks a lot for this awesome set of libraries and contributing something important to OS Swift, if I ever see you at a conference I owe you a beer! :)

I'm glad you got it to work 馃憤 - and really appreciate the feedback 馃槃 That's what keeps the motivation up 馃槈

ok

does not work bro

Was this page helpful?
0 / 5 - 0 ratings