Activity 1
Protect a counter
Create a public Counter whose value is readable publicly but changes only through increment() and reset().
Hint: Use public private(set).
Swift Fundamentals
Protect implementation details and design clear boundaries with private, internal, package, and public access.
Before you begin
Learning stage
Access control defines where declarations can be used. Keeping implementation details hidden reduces accidental coupling and leaves a type free to change internally. Swift defaults to internal, which makes a declaration available inside its module but not to importing modules.
Use private for a declaration limited to its enclosing scope, fileprivate for the source file, package for modules in the same Swift package, internal for the current module, and public or open for exported framework APIs. open additionally permits external subclassing and overriding, so it should be deliberate.
Learning stage
The type exposes the behavior callers need while keeping mutable storage under its own control.
public struct DownloadProgress {
public let totalBytes: Int
public private(set) var receivedBytes = 0
public init(totalBytes: Int) {
self.totalBytes = totalBytes
}
public mutating func record(bytes: Int) {
receivedBytes = min(receivedBytes + bytes, totalBytes)
}
}Learning stage
These concepts appear throughout production iOS code. Focus on the requirement each technique communicates.
Learning stage
Notice these mistakes early so the compiler and type system can help instead of becoming obstacles.
Learning stage
Work through these activities in a small Xcode project. No embedded playground is required on this site.
Activity 1
Create a public Counter whose value is readable publicly but changes only through increment() and reset().
Hint: Use public private(set).
Activity 2
Take a small type and label which members should be private, internal, or public. Explain each choice.
Hint: Start with the narrowest level and widen only for a real caller.
Learning stage
Answer each question before revealing the explanation.
QUESTION 1
internal
Declarations are visible throughout their module unless another level is specified.
QUESTION 2
open permits subclassing and overriding from another module; public does not.
That extra extension point makes open a stronger and more consequential promise.
Learning stage
Explain the idea in terms of its purpose, behavior, and tradeoffs rather than reciting syntax.
Short answer: It prevents accidental dependencies and keeps implementation details changeable.
A small API surface communicates the supported contract. Callers cannot depend on hidden storage or helpers, so implementation changes have a smaller impact. Access control is therefore a design tool, not merely a compiler restriction.
Possible follow-ups
Learning stage
Access control turns code boundaries into enforceable contracts. Expose the behavior callers need, protect mutable implementation details, and widen access only for a real module or package requirement.