You’ve been working on your billion dollar app happily for days or weeks. It’s Monday morning, you open up Xcode 9 to get back to work and — dang, bummer — all your
IBAction connections look like they’ve been disconnected (see image below):
Note that I’ve seen this happen mostly with large Objective-C projects, but look at the image above. I threw together a
Single View App project, with Swift as the language, just for the purposes of writing this article. After closing the project and reopening it, all my
IBAction connections look like they’ve been disconnected. To make matters worse, when Xcode 9 is in this state, you can’t create new
IBAction connections. Oy vey ist mir!
Generally, the outlets and actions haven’t really been disconnected. This is just another happy, happy, joy, joy bug from Apple. The Xcode user interface isn’t drawing (refreshing) the screen to show outlet and action “connection dots.” I’ll show you below.
(NOTE: I know this blog is called http://iosbrain.com/, but macOS development is very similar to iOS development. macOS developers are in demand, so you may want to look into creating a few practice projects. You never now when your employer or customer may ask you to “integrate that iOS app with our macOS desktop app.” I would recommend you look at some references to get started. Mac OS X and iOS Internals: To the Apple’s Core does a great job of highlighting the similarities and differences between iOS and OS X programming. Cocoa Programming for OS X: The Big Nerd Ranch Guide (5th Edition) (Big Nerd Ranch Guides) concentrates solely on macOS app development.)
I then created a new macOS project based on the
Cocoa App template, specified use of the Objective-C language, went into the storyboard, and dragged a bunch of checkboxes (
NSButton), text fields (
NSTextField), and [OK] and [Cancel] buttons (
NSButton) onto my
NSView. I arranged all these UI objects and finally wired up 16
IBOutlet connections and 2
IBAction connections for my checkboxes, text fields, and 2 buttons, respectively. See the following images:
I closed the project and then reopened it. Guess what. The
IBAction connections all showed as disconnected:
Look what happens when I open the storyboard and go to the Connections Inspector. All my outlets and actions are still there:
The fix for seemingly disconnected outlets and actions
Often you can get your outlets and actions to show as connected by moving files around in the Xcode IDE’s file editors. By this I mean: open the storyboard in the main Xcode window and then open the file containing the outlets and actions (.swift, .h, or .m) in the Assistant Editor. Then, switch the storyboard file to display in the Assistant Editor and switch the file containing the outlets and actions into the main Xcode window. Sometimes you have to go through this process multiple times.
If that still doesn’t work, shutdown and restart Xcode and do the file shuffle as I explained above. If that doesn’t work, try closing and reopening the file containing the outlets and actions over and over until the
IBAction connections show up.
This can be really frustrating and I’ve had to try fixing things for up to 10 minutes. Don’t think that upgrading from Xcode 9.0 to 9.1 or 9.2 will help, as I’ve seen this happen in all three versions (as well as in older versions of Xcode).
Manually creating actions and outlets
Did you know that you can create an
IBAction connection “manually,” using the keyboard and the mouse? Oftentimes, when you’re in this seemingly-disconnected-outlets-and-actions hell, you can’t always create an outlet or action by [control]-dragging from the UI object into code. Let me show you the manual workaround:
You see what I did, right? I typed an
IBAction into the
@interface section of my
When I finished typing and wrote a correctly-formed action, Xcode recognized the new line of code as an
IBAction. It placed a “connection dot” next to the action. All’s I had to do was to click into the “connection dot” and drag to the target
NSButton in the storyboard. Remember that when Xcode is functioning normally, if we create an
IBAction in an Objective-C .h file, Xcode automatically creates the body of that action in the .m file. In this manual scenario, we have to create the
IBAction method body manually in the .m file.
I could then add code to clear out (empty) all text in the
NSTextField objects in my NSView, like so:
self.text1.stringValue = @"";
self.text2.stringValue = @"";
self.text3.stringValue = @"";
self.text4.stringValue = @"";
self.text5.stringValue = @"";
self.text6.stringValue = @"";
self.text7.stringValue = @"";
self.text8.stringValue = @"";
Here’s my manually-wired
IBAction for the “Reset” button in action:
I hope you’re not too put off by Xcode 9’s bevy of bugs. It actually has some nice new features, and with Apple’s High Sierra disaster, iOS 11 disaster, slowing down older iPhones, etc., I hope they’ve learned some humility and gained a greater appreciation for their customers and all the people who create products within their ecosystem.
We started today with a bug, ended up learning about manually creating actions and outlets, and did some macOS programming (which may be totally new to many of the iOS developers out there). Thanks for reading my posts! Come back soon.