SwinjectStoryboard
SwinjectStoryboard copied to clipboard
Explicit instantiation for macOS apps
The README mentions you can do something like this in iOS apps to explicitly load your root view controller from SwinjectStoryboard
:
let window = UIWindow(frame: UIScreen.mainScreen().bounds)
window.makeKeyAndVisible()
self.window = window
let storyboard = SwinjectStoryboard.create(name: "Main", bundle: nil, container: container)
window.rootViewController = storyboard.instantiateInitialViewController()
Is there an equivalent practice for macOS?
I don't typically do OSX development, so can't comment on recommended practices. It would definitely be welcomed if someone well versed in OSX apps gave some pointers.
My current workaround is to let the app load via storyboard, and then call this method in applicationDidFinishLaunching(_ aNotification: Notification)
.
func setupWindow() {
let storyboard = SwinjectStoryboard.create(name: "Main", bundle: nil)
guard let window = NSApplication.shared.windows.first(where: { $0.delegate is MainWindowController }),
let mainWindowController = storyboard.instantiateInitialController() as? MainWindowController else { return }
window.windowController = mainWindowController
window.makeKeyAndOrderFront(self)
}
One thing to note though (not sure if this is a separate bug or a side effect of doing the above) but I'm noticing storyboardInitComplete()
is called after windowDidLoad()
. This behavior is different than on iOS, where they're called in the opposite order.
@mpdifran Hey i am not sure if I understand you correct but you can remove the storyboard from the Info.plist you need to add your own NSApplication
import Foundation
import Cocoa
class CustomApplication: NSApplication {
let strongDelegate = AppDelegate()
override init() {
super.init()
self.delegate = strongDelegate
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
and you need to add/replace this class to the info plist
<key>NSPrincipalClass</key>
<string>your_project_name.CustomApplication</string>
if you have a problem to get the correct project name just start your app and add this line somewhere in your project and you will get in the console your project name.
print(String(describing: self))
class AppDelegate: NSObject, NSApplicationDelegate {
private var storyboard: SwinjectStoryboard!
private var windowController: NSWindowController!
let container = Injections().container
func applicationDidFinishLaunching(_ aNotification: Notification) {
storyboard = SwinjectStoryboard.create(name: "Main", bundle: nil, container: container)
windowController = storyboard.instantiateInitialController() as! NSWindowController?
windowController?.showWindow(self)
}
}
Ah that's perfect. Thank you!