Just one week left till WWDC 2017! I am expecting much more power given to developers in SiriKit and a couple of surprises. I guess you are waiting for some new APIs too 😬.
The new Apple developer season is not only about APIs, OSes but also about Swift update. Swift 4 is coming. There are no big breaking changes, backwards compatibility will be ensured. Some neat things there. Ole Begemann has created a neat playground with all news.
private gets boost in Swift 4
Among all new features, one thing came particularly to my interest – visibility of private declaration in extensions in the same file (SE-0169).
About a year ago, in Issue #22
we have discussed, and complained a bit about the new fileprivate. As much as splitting implementation to extensions is considered a good practice, fileprivate was initially intended to be used rarely. In reality it was used a lot. We've had to update our code in around 200 places 😅.
But this will change with Swift 4. private declaration will be accessible in type extensions in the same file. This change concerns only extensions; subclasses in the same files are not in scope.
private in Swift 3 vs. Swift 4
Take a look at this sample code:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// ListViewController.swift class ListViewController: UIViewController { private let tableView = UITableView() private let items: [String] = ["Item 1", "Item 2", "Item 3"] // ... } extension ListViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count // Inaccessible in Swift 3 } //... } |
This code is invalid in Swift 3 as items is not accessible in extension. In Swift 3 items would require fileprivate However in Swift 4 this will be valid.
So what happens with fileprivate now?
It will stay, but will be used as intended – rarely.
Take a look at the following example:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
struct A { fileprivate var a: Int = 1 private var b: Int = 2 } struct B { private var c: A = A() } extension B { func foo(){ print(c.a) //accessible //print(c.b) //💥inaccessible } } extension A { func boo(){ print(a) //accessible print(b) //accessible } } B().foo() A().boo() |
Property a is marked with fileprivate so it will be visible even for other types within scope of this file.
However property b is marked with private so it remains restricted to its owning type extension.
Swift 4 access control diagram?
Well, our previous diagram remains valid. Just a bump in language version:

Summary & References
If SE-0169 makes it, fileprivate will have less prominent role. Luckily your Swift 3 code will continue to work, as fileprivate is now just a bit less restrictive than private. For me, in practice this means I will probably forget about fileprivate existence.