Bringing multiple windows to your SwiftUI app
At a glance
| Item | Summary |
|---|---|
| Purpose | Compose rich views by reacting to state changes and customize your app’s scene presentation and behavior on iPadOS and macOS. |
| App architecture | A Swift sample with the source-visible chain BookClubApp → ArcView → NavigationModel → SeededRandomNumberGenerator → SwiftUI APIs. |
| Main patterns | Factory, Publisher-backed observable state |
| Project style | 36 scanned source file(s) across Swift, organized around ranked entry, type, and file boundaries. |
| Execution model | Source-visible boundaries: await suspension point, @MainActor; none alone proves a background thread. |
| State/event model | Source-visible mechanisms: ObservableObject, @Published, SwiftUI state property wrapper. |
| Key frameworks/packages | SwiftUI, Foundation, Combine, Charts; these are source dependencies, not architecture labels. |
Project structure
Source bundle/
└── BookClub/
├── BookClubApp.swift
├── Views/
│ ├── CircularProgressView.swift
│ ├── LinearProgressView.swift
│ ├── StackedProgressView.swift
│ ├── BookDetail/
│ │ └── BookDetailHeader.swift
│ └── BookCover.swift
└── Models/
├── NavigationModel.swift
├── ProgressEditorModel.swift
├── ReadingListModel.swift
├── CurrentlyReading.swift
├── ReadingProgress.swift
└── ReadingActivityItem.swift
Structure observations
- Architecturally prominent files are ranked from entry points and role-named declarations; resource-only paths are omitted.
- Primary languages: Swift.
- The verified tree contains 5 project/configuration file(s) and 51 source declaration(s).
Overall architecture
flowchart LR
N1["BookClubApp"]
N2["ArcView"]
N3["NavigationModel"]
N4["SeededRandomNumberGenerator"]
N5["SwiftUI APIs"]
N1 --> N2
N2 --> N3
N3 --> N4
N4 --> N5
Reference code
BookClub/BookClubApp.swift:11 — architecture anchor
@main
struct BookClubApp: App {
private var dataModel = ReadingListModel()
var body: some Scene {
WindowGroup("Reading List") {
ReadingList(model: dataModel)
}
.commands {
SidebarCommands()
}
#if os(macOS)
WindowGroup("Book Details", for: Book.ID.self) { $bookId in
BookDetailWindow(dataModel: dataModel, bookId: $bookId)
}
.commandsRemoved()
Window("Reading Activity", id: "activity") {
ReadingActivityList(activity: dataModel.activity)
.frame(minWidth: 640, minHeight: 480)
}
.keyboardShortcut("1")
.defaultPosition(.topTrailing)
.defaultSize(width: 800, height: 600)
#endif
}
}Interpretation
The arrows summarize the source-visible entry, role-named types or folders, and framework direction; when nodes come from structural folders, the sequence is a high-level interpretation rather than proof that every adjacent node calls the next. Ownership is claimed only where the next section cites a stored property or assignment. The diagram is intentionally limited to the dominant path into SwiftUI.
Ownership and state
classDiagram
BookClubApp *-- ReadingListModel : dataModel
NavigationModel o-- NavigationSplitViewVisibility : columnVisibility
NavigationModel o-- Category : selectedCategory
NavigationModel *-- Set : selectedBookIds
Ownership evidence
BookClub/BookClubApp.swift:13 — stored dependency or nearest verified ownership anchor
@main
struct BookClubApp: App {
private var dataModel = ReadingListModel()
// ...
}| Owner | Object or state | Relationship | Mutation authority |
|---|---|---|---|
BookClubApp |
ReadingListModel (dataModel) |
creates and retains | Owning lexical scope |
NavigationModel |
NavigationSplitViewVisibility (columnVisibility) |
stores or receives | App/module collaborators |
NavigationModel |
Category (selectedCategory) |
stores or receives | App/module collaborators |
NavigationModel |
Set (selectedBookIds) |
owns value state | App/module collaborators |
Composition arrows indicate a source-visible construction expression or locally owned value state; aggregation means the owner stores or receives a dependency without proving exclusive lifetime ownership.
Concurrency, scheduling, and thread safety
Evidence limit: actor isolation, async/await, or Task creation does not by itself prove background-thread execution; Sendable conformance alone does not prove thread-safe mutation.
| Concern | Source mechanism | Verified placement or handoff | Evidence |
|---|---|---|---|
| Suspension boundary | await suspension point |
The source declares or crosses an asynchronous boundary; it does not by itself establish background execution. | BookClub/Views/ReadingList.swift:43 |
| Main isolation | @MainActor |
The cited annotation marks its attached declaration or closure as main-actor isolated. | BookClub/Views/ShareButton.swift:35 |
@MainActor/MainActor.run, DispatchQueue.main, and RunLoop.main are reported as distinct isolation, queue, and event-loop mechanisms. A plain Task is kept separate from Task.detached; neither is labeled as a background thread.
Reference code
BookClub/Views/ReadingList.swift:43 — representative execution boundary
for await jsonData in navigationModel.$jsonData.values {
if let data = jsonData {
navigationData = data
}
}State propagation, frameworks, and dependencies
Evidence limit: an import proves a source-level compilation dependency at the cited line; it does not prove runtime use, architectural adoption, or whether a Swift package is a direct application dependency.
| Category | Mechanism or module | Verified role | Evidence |
|---|---|---|---|
| State propagation | ObservableObject |
ObservableObject supplies an observation contract. | BookClub/Models/CurrentlyReading.swift:10 |
| State propagation | @Published |
A published property can emit owner-controlled changes. | BookClub/Models/CurrentlyReading.swift:12 |
| State propagation | SwiftUI state property wrapper |
A SwiftUI property wrapper supplies or observes UI state. | BookClub/Views/BookContentList.swift:12 |
| Source import | SwiftUI |
The cited file imports this module; runtime use and architectural role are not inferred. | BookClub/BookClubApp.swift:9 |
| Source import | Foundation |
The cited file imports this module; runtime use and architectural role are not inferred. | BookClub/Models/Category.swift:8 |
| Source import | Combine |
The cited file imports this module; runtime use and architectural role are not inferred. | BookClub/Models/NavigationModel.swift:8 |
| Source import | Charts |
The cited file imports this module; runtime use and architectural role are not inferred. | BookClub/Views/BookDetail/BookDetailReadingProgressChart.swift:9 |
receive(on:) describes downstream delivery scheduling, while subscribe(on:) describes upstream subscription/request/cancel scheduling. An import Combine alone establishes neither behavior nor a Store, reducer, Redux, or other application architecture.
Class and protocol design
BookClub/BookClubApp.swift:12 — representative type boundary
@main
struct BookClubApp: App {
private var dataModel = ReadingListModel()
// ...
}| Type | Responsibility | Depends on or conforms to |
|---|---|---|
BookClubApp |
Application entry and top-level composition | App |
CircularProgressView |
User-interface presentation and input forwarding | View |
ArcView |
User-interface presentation and input forwarding | View |
NavigationModel |
Feature data or observable state | Codable, ObservableObject |
ProgressEditorModel |
Feature data or observable state | Hashable |
LinearReadingProgressView |
User-interface presentation and input forwarding | View |
StackedProgressView |
User-interface presentation and input forwarding | View |
ReadingListModel |
Feature data or observable state | ObservableObject |
MockFactory |
Constructs a selected implementation | Concrete collaborators/imported frameworks |
SeededRandomNumberGenerator |
Generates feature data or resources | RandomNumberGenerator |
No local protocol conformance is claimed as protocol-oriented design; external framework conformances are listed only as dependencies.
Access control
| Symbol | Access | Verified effect | Likely rationale |
|---|---|---|---|
dataModel (BookClub/BookClubApp.swift:13) |
private |
Use is restricted to the lexical declaration and same-file extensions allowed by Swift. | Inference: keep state mutation or dependency lifetime inside the owning implementation. |
id (BookClub/Models/Book.swift:11) |
private(set) |
Read access follows the declaration; writes remain in the private scope. | Inference: allow observation while reserving invariant-changing writes for the owner. |
random (BookClub/Models/CurrentlyReading.swift:88) |
fileprivate |
Use is restricted to this source file. | Inference: share with same-file helpers or extensions without exposing the symbol module-wide. |
book (BookClub/Models/CurrentlyReading.swift:150) |
private |
Use is restricted to the lexical declaration and same-file extensions allowed by Swift. | Inference: hide an implementation step that is not part of the collaboration surface. |
Reference code
BookClub/BookClubApp.swift:13 — representative boundary
@main
struct BookClubApp: App {
private var dataModel = ReadingListModel()
// ...
}Swift declarations without a modifier are internal; explicit private, fileprivate, private(set), public, or open entries above are interpreted by language semantics. Objective-C/C samples instead rely on header and implementation boundaries, which are not equivalent to Swift lexical privacy.
Logic ownership and placement
| Logic | Owning type or file | Placement rationale |
|---|---|---|
| Application entry and top-level composition | BookClubApp |
The source’s App suffix makes this role explicit. |
| Constructs a selected implementation | MockFactory |
The source’s Factory suffix makes this role explicit. |
| Generates feature data or resources | SeededRandomNumberGenerator |
The source’s Generator suffix makes this role explicit. |
| Feature data or observable state | NavigationModel, ProgressEditorModel, ReadingListModel |
The source’s Model suffix makes this role explicit. |
| User-interface presentation and input forwarding | ArcView, CircularProgressView, LinearReadingProgressView, StackedProgressView |
The source’s View suffix makes this role explicit. |
Design patterns
| Pattern | Source evidence | Purpose or tradeoff |
|---|---|---|
| Factory | BookClub/Models/CurrentlyReading.swift:101 |
A factory-named type owns implementation construction. |
| Publisher-backed observable state | BookClub/Models/CurrentlyReading.swift:12 |
Published properties notify observers while mutation remains with the state object. |
Naming conventions
- Types: App: BookClubApp; Factory: MockFactory; Generator: SeededRandomNumberGenerator; Model: NavigationModel, ProgressEditorModel, ReadingListModel; View: ArcView, CircularProgressView, LinearReadingProgressView, StackedProgressView.
- Protocols: no local protocol declaration in the scanned source.
- Methods:
makeBody,path,inset,encode,present,dismiss,togglePresentation,foregroundStyle. - Files:
BookClub/BookClubApp.swift,BookClub/Views/CircularProgressView.swift,BookClub/Models/NavigationModel.swift,BookClub/Models/ProgressEditorModel.swift,BookClub/Views/StackedProgressView.swift,BookClub/Models/ReadingListModel.swift.
Architecture takeaways
BookClubAppis the main source-visible entry or composition anchor for this sample.- Framework work reaches SwiftUI, Charts through a deliberately small high-level chain; the detailed API graph remains inside the cited implementation files.
- Stored-property evidence identifies lifecycle collaboration; it does not by itself prove exclusive object ownership.
- Access-control conclusions separate verified language visibility from the likely design rationale.
- The source does not justify labeling the design protocol-oriented.
Source map
| Source file | Relevant symbols |
|---|---|
BookClub/BookClubApp.swift |
Cited implementation, BookClubApp, SwiftUI |
BookClub/Models/Book.swift |
Cited implementation, Book |
BookClub/Models/CurrentlyReading.swift |
Cited implementation, MockFactory, ObservableObject, @Published, CurrentlyReading, SeededRandomNumberGenerator |
BookClub/Views/ReadingList.swift |
await suspension point, ReadingList, ReadingList_Previews |
BookClub/Views/ShareButton.swift |
@MainActor, ShareButton, ShareButton_Previews |
BookClub/Views/BookContentList.swift |
SwiftUI state property wrapper, BookContentList, BookContentList_Previews |
BookClub/Models/Category.swift |
Foundation, Category |
BookClub/Models/NavigationModel.swift |
Combine, NavigationModel, CodingKeys |
BookClub/Views/BookDetail/BookDetailReadingProgressChart.swift |
Charts, BookDetailReadingProgressChart, BookDetailReadingProgressChart_Previews |
BookClub/Views/CircularProgressView.swift |
CircularProgressView, CircularProgressViewStyle, ArcView, Arc, CircularProgressView_Previews |
BookClub/Models/ProgressEditorModel.swift |
ProgressEditorModel, DismissAction |
BookClub/Views/LinearProgressView.swift |
LinearReadingProgressView, LinearReadingProgressViewStyle, LinearReadingProgressView_Previews |
BookClub/Views/StackedProgressView.swift |
StackedProgressView, StackedProgressViewStyle, StackedProgressView_Previews |
BookClub/Models/ReadingListModel.swift |
ReadingListModel |
BookClub/Views/BookDetail/BookDetailHeader.swift |
BookDetailHeader, BookCover, ButtonFooter, BookDescriptionSheet, BookDetailHeader_Previews |
BookClub/Models/ReadingProgress.swift |
ReadingProgress, EntriesByDate, Entry |