Member-only story
Access control in Swift like a boss
Or, more specifically, like a Staff Engineer

I mostly post to Substack these days. Subscribe now to receive non-paywalled, ludicrously in-depth articles on iOS, Swift, and indie projects every 2 weeks.
I remember the day I first learned about the internal
access modifier when reading The Swift Programming Language.
At the time, I was coding a take-home test for a job at Revolut. I was desperate to show how clever I was for knowing this keyword (which is synthesized by the compiler automatically). Subsequently, like a puppy marking its territory, I sprayed internal
on every (API) surface I saw, in the hope that Storonsky-senpai would notice me.
Later, I worked with a… well, a Staff Engineer but because we were in consulting she was called “Senior Manager”. She’d modularised our codebase — a novel concept for me at the time — and our ModelKit
module was chock-full of properties marked:
public private(set) var somePropertyName: SomeTypeName
As intimidated as I was, I swore that one day I would be intelligent enough to wield access control keywords with the same finesse as she.
And one day, I was.
In order to protect the good people at Revolut from code snippets like the following abomination, I’m going to explain how to apply each access control level in Swift, and make you indistinguishable from the mighty Staff Engineer.
class CurrencySwapDataProvider: NSObject {
weak var tableView: UITableView? {
didSet {
registerCells()
}
}
internal var viewModel: CurrencySwapViewModel?
internal var currencyDelegate: CurrencySymbolDelegate?
internal var activeCurrencyCode: String?
// helper variable to flag the status of the data when intializing
internal var tableViewIsReady: (Bool, Bool) = (false, false)
internal func currencyDataUpdated() {
if tableViewIsReady.0 && tableViewIsReady.1 {
updateConversionRates()
} else if tableViewIsReady.1 {
reloadTableView()
}
}
/* ...
I hate to admit this is real-life code I submitted to Revolut circa 2017.