Latest Articles

Getting started with SwiftLint

There is nothing better than spending some time to sharpen the saw —and improve the way that I code my apps. By finding new ways to improve the code quality, or efficiency in which I write my code — it pays off big time in being more productive and heck it’s even a bit more fun.

For this week — it was a no brainer. I was chatting with my friend Jane yesterday- and telling her about SwiftLint and her reaction was… “this is awesome” and you should blog about it now.. so here it is.

So here we are….

SwiftLint is one of the new standard tools that I now spin up at the start of every project. This nifty tool is one of the few that will:

  1. Help you to write better code
  2. Make sure that your code is readable and understandable to others who need to use your code,
  3. and most importantly.. for those of you like me who are on a quest to get those Xcode warnings list down to zero — it encourages you to fix the code as you type and thus you have the weighty bonus of having your GitHub full of lovely compliant code.

What it does…

SwiftLint works by applying over 75 (and counting) rules which are roughly based on the Swift Style Guide.

The SwiftLint Rules

An examples of the rules that really helped me were:

  • Trailing_newLine — SwiftLint highlights and warns if you put too many whitespaces lines at the end of a class ( a bad habit I picked up- which is now happily cured) It shows up in Xcode as a regular warning when you try build.

The great thing about SwiftLint is that it’s super flexible. You have the ability to use

  • all the rules on your project
  • Some of the rules on your project
  • None of the rules on your project
  • Or even apply some rules to only some classes.

Heard enough ? Let’s try it.

How to use it

To install SwiftLint — you need to:

  1. Install it on your Mac via HomeBrew as my recommended choice: brew install swiftlint
  2. Add the following build script to your project:
if which swiftlint >/dev/null; then
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
Image for post
How to install SwiftLint

Then start building with CMD+B.

3. This is the most depressing part of the whole journey, when you zero error project suddenly generates a massive amount of warnings and errors. Don’t lose faith — we will fix them soon.

Below is an example from a project I use regularly called SWIFTCSV ( a CSV Parser which I am working on porting to Swift 4) where I went from zero warnings and zero errors to ….

Image for post
A very depressing number of errors after adding SwiftLint

The great news is that SwiftLint has a superb command line tool- which can automatically tidy up some of the errors for you (eg trailing line spaces)

4. Open Terminal and go to your project folder by dragging the project folder onto the terminal icon in the dock bar.

5. Run `swiftlint rules` to see what rules you have applied to your project

Image for post
A list of the swiftlint rules that were generating errors and warnings.

6. Run ‘swiftlint autocorrect’ which will try and fix the most common errors that it can. For me — it fixed a whopping 17 files straight away.

Image for post
Test result after running Swift Lint

The rest of the warnings and errors took me a mere 10 minutes, and I could already see the benefit for working with other peoples code, and also making sure that I play nice by giving others better code to use.

Is the tool any good ?

The tool was written by Realm, who have a wonderful simple to use database tool which I encourage you to try out. The team behind Realm have a focus on producing great Dev tools and the quality of SwiftLint is a great showcase for this.

SwiftLint tools rocks — go try it out now at the SwiftLint Github project

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.