top of page

CFA Reference: Project Structure

Formal CFA AI Toolkit for iOS Documentation · Reference 2 of 26

CFA organises an Xcode project by ownership. A reader should be able to open one feature folder and follow the whole path for that feature without searching through unrelated files.

Definitions

  • 1 - View: The app entry point, theme code, and each screen's SwiftUI View with its dedicated ViewModel, grouped by screen under Views (Root, Git Repos, Settings in the CFA App template).
  • 2 - AppModel: The AppModel, the concrete Features under Features, and the storage code. In the CFA App template it also contains Networking & Data Storage, with NetworkingManager, GitHubAPI, RepoFileCache and the GitReposProvider protocol.
  • 3 - App Resources: Assets, the app icon and other bundled resources.
  • 4 - Swift Extensions: Small, general extensions, for example Date+Display.swift.
  • Navigator map: A before-and-after outline of the folder tree. The change gate asks for one in the completion record.

Rules

  1. Use the four numbered top-level groups so the Xcode navigator sorts them in reading order.
  2. Group files by the feature that owns them. The Git Repos View and ViewModel sit together under 1 - View/Views/Git Repos, and GitReposFeature with its Repo value sits under 2 - AppModel/Features/Git Repos.
  3. Keep one primary type per file, named after the type.
  4. Put shared infrastructure, such as networking and SwiftData access, in a clearly named storage group rather than inside a single feature.
  5. Do not create empty folders, placeholder files or speculative abstractions.
  6. Record the navigator map before and after a structural change.

Decision rules

  • When a new screen is added, add its View and ViewModel in a new group under 1 - View/Views.
  • When a new area of business rules is added, add a concrete Feature under 2 - AppModel/Features and register it in AppModel.live().
  • When a helper is used by only one feature, keep it in that feature's group; move it to 4 - Swift Extensions only when it is genuinely general.
  • When an existing app has its own clear structure, keep it during feature work; restructure only as part of an architecture change that passes the gate.

Example

Source folder map of the CFA App template, from the repository

Source/Application
├── 1 - View
│   ├── Theme
│   │   ├── AppColourTheme+Palette.swift
│   │   └── ThemeManager.swift
│   ├── Views
│   │   ├── Root
│   │   │   ├── RootTabView.swift
│   │   │   └── RootTabViewModel.swift
│   │   ├── Git Repos
│   │   │   ├── GitReposView.swift
│   │   │   └── GitReposViewModel.swift
│   │   └── Settings
│   │       ├── SettingsView.swift
│   │       └── SettingsViewModel.swift
│   └── <ProductName>App.swift
├── 2 - AppModel
│   ├── AppModel.swift
│   ├── Features
│   │   ├── Git Repos
│   │   │   ├── GitReposFeature.swift
│   │   │   └── Repo.swift
│   │   └── Settings
│   │       ├── AppColourTheme.swift
│   │       └── SettingsFeature.swift
│   └── Networking & Data Storage
│       ├── File Cache/RepoFileCache.swift
│       ├── Networking/GitHubAPI.swift
│       ├── Networking/NetworkingManager.swift
│       └── Protocols/GitReposProvider.swift
├── 3 - App Resources
└── 4 - Swift Extensions
    └── Date+Display.swift

Common mistakes

  • Grouping by type (all Views together, all models together), which forces a reader to jump between folders for one feature.
  • Creating a Managers or Services folder that becomes a dumping ground. Features are never called Managers.
  • Leaving files from a removed feature behind. Feature removal deletes its View, ViewModel, Feature, repository and tests together.
  • Restructuring an established app's folders during an unrelated, narrowly requested fix.

Links

bottom of page