I have a test project that I'm trying to pass an argument to the resolve method in a Swinject project.
Here is an example of what my Swinject storyboard extetion file has in it.
import Swinject
extension SwinjectStoryboard {
class func setup() {
let mainDm = MainDM()
defaultContainer.register(MainDM.self) { _ in
mainDm
}
defaultContainer.registerForStoryboard(ViewController.self) { r, c in
c.dm = r.resolve(MainDM.self)
c.container = defaultContainer
}
defaultContainer.register(GetMessageAction.self) { _, delegate in
GetMessageAction(dm:mainDm, delegate: delegate)
}
}
}
in my ViewController I'm trying to do the following to resolve the GetMessageAction
@IBOutlet weak var myText: UILabel!
var dm:MainDM!
var container:Container!
override func viewDidLoad() {
super.viewDidLoad()
NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(3), target: self, selector: #selector(ViewController.getMessage), userInfo: nil, repeats: false)
}
func getMessage() {
let action:GetMessageAction? = container.resolve(GetMessageAction.self, argument: self)!
action?.execute()
}
I get the following message when my getMessage function runs
fatal error: unexpectedly found nil while unwrapping an Optional value
As resolving with arguments is dependent on exactly matching types of arguments, you need to downcast passed object:
container.resolve(GetMessageAction.self, argument: self as GetMessageActionDelegate)!
Assuming that GetMessageActionDelegate
is the type of delegate passed in constructor GetMessageAction(dm:delegate:)
.
The swift file of the ViewController you have created in your Storyboard must declare init(NSCoder), it is actually not mentioned in the README.md, I'm thinking about opening an issue regarding this...
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
You can take a look at my open source project using exactly this technique, I am setting up the dependencies using the extension of SwinjectStoryboard here for example the LoadingDataVC.
extension SwinjectStoryboard {
class func setup() {
defaultContainer.register(HTTPClientProtocol.self) { _ in
HTTPClient()
}.inObjectScope(.Container)
defaultContainer.register(APIClientProtocol.self) { r in
APIClient(
httpClient: r.resolve(HTTPClientProtocol.self)!
)
}.inObjectScope(.Container)
defaultContainer.register(ImagePrefetcherProtocol.self) { _ in
ImagePrefetcher()
}.inObjectScope(.Container)
defaultContainer.registerForStoryboard(GameVC.self) { r, c in
c.imagePrefetcher = r.resolve(ImagePrefetcherProtocol.self)
}
defaultContainer.registerForStoryboard(LoadingDataVC.self) { r, c in
c.apiClient = r.resolve(APIClientProtocol.self)
c.imagePrefetcher = r.resolve(ImagePrefetcherProtocol.self)
}
}
}
Once you have the required init it should work! :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With