AI iOS Development: How to Load Data at Launch Without Blocking Your App's First Screen
The short answer
When you ask an AI tool to "load the data when the app starts", it often does it the quick way: it puts a database check or a loading screen in front of the whole app, or it starts the launch work from a SwiftUI View. The free, open-source CFA AI Toolkit for iOS gives your AI a written rule for this instead. The app delegate starts the app-wide refresh at the earliest launch callback, each screen starts its own work with SwiftUI's .task, and the root of the app is never held back while data loads.
Install the toolkit in Codex or Claude Code, then ask in plain words, starting with "Using CFA" so the AI knows to follow the CFA skills. For example:
Using CFA, refresh the habits feature when the app launches, without blocking the first screen.
💡 What this article covers
Why app launch is a tricky place for AI-written code, the two refresh paths the CFA specification allows, what the CFA App Xcode template already does, the mistakes the rules forbid, and how to check the result yourself.
What is the CFA AI Toolkit?
CFA stands for Cooperative Feature Architecture. It's a blueprint that gives every kind of code in an iOS app a clear home: the View draws the screen, a ViewModel holds that screen's state, a Feature owns the business rules and the data, and a repository reads and writes it. The toolkit packages that blueprint as eight AI skills, which are folders of instructions your AI coding tool reads, plus Xcode project templates and a local analysis tool. It's MIT-licensed, so you can use it in commercial apps too.
Why is app launch hard for AI-written code?
Launch is where two easy shortcuts tempt an AI. One is to wait for storage before showing anything, so the app sits behind a spinner, or shows nothing at all if the database fails to open. The other is to start everything from the first screen's View, so the work is tied to that screen and can run twice when a second screen asks for the same data.
The README describes this as "a common false choice": using a View task as the whole app's launch mechanism, or waiting to load anything until a screen is visible. CFA uses both routes, each with a clear owner.
The two refresh paths CFA allows
App-wide work starts in the app delegate. The delegate's didFinishLaunchingWithOptions callback creates one Task that calls AppModel's applicationDidFinishLaunching() method, and AppModel then awaits the feature refreshes the app needs. This shared work runs while the UI is being prepared.
A screen's own work starts with SwiftUI's .task. The specification calls .task { await viewModel.refresh() } "the normal, approved choice" for a screen's first asynchronous work. SwiftUI starts it before the View appears.
Neither path blocks the first frame, and neither promises the network request has finished by then. So each screen shows what its ViewModel observes: loading, saved data, an empty state or an error.
What the CFA App template already does
If you start from the toolkit's CFA App Xcode template (File, New, Project, iOS, CFA App, after running the template installer), the launch refresh is already wired up. This is the template's app delegate:
final class CFAAppDelegate: NSObject, UIApplicationDelegate {
func application(
_: UIApplication,
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
Task { @MainActor in
await AppModel.shared.applicationDidFinishLaunching()
}
return true
}
}
And this is the AppModel method it calls. A simple Boolean makes sure the launch refresh only runs once:
func applicationDidFinishLaunching() async {
guard !hasFinishedLaunching else { return }
hasFinishedLaunching = true
await gitReposFeature.refresh()
}
The App itself stays plain. Its WindowGroup always shows the same root view, RootTabView, with no launch .task and no "is the data ready yet?" check:
WindowGroup {
RootTabView()
.environment(themeManager)
.preferredColorScheme(themeManager.selectedTheme.colorScheme)
}
The Git Repos screen then decides what to show from its ViewModel: a progress view while the first download runs, a "Try again" card if it failed with nothing saved, an empty state, or the list. On later launches, the feature publishes the repositories it saved in its JSON file cache before it asks GitHub for newer ones.
What the CFA rules tell your AI not to do
The CFA specification, which the skills read before they write code, is direct about launch. In plain words, it says:
Never gate the interface on a database. "Opening a database is never a prerequisite for presenting the application's interface." The root navigation appears straight away, whether storage is opening, ready or failing.
No launch .task in the App or a View. The specification says never to use .task { await AppModel.shared.applicationDidFinishLaunching() } or any other View-tied call to signal launch.
No app-wide launch error. There's no launchError or startupError. A failed fetch belongs to the feature that made it, and that feature's screen explains it and offers a retry.
One failure doesn't block everything. "One feature failing must not prevent unrelated features from becoming usable." Settings should still open if the data screen failed.
Don't throw away saved data. Keep previously loaded data when a refresh fails, and never report a failed first fetch as a successful empty list.
One request, many waiters. When launch and a screen's .task can both ask the same Feature to refresh, the specification says the Feature stores one in-flight task, and later callers await it instead of starting a second request.
How to check what your AI built
The specification includes an acceptance check you can run yourself. Make the first storage-opening request fail on purpose, then confirm that:
the tab bar or root navigation is still visible,
the affected screen explains its failed request,
an independent screen such as Settings still opens, and
a successful retry recovers the feature without replacing the root interface or losing saved data.
It also asks for tests showing that the launch triggers the intended features once, and separate feature tests for a successful refresh, a failed refresh, keeping cached data and retrying. It says plainly that compiling the app or using a fake fetch doesn't prove the real storage and UI behaviour, and that any check that wasn't run should be reported as not run.
How do I install the toolkit?
For Codex, download and extract the plugin release from the CFA AI Toolkit for iOS repository and double-click Install.command, or run node scripts/install.mjs in Terminal. For Claude Code, copy the eight skill folders into ~/.claude/skills, or run:
node scripts/install.mjs --mode skills --skills-directory ~/.claude/skills
Other AI coding tools that read plain skill folders can use the same folders. The cfa command comes with the Codex plugin install, so it may be missing from a skills-folder-only install. You don't need it for anything in this article. To get the CFA App template, run Install Xcode Template.command from the repository, then quit and reopen Xcode.
What to Remember
App-wide refreshes start in the app delegate's launch callback, and each screen's own first load starts with .task.
The root of the app always appears straight away. No database gate, launch spinner or app-wide launch error.
Each feature owns its loading, failure and retry, and keeps saved data when a refresh fails.
The CFA App template already wires this up, so it's a good place to start.
Test it by forcing the first storage request to fail and checking the rest of the app still works.
Is the CFA AI Toolkit free?
Yes. It's open source under the MIT licence, so you can use, change and share it, including in commercial apps.
Related articles
Codex SwiftUI: How to Add Colour Themes to Your iOS App with the CFA AI Toolkit
AI iOS App Development: How to Check AI-Written Swift for Race Conditions with the CFA AI Toolkit
Codex Swift: How to Make Codex Check Its Own iOS Changes with the CFA Change Gate
Claude Code iOS App Testing: How to Get Meaningful Unit Tests with the CFA AI Toolkit
About Us

3 Days of Swift Concurrency is created by Matthew Thomas, an iOS developer building in public since 2022. He publishes the free, MIT-licensed CFA AI Toolkit for iOS and reference apps on GitHub. Visit 3DaysOfSwiftConcurrency.com to follow along. The paid training programme is still being built: a soft launch is targeted for 1 December 2026, but that date depends on deadlines being met and isn't guaranteed.




Comments