How to create a macOS Project without Storyboards in Xcode 8

Since Xcode 7 we can now use Storyboards for the development of macOS apps. While that’s a welcome addition, not everything works as straightforward with macOS and Storyboards as it once did without them (Cocoa Bindings for example is still a huge mystery to me).

In Xcode 9 we have once again a choice when starting a new macOS Project, a simple tick box we had lost over the course of Xcode 8 and Xcode 7. For those of us who are still looking at Xcode 9 as “a little bit beta” and still like to work with Xcode 8, here’s a quick guide on how to create a new macOS project from scratch using good old fashioned XIB files with Xcode 8.3.3.

Let’s go through this process step by step, as we’ll have to do the whole setup manually. It’ll be very exciting, and a nice exercise, I promise!

Create a new macOS / Cocoa Project

In Xcode 8.x, head over to File – New, and under macOS, select Cocoa Application. Give it a name and save it somewhere. Note that you do not get a choice of using Storyboards – it is implied that you want them at this point.

Now we’ll see in the Project Navigator that under General – Deployment Info, our Main Interface is set to something called Main. This refers to Main.storyboard, which is the default Storyboard that has been created for us. Let’s just make a mental note of that here, because we’ll have to change this manually later.

Create a Main Menu

XIB apps use two components: a Main Menu, which refers to the standard macOS App Menu Bar (the one that reads File, Edit, View, etc), and at least one Window with a view. Let’s create that manually by heading over to File – New, and under macOS – User Interface, select a Main Menu. I’ll call mine MainMenu.xib as the default suggests and save it in the suggested default location, together with all my other project settings.


Click on your new MainMenu.xib file and you’ll see it open up in InterfaceBuilder.

Create a Window

Still in Interface builder, find the Object Library on the bottom right and search for a Window. Drag one into your MainMenu.xib file and strategically position it somewhere underneath the menu bar.

To see if our app can actually do anything in a moment, and while you’re still here, search for a button and put it at the very bottom of our Window. This will actually be placed inside a View, which is conveniently delivered with our new Window.

You’ll end up with something like this:

 

 

Load your XIB at App Launch

We’re nearly there: all we have to do now is to tell our app NOT to load the Main.storyboard file anymore, and instead load our own MainMenu.xib.

To do that, head over to your Project Navigator, select your Target, and under Deployment Info, choose MainMenu.xib.

For those of us who don’t quite understand the last sentence:

  • the Project Navigator is the tab on the left side of the interface, resembling a File Manager
  • the Target can be accessed by clicking on the top blue icon with your project title on; these are your Project Settings. From here, select your Target with the dropdown menu on the second row, next to the word “General” in the screenshot above
  • Deployment Info is in the third section from the top under the word Deployment Target.

Launch the App and see what happens

At this point, and if you’ve done everything right, you should see your app launch with a single window and a single button. None of it will do much yet, but the menu bar should work and disclose some items. That’s a good start!

Let’s add some action by writing out a simple log message that is displayed if someone presses that ominous button we’ve added. Perhaps we’ll add some code to our AppDelegate.m file first:

- (IBAction)saySomething:(id)sender {

    NSLog(@"Hello from the AppDelegate!");

}

Add this before the @end line. Now let’s hook it up in our MainMenu.xib file. To do that, we need a graphical reference to our AppDelegate. Find an NSObject in the Objects Library, then drag it underneath all the other Objects we have in Interface Builder.

With it selected, choose the Identity Inspector on the right and type AppDelegate into the Class Field (this should auto-complete).

Now we can hook up our Button to the code we’ve written by CTRL-dragging from the button to the AppDelegate Object. We should get a pop-up window, in which we can now select our method, aptly titled “saySomething”.

Our app will already work at this point: when you launch it and press the button, Xcode will display a nice log message saying Hello from the AppDelegate.

Just one more thing…

As a final touch, and to setup the project exactly like the old-style Apple template (and Xcode 9 “no storyboard version), CTRL-drag from the Window object to the AppDelegate object and select “delegate”. This means that any messages sent from the Window and any objects inside it are received by the AppDelegate, who can then react to such messages (it’s equivalent of calling self.something.delegate = self in AppDelegate.m).

Happy Hacking!





Leave a Reply