dicle
dicle

Reputation: 1152

Dependency Injection in View Controller

I am trying to use dependency injection instead of following singletons. This is how I am trying to achieve. When I run the application I am having an error on "No "decodeObject" candidates produce the expected contextual result type "ModelManager" on that. Any idea how can I implement dependency injection in a right way?

My Model class:

class ModelManager {
var results: MyCustomClass

init(results: MyCustomClass) {
    self.results = results
}
func update(customDataInfo: MyCustomClass!) {
    self.results = customDataInfo
}
}

MyViewController.swift

class MyViewController: UIViewController {

private let modelManager: ModelManager

init(modelManager: ModelManager) {
    self.modelManager = modelManager
    super.init(nibName: nil, bundle: nil)
    self.modelManager.modelManagerUpdate = self as ModelManagerUpdate
}

 required init?(coder aDecoder: NSCoder) {
    self. modelManager = aDecoder.decodeObject(value(forKey: "modelManager") as ModelManager)
    super.init(coder: aDecoder)

    fatalError("init(coder:) has not been implemented")
}

override func encode(with aCoder: NSCoder) {
    super.encode(with: aCoder)
    aCoder.encode(self. modelManager, forKey: "modelManager")
}
}

Upvotes: 5

Views: 3341

Answers (2)

Jakub Vano
Jakub Vano

Reputation: 3873

The fact that the init?(coder:) initialiser is being used suggests that your view controller is initialised from storyboard. If that is the case, storyboard does not contain ModelManager, thus it cannot decode it.

You can work around this by wrapping storyboard initialisation into your own method, e.g.:

class MyViewController: UIViewController {
    private var modelManager: ModelManager

    static func create(modelManager: ModelManager) -> MyViewController {
        let vc = /* instantiate vc from storyboard */
        vc.modelManager = modelManager
        return vc
    }
}

If the above method does not suit your needs, I would suggest you take a look at the SwinjectStoryboard framework. It provides - besides basic DI functionality - ability to inject dependencies to the view controllers initialised from storyboard.

Upvotes: 6

Bio-Matic
Bio-Matic

Reputation: 823

Why you call super.init(nibName: nil, bundle: nil)? in ViewController init method? Just call super.init() and it should fix.

Upvotes: 0

Related Questions