• public : visible outside the module
  • internal : visible only within the module
  • fileprivate : visible only within the current file New
  • private : visible only within the current type definition/declaration Updated

All classes inside a file are visible

It used to be that you cannot control class and member visibility when they are defined inside a file together.

Members are fuly accessible from codes inside the same file

So developers define each class in its own file in order to have a better control (to its class and member access):

A workaround to better control access visibility

But with Swift 3, there is now a much better way of controlling these access visibilities.

For example, there is now a "private to a single class" versus a "private to an entire file" distinction. With this, it's safe to define multiple classes again to a single file, but without the original problem this time.

The access controls in action

To demonstrate how these access controls behave, we define five structs for each of the five access controls. The members of these structs also follow the same pattern.

Default (internal)

Struct with a default visibility access

private Updated

Struct marked private


Struct marked internal


Struct marked public

fileprivate New

Struct marked fileprivate

Access within the current file

Here we define all five structs, with their respective access visibility modifiers, inside access-control.swift file. We test how they behave when we instantiate each of them from inside the same file itself.

Same file access scope

So public, internal, and the default (internal) allow instantiation of structs (or class objects) from within the same file, while private and fileprivate do not.

Access within the module but in different files

Here, we put each struct definition and the object-creation code ( main.swift) in their own respective files. All of them are inside the same module as well.

Module-level access in scope

Like the previous test; public, internal, and the default (internal) allow instantiation of structs from different files but from within the same module, while private and fileprivate do not.

Access outside of the module

We move the object-creation file ( main.swift) out of the module this time and try to instantiate structs like before.

External to module access scope

This time, only the struct marked public can be successfuly instantiated from outside the module.

Access outside of the type

Here we test to see how these visibility modifiers affect access to a struct's members.

With insights gained from previous tests, we omit structs marked private and fileprivate because they do not allow instantiation in the first place.


Member with default access visibility


Member marked internal


Member marked public

As it turns out, members marked public, internal, default (internal), and this time, fileprivate are accessible from outside its own type.

Marking a member private in Swift 3 can make it accessible only from inside the struct (or class) definition itself. This is a different behavior from Swift 2 where it behaved more like fileprivate. This time, private can enforce fine-grained control over its accessibility.