kylejs
kylejs

Reputation: 1128

AppDelegate instantiated last on launch

I'm very comfortable with writing iOS apps, but OS X unexpectedly seems somewhat alien.

Here's the question upfront (read on for context):

When my application launches using the .xib set in the Main Interface field under the deployment info of my apps target, why does the AppDelegate get instantiated after the ViewControllers?


Context (no pun intended):

The reason I ask is because I'm using Core Data (spare me any heckling for this decision), and typically you keep a pointer to the MOC (Managed Object Context) in AppDelegate. One of my controllers is trying to get this MOC instance variable but the AppDelegate instance isn't around yet and therefore my app doesn't present data just after launch.

The AppDelegate and the two ViewControllers are in the .xib. The VCs are hooked to views inside a split view. They're trying to use the MOC in viewDidLoad to make queries. They are accessing the AppDelegate like this:

let delegate = NSApplication.sharedApplication().delegate as AppDelegate
let moc = delegate.managedObjectContext

This will crash as the .delegate property of the sharedApplication() returns nil.

I tried making an NSWindowController from the .xib in applicationDidFinishLaunching and removing the .xib from the Main Interface field, but then applicationDidFinishLaunching doesn't get called at all.

I've ensured that all the connections in IB for from the Application and the Files Owner (NSApplcation) delegate IBOutlets to the AppDelegate have been made.




UPDATE - 31/03/15

Stephen Darlington's answer below offers a good solution for my/this case. And as I understand it's actually better to setup the MOC in the way he's suggested.

If a correct answer arrives that explains why the AppDelegate is being instantiated at some later time in the launch process, I'll mark it correct instead of Stephen's. Thanks Stephen!

Upvotes: 1

Views: 159

Answers (3)

kylejs
kylejs

Reputation: 1128

Here's another option without having to subclass NSApplication:

  • Don't put your view controllers in the .xib that you set as the Main Interface, just have the Main Menu (menu bar), AppDelegate and Font Manager in there.
  • Then make your view controllers in other .xibs.
  • Then in the applicationDidFinishLaunching method init your view controllers from their .xib files.

Upvotes: 1

kylejs
kylejs

Reputation: 1128

I also faced this issue with setting up Parse. To get around it, I simply subclassed NSApplication and set it as the Principle class in the Info.plist. In your NSApplication subclass, override the init methods and initialise Parse or anything else you need to, there.

Upvotes: 0

Stephen Darlington
Stephen Darlington

Reputation: 52565

The "easy" solution would be to have managedObjectContext create a MOC if one doesn't exist (i.e., change it from a property to a method). That way which ever code gets there first the stack will be available.

(I'll spare the lectures about both creating the Core Data stack in the app delegate and accessing the app delegate like that!)

Upvotes: 1

Related Questions