Access Control
Decide who can see and use each part of your code with Swift's five access levels — open , public , internal , fileprivate , and private — to hide implementation details and present a clean, deliberate interface.
Learn Access Control in our free Swift course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Swift course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ The Five Levels in Action
From widest to narrowest: open , public , internal , fileprivate , private . The classic pattern is a public type with private internals, exposing only safe methods.
2️⃣ internal — The Default
Write no modifier and you get internal : usable anywhere in the same module. This is what the vast majority of app code wants, so you only annotate when you need to go tighter or wider.
3️⃣ private(set), private vs fileprivate
private(set) gives you a property others can read but only your own code can write — perfect for protected state. And remember: private is scoped to the enclosing declaration (plus same-file extensions), while fileprivate opens up to the whole file.
Your turn. Fill in the setter modifier and the most restrictive level.
📋 Quick Reference
No blanks this time — just a brief and an outline. Encapsulate the calibration and expose only a read-only reading.
Practice quiz
What is the default access level in Swift when you write none?
- private
- public
- internal
- open
Answer: internal. If you omit an access modifier, the entity is 'internal' — visible anywhere within the same module.
Which access level restricts use to the same source file?
- fileprivate
- private
- internal
- public
Answer: fileprivate. 'fileprivate' makes an entity accessible only within the file it is declared in.
How does 'private' differ from 'fileprivate'?
- They are identical
- private is broader
- private allows subclassing
- private limits to the enclosing declaration (and its extensions in the same file); fileprivate limits to the whole file
Answer: private limits to the enclosing declaration (and its extensions in the same file); fileprivate limits to the whole file. private is tighter — scoped to the enclosing type/declaration, while fileprivate covers the entire file.
What does 'internal' mean?
- Visible only in the type
- Visible anywhere within the same module
- Visible to any module
- Visible only in subclasses
Answer: Visible anywhere within the same module. internal entities are accessible throughout the defining module but not from other modules.
What can 'open' do that 'public' cannot?
- Allow subclassing and overriding from outside the defining module
- Nothing, they are the same
- Restrict access to a file
- Make members private
Answer: Allow subclassing and overriding from outside the defining module. open lets other modules subclass a class and override its members; public exposes but does not permit external subclassing/overriding.
Which is the MOST restrictive access level?
- fileprivate
- internal
- private
- public
Answer: private. private is the most restrictive, limiting access to the enclosing declaration.
Order these from most open to most restrictive.
- private, fileprivate, internal, public, open
- open, public, internal, fileprivate, private
- internal, public, open, private, fileprivate
- public, open, internal, private, fileprivate
Answer: open, public, internal, fileprivate, private. From most to least open: open, public, internal, fileprivate, private.
Can a public function have a parameter of an internal type?
- Yes, always
- Only with open types
- Only inside extensions
- No — a public API cannot expose a less-accessible type in its signature
Answer: No — a public API cannot expose a less-accessible type in its signature. An entity cannot be more accessible than the types it uses in its public interface.
What is a common use of 'private(set)' on a property?
- Make it fully public
- Allow reading from anywhere but only setting within the declaring scope
- Hide it completely
- Make it open
Answer: Allow reading from anywhere but only setting within the declaring scope. private(set) gives a property a public (or internal) getter but a private setter — read freely, write internally.
Why use access control at all?
- To make code run faster
- It is required for every declaration
- To hide implementation details and expose a clean, intentional interface
- To enable optional chaining
Answer: To hide implementation details and expose a clean, intentional interface. Access control encapsulates internals, reducing coupling and protecting invariants behind a deliberate public surface.