@RayWenderlich has just published a Swift Style Guide update or April, covering Swift 1.2 which was just released from beta a few days ago.
Multiple Optional Binding
Swift 1.2 now allows you to optionally bind multiple things in one line. Our style guide recommends using this new style, rather than the old style of multiple if let statements:
// old if let widget = widget { if let url = options.url { if let host = options.host { // widget, url, and host are all non-optionals } } } // new if let widget = widget, url = options.url, host = options.host { // widget, url, and host are all non-optionals }
This new syntax lets you avoid the “pyramid of doom” when you had to test and bind several optionals.
So many spaces saved!
Note you can also include boolean conditions in your if let statements, which can make your code more concise as well.
Enumerations and Case
After a good amount of discussion, we formalized the style we were using in our tutorials: UpperCamelCase for enumeration values.
enum Language { case Swift case ObjectiveC case ObjectOrientedFortran }
There’s a bit of an inconsistency since enum values are like class constants inside the enum scope, and feel like they should be in lower-camel case. However, the style guide usage matches our general practice, existing enumerations in Cocoa, and Swift itself – remember, optionals are implemented as enums with values Some and None which begin with a capital letter.
Trailing Closures
Trailing closures are great for keeping the closure expression linked to its function call, without having to wrap them in the argument parentheses.
UIView.animateWithDuration(0.75) { self.dogeImage.alpha = 1.0 }
Our old guidance was to use trailing closures wherever possible. However, there’s one special case where this isn’t a good idea: when there are two closure arguments! In that case, you should use the normal syntax to keep both closure expressions “on the same level” with named arguments:
UIView.animateWithDuration(1.0, animations: { self.myView.alpha = 0 }, completion: { finished in self.myView.removeFromSuperview() })
The alternative is to have one named and one trailing, which looks strange and we recommend against.
// Don't do this! UIView.animateWithDuration(1.0, animations: { self.myView.alpha = 0 }) { f in self.myView.removeFromSuperview() }
Function and Method Naming
As in Objective-C, a full, unambiguous function signature includes the method name and its named arguments. When referring to a function in a tutorial, we follow the same formatting as you see in the Xcode jump bar:
Previously, we said it was OK to write just the bare function name if the context was clear. That allowed us to write viewDidAppear rather than the full viewDidAppear(_:).
After some discussion, we decided it was best to be clear about whether something was a function or a variable. The new guideline is to always include the full signature. That means something like viewDidLoad() where there are no arguments, and tableView(_:cellForRowAtIndexPath:) where there are arguments.
MARK
In the last style guide update, we introduced the rule of one extension per protocol. That keeps the protocol conformance together with the protocol methods, and makes adding and finding related code easier.
As an addition to that rule, we want to start adding MARK comments to provide better navigation.
// MARK: - UITableViewDataSource extension MyTableViewController: UITableViewDataSource { // table view data source methods here... }
Extensions are great for grouping methods together, and the MARK comment should help navigating your way around source files even easier than before!
Code flows out much easier when your files are well organized!
Shadowing
Speaking of optional binding, one thing that hasn’t changed in the style guide is that we use the same name for the optional and the unwrapped version:
var subview: UIView? // later... if let subview = subview { // referring to "subview" here is the unwrapped version }
The benefit is that the names remain short and we avoid things like maybeView and unwrappedWidgetand optionalTableView. Once you understand Swift and optionals, the code makes sense. The downside is that the code just looks strange and can be hard to read and understand for beginners.
The issue thread on variable shadowing is still there and we’re open to change things if you’re especially convincing. “Especially convincing” includes offers of an Apple Watch Edition, of course. ;]
You can also follow the style guide updates on their official Github page, at: https://github.com/raywenderlich/swift-style-guide.