Naming in Swift Part 3: Boundary Words
With the introduction of async/await to Swift, this article may have already aged poorly. In fact I wrote the first draft of this for Objective-C, before Swift even existed!
There are some words that appear in pairs through Swift APIs:
start
andstop
start
andfinish
begin
andend
I am calling these boundary words, as they delimit the boundarys of certain actions, events or processes.
Although theses words are considered synonyms of each other in plain English, they take on distinct semantics and should no longer be considered synonyms in Swift.
Furthermore, due to this specialisation, there are certain pairings that make sense and some pairings that you don't see as often.
For example, you typically won't see start()
paired with end()
, nor begin()
with finish()
even though these constructs would be perfectly fine in ordinary English.
About start and stop
APIs use start and stop to convey a long-running task that is happening in human-perceivable time.
Here are some examples:
URLProtocol
hasstartLoading()
andstopLoading()
AVCaptureSession
hasstartRunning()
andstopRunning()
UIImageView
hasstartAnimating()
andstopAnimating()
Things that can be stopped can usually be started again. This means the object will have state.
Where you see startPerformingTask
and stopPerformingTask
you often also see isPerformingTask
.
About finish
Sometimes start is paired with finish.
Here are some examples:
AVAssetWriter
hasstartWriting()
andfinishWriting(completionHandler:)
PHContentEditingController
hasstartContentEditing(…)
andfinishContentEditing(completionHandler:)
Unlike stop, finish is not simply the opposite of start. It specifically denotes that there is some sort of final phase to the task. For example, flushing the contents of a buffer, writing to the disk, or cleaning up resources.
About complete
You see APIs with complete when they have completion handlers. The concept of completion specifically denotes the boundary of the task between the caller and callee.
Here are some examples with both finish and complete:
AVAssetWriter.finishWriting(completionHandler:)
HKWorkoutBuilder.finishWorkout(completion:)
In these APIs, finish is refering to the final phase of the task that needs to be performed before control is transferred back to the caller in the completion handler.
About begin and end
These pairs normally appear within the same lexical code block, and are used to group operations into batches, transactions or other constructs.
Here are some examples:
UITableView
hasbeginUpdates
andendUpdates
MTLCaptureScope
hasbegin
andend
OSSignposter
hasbeginInterval
andendInterval
These APIs were much more common in Objective-C prior to the introduction of block syntax. In Swift these would be good candidates to improve using closures.
Counter-examples
When writing this I did find a lot of examples in Apple's APIs that contradicted my definitions above.
For one, in the Swift Standard Library, collections have a start index and end index.
These definitions aren't hard rules, but I believe they are more consistent than not and that makes them worthwhile to know. Many design patterns that have corresponding vocabulary already defined. If possible, why not use a common vocabulary — it will only make your APIs feel more at home.