Dependency Injection in View Controller

2019-07-02 20:58发布

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

2条回答
女痞
2楼-- · 2019-07-02 21:47

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

查看更多
我想做一个坏孩纸
3楼-- · 2019-07-02 21:56

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.

查看更多
登录 后发表回答