How to avoid Redefinition of 'Category' as different kind of symbol error in Xcode

I got a weird error in Xcode 5.1 today while developing a Mac App which serves as a data entry tool for an iOS app: Redefinition of ‘Category’ as different kind of symbol. The weird thing is that the Mac App builds and runs fine, but when I import the model over to iOS I get an error at compile time:

Screen Shot 2014-05-08 at 19.09.19

The puzzle’s solution lies in something called “Namespacing”. Not that I even remotely care or pretend to understand this, but in a nutshell it means that the name Category is reserved and already defined in /usr/include/objc/runtime.h:

What that file is or where it comes from will forever remain a mystery to me, just like why it’s not a problem in a Mac App. I could probably try to figure this out for the rest of my days but really: life’s too short as it is. Let’s just

  • rename the Category entity
  • regenerate all NSManangedObject sub classes
  • remember Category as an evil string for the future

and be done with it. Note that you must rename the Entity as well as the Class it creates, and for good measure re-create all your NSManagedObject subclasses:

Screen Shot 2014-05-08 at 19.27.39

I guess that’s why at the beginning of a new Xcode project we have the option to prefix all our classes (which would undoubtedly avoid such problems in the future).

For those who care:

How to populate an NSTableView in code

I’ve previously shown you how to populate an NSTableView using Bindings and an array controller. Today I’ll show you how to do it in code.

It’s relatively simple and very similar to powering a UITableView. The main difference is that in Cocoa we don’t have a controller object that comes bundled with our view, so we’ll have to create one manually (or use an existing class). Here are the steps:

  • add an NSTableView to your XIB file
  • create a controller class based on NSObject (I’ll call mine TableController)
  • drag an NSObject object into the XIB (that blue box)
  • associate it with your custom controller object (i.e. TableController)
  • set the data source and implement its methods

Screen Shot 2014-05-04 at 11.22.52

In this example I’m using the numbers 1-10 in two arrays: as numbers, and as written out values – so that two columns of the table view can be populated with different items.

Next we’ll implement the following two methods: the first for returning the number of rows, and the second for returning the relevant data in each row:

Notice that in the second method we’re not referencing the columns with a number (like we do with rows). That’s because the user could reorder or remove columns. Instead we’re using the column identifier which you can set in IB.

Reacting to selections

If you want to react to user selections in your code you need to implement the NSTableViewDelegate Protocol and also connect your table view’s delegate to the above class. Then simply implement this method and you’re notified when a user clicks a row:

Unlike in iOS, we’re not directly passed the table view object – but we can grab it from the notification. Note that the log message will be off by one because the rows start at 0 rather than 1.

Demo Project

Here’s a demo project with the above steps implemented:

Watch the full course in one convenient playlist:
Catch this episode on my iOS Dev Diary Podcast:

How to remove focus from an NSTextField

Sometimes you need to make your text field give up first responder status, and therefore end editing. You’d think that – looking at the NSControl Class Reference – we should call something along the lines of validateEditing or abortEditing. But that doesn’t work.

Instead, we can set our text field’s window to “no first responder”. This approach works with any NSControl element:

This approach is similar to telling a UITextField to resignFirstResponder (the old “invisible button to dismiss the iOS keyboard” ploy).

How to create pop-up help for your own code in Xcode 5

Screen Shot 2014-05-03 at 11.17.05You know this super helpful feature that displays pop-up help windows in Xcode? The one I always forget is there? CMD-Hover over a method you’re calling and something like the above window is displayed. For Apple’s own code it even features links to the documentation.

We can do this in our own code as well using Doxygen style comments. Just above your own methods, add the following comment style block:

Now CMD-Hover over this method and that lovely box is displayed – it works anywhere you call it, even in different classes. This makes it a really useful feature, especially when you’ve forgotten how and why you’ve constructed code several moths down the line.

The parameters in those comments don’t need to be in order, Xcode will parse them no matter if @brief is at the top or @author is at the bottom. Empty lines don’t matter either, but they’re easier on the eyes.

The whole block is enclosed in standard /* multiline */ comments. The asterisks at the beginning of each line are not necessary either. Add one of the @ short codes on a new line, followed by your definitions. Some of the helpful ones are:

  • @brief – optional summary
  • @author – the author of the function, great for collaborative code (optional)
  • @param – input parameter (the first word right after is assumed to be the type)
  • @since – since which version this method is available (optional)
  • @code and @endcode – give a brief usage example that’s formatted as a code block (optional)
  • @see – adds a bold formatted “See Also” comment (optional)

I’m sure there are others, but I haven’t found any Apple documentation on those yet. Explore and document!

And check out Phil Beauvoir’s article for more tips on how to make this work for code completion:

This is one of those features that I wish Apple would tell you about. Perhaps in their… what’s it called.. documentation?

How to create an Alert View in Cocoa

Much like a UIAlertView, you can run an NSAlert on Mac like this:

Or, if you prefer a much simpler one-liner you can use NSRunAlertPanel:

Your App Icon will be displayed in the window. Here’s an example:

Screen Shot 2014-05-01 at 18.20.43

The result will be the same: a separate modal window is brought up, waiting for the user to dismiss it with any of the buttons. The latter method will return an NSInteger to indicate which button was pressed.

Alert Sheets

Instead of the Alert Panel, we can also run an Alert Sheet. The functionality is the same, but instead of being a floating window the Alert Sheet is attached to your main application window. This is what it looks like:

Screen Shot 2014-05-03 at 10.10.31

You can create Alert Sheets like this:

The above method relies on a delegate to be called so you can evaluate which button was clicked. Alternatively – if you prefer blocks and evaluate the result right there and then – you can call the Alert Sheet with

How to open a URL in Safari (on Mac in Cocoa)

Similar to UIApplication, we can use NSApplication to open a URL on Mac. This will launch Safari automatically:

Apparently this method returns a BOOL to indicate success of the operation. Note that this is does not indicate success at all, because as long as Safari can be launched, this will return YES – no matter if the URL can be displayed or not.

Test for internet connectivity before use (for example with Tony Million’s Reachability).