Avoiding Dropdown Haystacking by Adding IBOutlet prefixes to speed up development time

I have reluctantly added another definition to my personal Swift glossary. Its an anti-pattern called “Haystacking” which is….

HayStacking — trawling through the variety of Xcode drop downs trying to find a variable or outlet that can you kind of remember the name of.

Like other anti-patterns it:

  • wastes time,
  • takes away the joy of coding
  • and creates bugs.
  • again is slooooow to do — especially if you are a victim of a Xcode SourceKit crash in the process

Problem: Too many options when selecting from AutoComplete Dropdowns in Xcode

I personally have found that Xcode:

  • has way too many options when suggesting autocompletes ( this has increased exponentially since it also started suggesting images) When I come back to an app, it takes me a while to remember what outlet was called what.
  • It takes ages to find the name of an IBOutlet that I want to update especially if there are multiple ways to call it. eg did I call it NameLabel, or FirstNameFieldTitle. I sometimes have to scroll back up the pages to recall what the name is, or sometimes use a storyboard open in a second pane which slows things down.
  • Sometimes I want to see a list of just the labels — and currently this isn’t possible ( as far as I am aware)
  • If you are an advocate of using ViewModels (and ❤️MVVM❤️) — then I find its also handy to not have to keep switching to another file, to make sure I have covered all the view use cases.

Solution: Add type prefixes to the titles for your IBOutlets to let Xcode help you!

Edit:

  1. Thanks to a few people reaching out and letting me know that the syntax that I am recommending is actually called “Apps Hungarian” or “Hungarian Notation” which was originated by ex-Xero PARQ engineer, and former chief of Microsoft Engineering Charles Simonyi ( he also was also the 5th space tourist)

My solution for above is really simple which is adding type prefixes to the title for each of the outlets.

eg:

@IBOutlet weak var namesInTitleLabel: UILabel!

becomes

@IBOutlet weak var lbl_namesInTitle: UILabel!

and Xcode suddenly becomes a joy when you ask to see the list of all the labels in a view.

Image for post
It becomes a joy to get a list of all the labels in a view

Buttons Actions Vs Outlets is no longer a problem

One additional bonus I have picked up from doing this — is distinguishing an action from a outlet quickly even for outlets I hadn’t created. I noticed that people tend to name their UIButton actions and outlets similarly, which can cause issues.

I name all my UIButton Outlets with the “obtn_” prefix and the actions with the “abtn_”. This “double re-inforcement” has the side effect that I now never forget to click the dropdown to select the ‘action” in the dropdown when creating the action for a UIButton via dragging.

This is what it looks like:

// No prefixes

@IBOutlet weak var refreshPhotoButton: UIButton!

@IBAction func RefreshPhoto(_ sender: UIButton) {

}

//with prefixes

@IBOutlet weak var obtn_refreshPhoto: UIButton!

@IBAction func abtn_RefreshPhoto(_ sender: UIButton) {

}

and again we can find the list of all the button outlets in one go:

Image for post
Getting a list of just the button outlets is easy!

I have built up a list of the following prefixes- which I find work pretty well, but if you chose to do something like this — make sure you have an agreement with your team/ company to standardise the prefixes that you use.

  • lbl_ — UILabel
  • obtn_ — UIButton Outlet
  • abtn__ — UIButton Action
  • vw_ — Custom View
  • sv_ — StackView
  • tbl_ — Tableview
  • act_ — Activity Spinner

Above has really made it so much faster and more enjoyable, and at least until Xcode finds away to bring out a list of only a certain set of classes when autocompleting. This simple tip above works a treat and makes working with Swift even more expressive and easy to use.

Edit: ( added after publishing in response to feedback)

  1. From the comments, I now realise that its equally possible to add the __lbl as a suffix and Xcode will pick it up it in its suggestions. This is perfectly valid as long as you remember to add in the suffix.

eg :

@IBOutlet weak var refreshPhoto_obtn: UIButton!

2. Some people are frowning on this approach, as apparently Apple prefers you to append the full control name to the variable. The problem with this approach is that you get some incorrect suggestions included alongside the correct suggestions, which take up more time.

eg: using label, the Xcode suggestion will favour the wording which starts with “label” as the first suggestion. It also shows up the class name directly below the correct suggested outlets, which can also be selected incorrectly.

Image for post

3. There are some people who suggest that devs shouldn’t use prefixes as Swift should read like English. I disagree on this point, I personally think there are enough examples where Swift has chosen NOT to read like English in favour of features/ speed.

eg: (completion:@escaping (_ passedResult:Bool)-> Void) is very difficult to fathom

Given that Xcode is currently quite buggy with its speed of suggestions, whatever we can do to improve the speed in which we code is worth trying. Hopefully Xcode will improve enough that its easy to identify all the labels/ uibuttons quickly within a view controller, however until then — for me at least, prefixes are my preferred solution.