Swift fileprivate vs private

⋅ 3 min read ⋅ Swift

Table of Contents

Swift fileprivate and private

Swift has five access levels, private is the most restricted level and fileprivate is the second one.

  • fileprivate restricts the use of an entity to its own defining source file.
  • private restricts the use of an entity to the enclosing declarationand to extensions of that declaration that is in the same file.

In simpler words:

  • fileprivate entity is visible within the file it is declared.
  • private entity is visible within its declaration, e.g., struct, class.

It is easier to understand this with an example.

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

Example of private and fileprivate

As an example, we will create two files.

  1. A.swift
  2. B.swift

We create an A struct within A.swift. It contains both private and fileprivate variables.

// A.swift
struct A {
private var privateVar = 0
fileprivate var fileprivateVar = 1
}

If you can read private, you can read fileprivate

We can access the private variable from within its declaration and extension within the same file.

The following code will work.

// A.swift
struct A {
private var privateVar = 0
fileprivate var fileprivateVar = 1

// 1
func readInA() {
print(privateVar)
print(fileprivateVar)
}
}

// 2
extension A {
func readInExtensionA() {
print(privateVar)
print(fileprivateVar)
}
}

1 We can read a private variable within its declaration. In this case, an A struct.
2 We can also read a private variable from an extension in the same file.

The fileprivate access is less restricted than the private one, so we can also read fileprivateVar if we can read privateVar.

The difference

The case which differentiates private and fileprivate access is when we try to access them from outside its declaration (Outside struct A) but still in the same file.

Here is an example where we try to access both privateVar and fileprivateVar.

  • From outside its declaration (NotA struct).
  • In the same file (A.swift).
// A.swift
struct NotA {
let a: A
func readOutsideA() {
// 'privateVar' is inaccessible due to 'private' protection level
print(a.privateVar)

// You can read `fileprivateVar` here.
print(a.fileprivateVar)
}
}
  • fileprivateVar is still visible outside the A struct because it is still in the same file of its declaration.
  • privateVar is not visible because we try to read it from outside its declaration.
'privateVar' is inaccessable due to 'private' protection level.
'privateVar' is inaccessable due to 'private' protection level.

You can't read it outside the defining file

You can't access either private or fileprivate outside its defining file.

So if you create a new file, B.swift. You cannot access either private or fileprivate.

The following code will be failed.

// B.swift

struct B {
let a: A
func readInB() {
// 'privateVar' is inaccessible due to 'private' protection level
print(a.privateVar)

// 'fileprivateVar' is inaccessible due to 'fileprivate' protection level
print(a.fileprivateVar)
}
}

extension A {
func readInExtensionB() {
// 'privateVar' is inaccessible due to 'private' protection level
print(privateVar)

// 'fileprivateVar' is inaccessible due to 'fileprivate' protection level
print(fileprivateVar)
}
}
Both private and fileprivate inaccessible out side it defining source file.
Both private and fileprivate inaccessible out side it defining source file.

When to use private

The concept of private in Swift is not much different from other languages.

You use private for entity means to use within the enclosing declaration. We usually use this to hide complexity or information that doesn't require outside the declaration.

The less we expose, the more flexibility we get between each entity (loose coupling).

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

When to use fileprivate

As you see in the previous example, the only time when you use fileprivate over private is when you want to access an entity:

  1. Within the same file.
  2. But outside its declaration, e.g., different class, struct.

I can't think of any reason or situation where I want this behavior. And I never use it at all in my work.

I believe there might be a use case for some specific cases or scenarios.

If you use it, feel free to share your experience and use case with me on Twitter.


Read more article about Swift or see all available topic

Enjoy the read?

If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron Buy me a coffee Tweet Share
Previous
How to add Launch Screen in SwiftUI

If you create a new SwiftUI project, you won't see a launch screen storyboard anymore. Learn how to configure a launch screen in the SwiftUI world.

Next
How to Hide Navigation Bar when Keyboard is shown in UIKit

Since iOS 8, we can easily hide a navigation bar when we show the keyboard.

← Home