From the blog

Swift Mistakes I’ve Made – Learning Swift Best Practices

I was busy working on Objective-C apps when Swift came out, and as a result I didn’t really sink my teeth into a Swift project until well after Swift 2 was released. Even though I’ve been keeping up with Swift blog posts, my First Swift app was a port of an old and crusty Objective-C code base, and I carried over a lot of old habits. In looking back over it, I found many small- to medium-sized changes that make the code cleaner and more Swifty. Maybe I can help you avoid similar mistakes.

Use (Private) Extensions for Protocol Conformance

In Objective-C, it was common to declare all your protocol conformances in your interface (public or private, depending on what you’re doing), and then label each section of the code with a comment or #pragma mark :

There are a few problems with this approach. The implementation of the class becomes sprawling, because logic related to your different conformances are all lumped in together. There’s also nothing enforcing that your methods will remain separate: a copy/paste mistake could cause your code from different protocols to become intertwined.

Also, those #pragma mark - UITableViewDataSource lines aren’t enforced by the compiler. I had a protocol whose name I had changed, and I forgot to update the comment, so I had a hard time finding the spot where its method were during a later refactor. Swift to the rescue!

Sadly, you can’t make protocol conformances private, but otherwise you should be using private extensions wherever you aren’t required to make them public.

Use Private Extensions for Private Methods

A similar Objective-C-ism is to put a #pragma mark - Private section at the bottom of a class, and stick all your private and utility functions there. This has similar problems to the previous section: if you’re not careful, your private methods can easily get mixed in with your public ones. You can put your private methods in a private extension, and you’ll never accidentally leak them to your public interface:

Consider Your Options

It’s pretty easy, coming from Objective-C, to imagine some uses of Swift optionals. However, when looking back over my code, I found some patterns I had written early on that could have been better. Here’s an example:

You usually don’t need to compare FOO != NIL

If you find yourself doing this, consider whether there’s a more idiomatic way to solve the problem. I originally had ported over some NSUserDefaults code like this:

Forced unwrapped optionals? Asking for the same object from NSUserDefaults twice‽ We can do better. We can’t use integerForKey directly, since it returns Int(0) instead of Int?() if the key is not present, but we can use conditional type casting ( as?) with objectForKey to get the same result, and turn the above into a more concise and efficient one-liner:

There are certainly cases where direct comparison to nil are appropriate, but Swift’s language features make it pretty rare in my experience.

Overridden Setters Aren’t Scary

In Objective-C, overridden property setters are a place where the language’s C roots start to show. You have to access the property’s backing ivar directly. In this case, I was trying to clamp a value to the range [0…2π):

My original Swift implementation looked pretty similar (I already have twoPi defined elsewhere):

This is pretty ugly, with the _theta and the boilerplate overridden getter. But of course, like so many common tasks from Objective-C, Swift provides a much cleaner way to do it at the language level. Near the bottom of the Properties section of the Swift documentation, they show a similar example of how to clamp the value of a property when it is set. It looks like this:

It’s so much cleaner now! The boilerplate is gone, leaving the actual meat of the code ( theta % twoPi) much more visible. It’s also harder to screw up an overridden setter that you never had to write in the first place.

Put Utilities in Their Own Files

This one isn’t unique to Objective-C, but it’s even more powerful in Swift. Since you can extend any type, it’s convenient to make extension files for your utilities on CGRect, CGPoint, UIInterfaceOrientation, and other types that couldn’t be extended when they were lowly C structs. So don’t litter your main code files with one-off domain-specific utilities on system types. Put them in a separate file and write a couple of unit tests just for that file. By breaking down your code into smaller, more testable chunks, you’ll gain greater confidence that the code as a whole is working as intended.

Leave a Reply

Your email address will not be published. Required fields are marked *