Hello everybody,
i just struggled a little bit when trying out your awesome database solution in one of my mac apps. According to your documentation one should migrate the Realm in applicationDidFinishLaunching but in my case it didn't worked. The app always crashed and i think thats due to the fact that i'm on OS X, not iOS and I'm using StoryBoards. My app is one window and therefore one ViewController. In the VC i use var bricks: Results<Brick> = try! Realm().objects(Brick).sorted("title") on class level so i can populate my NSTableView. Apparently the code gets called before applicationDidFinishLaunching gets called in the AppDelegate. My solution for now is to use a custom NSWindowController class in my StoryBoard in which i can migrate the database in init?(coder). Maybe you could mention this in the docs or is there maybe even a better solution? Is there any best practice to migrate in OS X apps?
Kind regards
Jan
In general you will want to populate the properties of your view controllers in viewDidLoad rather than directly initializing them. It's unfortunately a bit more verbose (and in Swift requires using implicitly-unwrapped optionals), but doing work on view controller construction tends to run into a lot of issues like this where it's constructed surprisingly early in the life cycle.
A little test shows that even viewDidLoad: of the NSViewController is called before applicationDidFinishLaunching: of the AppDelegate
Hi @xxtesaxx!
I actually had a VERY similar question to this one a while back (But for an iOS app), so hopefully I can help.
You are correct. On both iOS and OS X, if you let the application automatically handle the creation and display of an NSWindowController / NSViewController from a storyboard, the controller will be created and viewDidLoad will be called before [NSApplication applicationDidFinishLaunching:] is called.
Our previous solution to the iOS problem was straightforward: don't let the system handle the controller instantiation; do it yourself in code, at the end of the 'applicationDidFinishLaunching method, _after_ you've performed your Realm migration. That being said, this seems to be a bit trickier on OS X as it now relies on storyboards to a much heavier degree than iOS.
All you need to do inside the storyboard is find the initial NSWindowController and uncheck its Is Initial Controller checkbox.
Then, in your app delegate, manually present the window controller using something like the below code
@interface AppDelegate ()
@property (nonatomic, strong) NSWindowController *windowController;
@end
///
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
//Realm migration logic here
NSStoryboard *storyboard = [NSStoryboard storyboardWithName:@"Main" bundle:nil];
self.windowController = [storyboard instantiateControllerWithIdentifier:@"My Storyboard ID"];
[self.windowController showWindow:self];
}
Hopefully that'll work. Let me know how you go!
Alternatively, you can also leave the Is Initial Controller checked in your storyboard and use -instantiateInitialController while you make sure that your app doesn't automatically load your storyboard by removing the contents of the combo box in your project managers app target settings in the _General_ tab under the pane _Deployment Info_ > _Main Interface_ as seen below:

Hi @xxtesaxx! Did that work in the end? Were you able to properly line up Realm's migration before the view controller loaded in the end?
I'm going to close this issue now. If you require any follow-up, feel free to open this issue again. :)
Yes, the suggested way to do it is maybe even better than the solution i came up with (override init in NSWindowController) but the main intention was to ask if you could state the problem in your documentation. :)