My Opinionated Swift Style and Rules
Inspired by a Twitter thread on writing clearer code I wanted to write down my own style and rules that I follow when writing Swift.
As someone that struggles with reading in general (my dyslexia report states a very low score for comprehension) I find terse and
I want to preface this post by saying that these are my opinions and I do not try to force them on anyone I work with.
When in doubt: whitespace
Since there aren’t any automated formatters for Swift that integrate cleanly with Xcode I find it hard to
Indent to show scope
guard let firstName = form.firstName, let lastName = form.lastName else { return nil }
guard let firstName = form.firstName,
let lastName = form.lastName
else { return nil }
func doSomething(price: Decimal,
quantity: Int,
name: String) {
// Do something
}
Verbosity > Compactness
Using `$0`
Never use $0 unless it’s on the same line as the opening { for the closure. Looking at the following it’s impossible to know what $0 is:
if $0.price > 0 {
return "\($0.price)"
} else {
return "Free"
}
}
We know it’s returning the price something, but it could be anything: a product, a shipping option, a service, etc.
This is much clearer with the name:
if shippingMethod.price > 0 {
return "\(shippingMethod.price)"
} else {
return "Free"
}
}
Now we know this is a shipping method and not “something with a price.”
Multiple `guard`s or `if`s
I have seen increadably long single-line guards similar to:
guard let firstName = form.firstName, let lastName = form.lastName, let email = form.email, let message = form.message else { return nil }
Not only is this very long but a lot of the information is lost.
One way to improve this is to at least break it up on to multiple lines:
guard
let firstName = form.firstName,
let lastName = form.lastName,
let email = form.email,
let message = form.message
else { return nil }
It may be more code to write but it’s both easier to read and debug when these are broken up:
Log Generously
I often include very noisy and verbose logs. This is primarily due to it being essentially impossible to debug an issue that has just occurred without any logs; there’s no timetravelling debugger for Swift and most bugs have you thinking “huh, that should never happen!”
There are 2 fairly big downsides to this: Xcode has quite poor log filtering, and debug and info logs are discarded by the iOS simulator without changing the settings.
I would love for Console.app to be built in to Xcode in some way, although that wouldn’t solve this compeltely.
Console.app Sidebar
Console.app could be so good but it’s missing a major feature: the ability to share/save filters. If I want to share a filter set with another developer or across multiple computers I have to write down how to create the filter. There’s no share option and copy/pasting only works on the computer it was copied from because the filter field uses a custom pasteboard data type.