Youll
Modules

Client

The orchestration layer that wires together all Bricks modules, manages app lifecycle, tab configuration, analytics, and notifications.

The Client package is the orchestration layer of the Youll platform. It sits at the top of the Bricks dependency graph, importing Core, Onboarding, Player, and Profile. Client is where a customer app plugs into Bricks: it provides the setup functions, the screen configuration factory system, analytics wiring, push notification management, and the full coordinator hierarchy that drives navigation.

This page serves as a module reference. For the underlying architectural concepts, see:

Package Dependencies

TypeDependencies
Internal (Bricks)Core, Onboarding, Player, Profile
FirebaseCrashlytics, Messaging, RemoteConfig
Binary frameworksAppsFlyerLib, PurchaseConnector, BrazeKit, BrazeUI
TransitiveSDWebImage (via Core), YoullNetwork (via Core)

File Inventory

The Client package contains approximately 65 Swift files organized into three directories.

App/

Application-level singletons, configuration, and service managers.

FilePurpose
Config.swiftConfig singleton implementation. Central state hub holding app config, networking, user service, and Combine publishers
ConfigType.swiftProtocol defining Config's public API contract
Config+Actions.swiftConfig extension for app config fetching, timezone updates, Crashlytics logger setup, and downloaded sessions cache
Config+User.swiftConfig extension for user refresh, AppsFlyer/Firebase user ID sync, and BricksNetworkDataSource conformance for token management
Keys.swiftsetup(with:) function and Keys accessor for ClientKeysType
UIConfigurator.swiftsetupUIConfigurator(with:) function and UIConfigurator accessor for UIConfig
AnalyticsManager.swiftTwo-layer analytics system: AnalyticsManagerType protocol + AnalyticsManager singleton with 19 protocol conformances
AppsFlyerManager.swiftAppsFlyer SDK wrapper with PurchaseConnector integration
TrackingManager.swiftApp Tracking Transparency (ATT) wrapper with trackingAuthorizationPublisher
NotificationManager.swiftFCM token management, push notification parsing, UNUserNotificationCenterDelegate and MessagingDelegate
UserNotificationManager.swiftPush notification authorization management with notificationAuthorizationPublisher
LocalNotification.swiftData model for local notification payloads
RemoteNotification.swiftData model for remote notification payloads
Screen Config/ScreenConfigFactory.swiftScreenConfigFactoryType protocol, setupScreenConfigFactory(with:), and global ScreenConfig accessor
Screen Config/FactoryTypes.swiftAll 24 sub-factory protocols for screen configuration

Coordinators/

The full coordinator hierarchy for app navigation.

FilePurpose
Coordinator.swiftCoordinatorFlow enum (20 cases), ParentCoordinator protocol, ChildCoordinatorDelegate, and coordinator presenting utilities
AppCoordinator.swiftTop-level coordinator owning UIWindow. Manages splash, auth/content branching, module injection, and app lifecycle
AuthCoordinator.swiftOnboarding and authentication flow: splash video, onboarding slider, social proof, auth screens. Supports quiz during onboarding and anonymous login
Main/
MainCoordinator.swiftTab bar coordinator. Manages all tab content post-login, navigation delegation, and deep link routing
MainCoordinators+TabSetup.swiftTab creation: calls makeTabItems(), creates coordinators per tab, wires journey completion delegates
MainCoordinator+RemoteNotifications.swiftRoutes parsed remote notifications to appropriate screen navigation
MainTabBarController.swiftCustom UITabBarController with tab bar appearance, haptic feedback, orientation support, and double-tap detection
Tabs/
BaseCoordinator.swiftBase class for Home, Showcase, and Profile coordinators. Provides Tuya screen navigation utilities
HomeCoordinator.swiftHome v1 (UIKit/GraphQL, deprecated) feed, tag feeds, category/subcategory navigation, journey content, timer, Tuya devices, welcome popups
ShowcaseCoordinator.swiftHome v2 (Showcase, SwiftUI/GraphQL). Supports both showcase and explore showcase modes
ExploreCoordinator.swiftExplore feed with generic or custom type, tag feeds, category/subcategory details
JourneysCoordinator.swiftJourney list (UIKit or SwiftUI), journey details, slides, completion, restart
LibraryCoordinator.swiftLibrary view, favorites, playlists, playlist details, downloads, history
EventsCoordinator.swiftEvents list and event details
ActivityCoordinator.swiftActivity/workout page, workout details, workout player, exercise preview
MealsCoordinator.swiftMeals page and meal details
HomeNavigable.swiftProtocol for coordinators that support home-style navigation
Tabs/Profile/
ProfileCoordinator.swiftUser profile, settings, subscriptions, badges, Tuya device management
ProfileCoordinator+Account.swiftAccount management (edit profile, delete account)
ProfileCoordinator+AppleHealth.swiftApple Health settings screens
ProfileCoordinator+Avatar.swiftProfile image picker
ProfileCoordinator+Notification.swiftNotification settings in profile
ProfileCoordinator+Reminders.swiftReminder configuration screens
ProfileCoordinator+SecretAction.swiftHidden debug/admin actions
ProfileCoordinator+Settings.swiftSettings screen, change password, measurement units
Static Coordinators/
ContentDetailsCoordinator.swiftShared singleton for content detail screens. Split across 8 files for auth, badges, content, events, facilitators, journeys, player, playlists, and reviews
SearchCoordinator.swiftShared singleton for search functionality
SubscriptionCoordinator.swiftShared singleton for subscription/paywall flows
QuizCoordinator.swiftShared singleton for quiz flows
Static Coordinators/ContentDetails/Utils/
TabBarItem.swiftTabItem enum and TabItemDetails struct
GenericConfig.swiftGeneric configuration utilities
AppToastConfig.swiftToast notification configuration
UnauthorizedUserActionManager.swiftContent gating alerts for anonymous/unsubscribed users
PlayerOptionsViewModel.swiftPlayer options view model
PortraitNavigationController.swiftPortrait-locked UINavigationController subclass

Utils/

FilePurpose
FirebaseFlagProvider.swiftFlagProvider implementation using Firebase Remote Config
BNAppConfig+DefaultConfig.swiftDefault app configuration fallback values
WhatsNewControllerManager.swift"What's New" popup logic using content hash comparison
UITabBarController+Utils.swiftTab bar controller utility extensions
UIViewController+PopupBar.swiftPopup bar (mini player) utility extensions
UnitTesting.swiftUnit testing hook setup

Setup Functions

Client exposes five setup functions that customer apps must call during initialization. All are called in AppDelegate.didFinishLaunchingWithOptions.

FunctionPurposeAccessor
Client.setup(with: ClientKeysType)Provides app keys (API keys, URLs)Keys
Client.setupScreenConfigFactory(with: ScreenConfigFactoryType)Provides the screen configuration factoryScreenConfig
Client.setupUIConfigurator(with: UIConfig)Provides the UI configurator for design tokensUIConfigurator
Client.AnalyticsManager.setup(with: AnalyticsManagerType)Provides the analytics implementationAnalyticsManager.shared.analytics
Client.Config.setup(with: environment, facebookAuthenticator:, enableRestoreAccount:)Initializes the Config singletonConfig.shared

Each setup function stores the provided instance in a module-level variable. The corresponding accessor fatally crashes if called before setup, ensuring initialization order is enforced at runtime.

For the full initialization sequence including Core setup and Settings configuration, see Bootstrap Sequence.

Config

ConfigType Protocol

ConfigType defines the public contract for the Config singleton. All coordinators and services depend on this protocol rather than the concrete Config class.

public protocol ConfigType: AnyObject {
    // App configuration (fetched from server)
    var appConfig: BNAppConfig { get }

    // Auth state
    var isLoggedIn: Bool { get }
    var isAnonymousLogin: Bool { get }
    var currentUserId: String? { get }

    // Services
    var facebookAuthenticator: FacebookAuthenticatoryType? { get }
    var flagManager: FlaggingManager { get }
    var bricksNetwork: BricksNetwork { get }
    var userService: UserService { get }

    // Combine publishers
    var registrationCompletionPublisher: PassthroughSubject<Void, Never> { get }
    var subscriptionCompletionPublisher: CurrentValueSubject<Bool, Never> { get }
    var didGetAppConfiguration: CurrentValueSubject<Bool, Never> { get }
    var requiredNetworkCheckPublisher: PassthroughSubject<Void, Never> { get }
    var applicationLaunchPublisher: PassthroughSubject<Void, Never> { get }

    // Network and delegates
    var networkReachability: NetworkReachability { get }
    var affiliateDelegate: AffiliateTokenDelegate? { get set }

    // Actions
    func didLogin()
    func refreshCurrentUser(completion: ((_ error: Error?) -> Void)?)
    func updateUser(completion: ((_ error: Error?) -> Void)?)
    func logoutIfNeeded(completion: (() -> Void)?)
    func getAppConfig()
    func checkDownloadedSessionsCache()
}

Config Extensions

Config+Actions handles:

  • getAppConfig(): Fetches app configuration from the API and stores it in appConfig. Sends didGetAppConfiguration publisher on completion.
  • Timezone update to the server
  • Crashlytics non-fatal error logging setup
  • setAppsFlyerDeviceID(): Syncs the AppsFlyer device ID
  • checkDownloadedSessionsCache(): Validates cached downloaded sessions against available content

Config+User handles:

  • prepareCurrentUser(): Sets AppsFlyer customerUserID and Firebase Analytics user ID when user state changes
  • refreshCurrentUser(): Calls userService.getProfile() to reload user data
  • BricksNetworkDataSource conformance: Provides auth tokens to the networking layer for API requests

Tab Selection

Customer apps define their tab bar by implementing GenericConfigFactoryType.makeTabItems(), which returns an array of TabItem values. Each tab maps to a coordinator that MainCoordinator creates on startup.

TabItem Enum

CaseCoordinatorCoordinatorFlowNotes
.homeHomeCoordinator.homeHome v1 (UIKit/GraphQL) — Deprecated
.showcaseShowcaseCoordinator.showcaseHome v2 Showcase (SwiftUI/GraphQL)
.slices.slicesHome v3 Slices (SwiftUI/REST)
.exploreExploreCoordinator.exploreStandard explore feed. Uses .generic or .custom type based on feature flags
.exploreShowcaseShowcaseCoordinator.exploreShowcaseExplore using the showcase coordinator (alternative layout)
.eventsEventsCoordinator.eventsEvents list and details
.libraryLibraryCoordinator.librarySaved content, favorites, playlists, downloads
.journeysJourneysCoordinator.journeysTimeline journeys (UIKit view)
.linearJourneysJourneysCoordinator.journeysLinear journeys (SwiftUI view)
.profileProfileCoordinator.profileFull profile with all settings
.lightProfileProfileCoordinator.profileLimited profile (for isLightVersion apps)
.mealsMealsCoordinator.mealsMeal plans and nutrition
.activityActivityCoordinator.activityWorkouts and activity tracking
.biometricsvia BiometricsModuleInterface.biometricsRequires module injection
.communityvia CommunityModuleInterface.communityRequires module injection
.custom(name)via makeCustomCoordinator(name:)N/ACustomer-defined custom tabs

TabItemDetails

Each tab's visual appearance is configured by returning a TabItemDetails from makeTabItemDetails(for:):

public struct TabItemDetails {
    public var accessibilityIdentifier: String
    public var name: String
    public var icon: UIImage?
    public var selectedIcon: UIImage?
    public var uppercased: Bool
    public var tintColor: UIColor?
}

Search in Tab Bar

Search can optionally appear as a tab bar item (rather than being accessed from a navigation bar button). This is controlled by two Settings:

  • Settings.isSearchInTabBar: Places search as a tab
  • Settings.isSearchEnabled: Enables search functionality globally

When both are true, a search navigation controller is appended after all makeTabItems() tabs.

Custom Tabs

The .custom(name) tab case allows customer apps to inject tabs that Bricks has no knowledge of. The flow is:

  1. Customer app returns .custom(name: "myTab") from makeTabItems()
  2. MainCoordinator calls ScreenConfig.makeCustomCoordinator(name: "myTab")
  3. Customer app's ScreenConfigFactoryType implementation returns a Coordinator for that name
  4. The coordinator is used as-is for that tab

The default implementation of makeCustomCoordinator(name:) returns nil, which causes a fatal crash. Customer apps using .custom tabs must override this method.

Screen Config Factory

The screen configuration factory is the primary customization mechanism for the visual appearance of every screen in the app. Customer apps implement ScreenConfigFactoryType and its sub-protocols to provide screen-specific configuration objects (colors, fonts, layout, copy).

Protocol Hierarchy

ScreenConfigFactoryType is the root protocol with 24 sub-factory properties and one method:

PropertyProtocolOptionalScreens Configured
onboardingOnboardingScreenConfigFactoryTypeNoSplash, onboarding slider, auth screens, social proof, login, signup, forgot password
contentDetailsContentDetailsScreenConfigFactoryTypeNoCategory details, subcategory details
libraryLibraryScreenConfigFactoryTypeNoCreate playlist, library, playlist details, history, downloads
quizQuizScreenConfigFactoryTypeYesQuiz screen, intro, answers, suggested content, static results, portrait video
superPaywallSuperPaywallScreenConfigFactoryTypeNoSuper paywall with slices
paywallPaywallScreenConfigFactoryTypeNoSubscription screen, subscription packages
playerPlayerScreenConfigFactoryTypeNoMedia player, player info, option picker, workout exercise preview
sharedSharedScreenConfigFactoryTypeNoSubcategory header, reviews widget, description config, confirmation banner, portrait video, error state, progress bar
homeHomeScreenConfigFactoryTypeNoHome screen, tag feed, events list, daily quote, timer sessions history
searchSearchScreenConfigFactoryTypeNoSearch screen, search filter
favoritesFavoritesScreenConfigFactoryTypeNoFavorites sessions
exploreExploreScreenConfigFactoryTypeNoExplore feed
journeyJourneysScreenConfigFactoryTypeNoJourneys screen, journey details, journey completed, journey intro slider
settingsSettingsScreenConfigFactoryTypeNoSettings screen, settings items, edit profile, Apple Health, change password, measurement, notifications
profileProfileScreenConfigFactoryTypeNoProfile stats, profile screen, badges, session completed, logout, image picker, share stats, events agenda
remindersRemindersScreenConfigFactoryTypeYesReminders screen, intro popup, reminder templates
unauthorizedUnauthorizedAccessConfigFactoryTypeNoRegistration-only alert, registration+subscription alert, unauthorized action config
appToastAppToastConfigFactoryTypeNoRemote notification toast, offline app toast
genericGenericConfigFactoryTypeNomakeTabItems(), tab item details, error config, email alert, delete account, notifications settings, language selector, welcome message, "what's new", navigation bar, and more
skeletonsSkeletonsConfigFactoryTypeNoSkeleton loading configs for all screens
eventDetailsEventDetailsScreenConfigFactoryTypeYesEvent details, info banners
mealsMealsConfigFactoryTypeYesMeals page, meal details
activityActivityConfigFactoryTypeYesActivity page, workout details, workout player, close alert
facilitatorDetailsFacilitatorDetailsScreenConfigFactoryTypeYesFacilitator details, contents list

Method: makeCustomCoordinator(name: String) -> Coordinator? (optional, defaults to nil)

Optional factories return nil by default via protocol extensions. Customer apps only need to implement them if they activate the corresponding product module.

For implementation guidance and examples, see the Screen Config Factory Guide (planned).

Analytics

Two-Layer Architecture

The analytics system has two layers:

  1. AnalyticsManagerType protocol: The interface that customer apps implement. It has one required method (logEvent(name:parameters:)) and six optional convenience methods for AppsFlyer, Meta, and purchase tracking.

  2. AnalyticsManager class: A singleton wrapper that bridges Bricks feature modules to the customer-provided analytics implementation. It conforms to 19 analytics protocols defined across Bricks packages, translating domain-specific events into logEvent(name:parameters:) calls.

Analytics Protocol Conformances

ProtocolDefined InDomain
OnboardingAnalyticsOnboardingMarketing slider, social proof, splash video, registration, login
MainFeedAnalyticsCoreFeatured content, tagged content, banners, journeys, quizzes, events, workouts, meals, facilitators
ExploreFeedAnalyticsCoreTags, categories, subcategories, content selection, facilitators
JourneysFeedAnalyticsCoreJourney selection, widgets, intro, start, content, congrats
EventsFeedAnalyticsCoreEvent selection, event screen, share, respond, location, calendar
ActivitiesFeedAnalyticsCoreActivity selection, workout lifecycle (get ready, exercise, rest, close, completed, share)
MealsFeedAnalyticsCoreMeals preparing, no meals, meal details
LibraryFeedAnalyticsCoreFavorite content, playlist selection
ContentAnalyticsCoreCategory/subcategory screens, like/dislike
FavoritesAnalyticsCoreDislike action, content selection
SearchAnalyticsCoreFeed content, search query, filter tag
DownloadAnalyticsCoreDownloaded content action, delete
PlayerAnalyticsPlayerPlayer screen, seek, auto-play, AirPlay, options, like/unlike, download, share, progress, speed, shuffle, playlist
ProfileAnalyticsProfileEvent selection from profile
ProfileSettingsAnalyticsProfileNotification switches, URL opens
SubscriptionAnalyticsProfileSubscription success/error, package selection, checkout, Google Analytics e-commerce
QuizAnalyticsCoreQuiz intro, questions, skip, results, content selection
DebugAnalyticsCoreDebug content selection, error state logging
MarketingVideoAnalyticsCoreMarketing video completion

For implementing a custom AnalyticsManagerType, see the Analytics Integration Guide (planned).

Notifications

The notification system has three components that work together.

NotificationManager

Singleton (NotificationManager.shared) that handles the low-level notification infrastructure:

  • Conforms to UNUserNotificationCenterDelegate and Firebase MessagingDelegate
  • Manages FCM token lifecycle: registers device tokens, saves FCM tokens to the server via UserAPI.updateFCMToken, tracks the last sent token in Settings.lastSentFCMToken
  • Parses incoming notification payloads: attempts to decode as PushNotification (remote) first, falls back to LocalNotification
  • Delegates parsed notifications to NotificationManagerDelegate (implemented by SceneDelegate in the customer app)
  • Removes FCM token on logout via removeFCMTokenForLogout()
  • Initializes LocalNotificationsManager.shared on configuration to reschedule local notifications

UserNotificationManager

Singleton (UserNotificationManager.shared) that manages push notification authorization:

  • Publishes authorization status via notificationAuthorizationPublisher: CurrentValueSubject<UNAuthorizationStatus, Never>
  • requestPushNotificationsAuthorization(completion:): Checks current status, requests permission if .notDetermined, and registers for remote notifications if granted
  • Automatically registers for remote notifications on init if already authorized

MainCoordinator+RemoteNotifications

Routes parsed notifications to the appropriate screen via MainCoordinator's navigation system. When NotificationManagerDelegate.didReceiveRemoteNotification fires, the SceneDelegate forwards it to MainCoordinator, which uses its redirect(to:) deep link mechanism to navigate to the relevant content.

Notification Flow

Push received → NotificationManager (parse payload)
    → NotificationManagerDelegate (SceneDelegate)
        → MainCoordinator.redirect(to: destination)
            → Appropriate tab coordinator

Feature Flags

FirebaseFlagProvider

Client provides FirebaseFlagProvider, implementing the FlagProvider protocol defined in Core. It wraps Firebase Remote Config:

  • Fetch interval: minimumFetchInterval = 0 (fetches fresh values on every call)
  • Defaults: Loads from remote_config_defaults.plist bundled with the customer app
  • Refresh: refreshAllFlags(completion:) calls fetchAndActivate, then:
    • Sends flagRefreshCompletedPublisher (Combine)
    • Posts kDidUpdateFlags notification (NotificationCenter)
  • Query: getState(forFlag:) returns Bool, getStringValue(forFlag:) and getStringValue(forKey:) return String?

The FlaggingManager (defined in Core) wraps FirebaseFlagProvider and provides the isActive(flag:) API used throughout the codebase. Feature flags control which product modules are visible and active.

Coordinator Reference

All coordinators defined in Client, with their flow and role. For detailed coordinator lifecycle, deep linking, and navigation patterns, see Coordinator Pattern.

Tab Coordinators

CoordinatorFlowBase ClassModule Interfaces Used
HomeCoordinator.homeBaseCoordinatorTimer, Tuya
ShowcaseCoordinator.showcase / .exploreShowcaseBaseCoordinatorTimer, Tuya
ExploreCoordinator.explore(none)Timer
JourneysCoordinator.journeys(none)(none)
LibraryCoordinator.library(none)(none)
EventsCoordinator.events(none)(none)
ActivityCoordinator.activity(none)(none)
MealsCoordinator.meals(none)(none)
ProfileCoordinator.profileBaseCoordinatorTuya

ProfileCoordinator is the most complex, split across 8 files handling account, Apple Health, avatar, notifications, reminders, secret actions, and settings.

Static Coordinators

Singletons initialized once via AppCoordinator.start(). They provide shared functionality callable from any coordinator.

CoordinatorSetup CallPurpose
ContentDetailsCoordinator.setup(with: config, customSubscriptionsManager:)Content detail screens, player launch, facilitator details. Split across 8 extension files
SearchCoordinator.setup(with: config)Search screen creation via createSearchController()
SubscriptionCoordinator.setup(with: config)Subscription/paywall presentation
QuizCoordinator.setup(with: config)Quiz flow management

CoordinatorFlow Enum

The CoordinatorFlow enum has 20 cases used as keys in the childCoordinators dictionary:

auth, main, home, explore, exploreShowcase, showcase, contentDetails, search, events, library, favorites, profile, subscription, journeys, contentReview, quiz, meals, activity, biometrics, community

Content Gating

UnauthorizedUserActionManager is a singleton that handles what happens when an anonymous or unsubscribed user attempts to access premium content. It presents three types of alerts, all configured through UnauthorizedAccessConfigFactoryType:

MethodWhen Used
makeRegistrationOnlyAlert(actionHandler:)Anonymous user taps content that requires registration
makeRegistrationAndSubscriptionAlert(actionHandler:)User taps content that requires both registration and an active subscription
makeUnauthorizedActionAlert(actionHandler:)User attempts an action (like, download, playlist) that requires authorization

The action handler typically triggers navigation to the auth or subscription flow. The manager ensures only one alert is displayed at a time by dismissing any existing alert before presenting a new one.

Utilities

TrackingManager

Wraps ATTrackingManager for App Tracking Transparency. Singleton with:

  • trackingAuthorizationPublisher: CurrentValueSubject<ATTrackingManager.AuthorizationStatus, Never>: Publishes the current ATT status
  • requestPermission(): Requests ATT authorization if status is .notDetermined, logs the result as an analytics event

AppsFlyerManager

Wraps the AppsFlyer SDK for attribution tracking. Integrates with PurchaseConnector for revenue attribution.

WhatsNewControllerManager

Controls the "What's New" popup display after app updates. Uses a content hash comparison pattern:

  1. Gets the "What's New" configuration from ScreenConfig.generic.makeWhatsNewViewConfig()
  2. Compares its hash against Settings.whatsNewPopupHashValue
  3. Shows the popup only when the hash differs (content has changed)
  4. Stores the new hash after display

MainTabBarController

Custom UITabBarController subclass that adds:

  • Tab bar appearance configuration
  • Haptic feedback on tab selection
  • Device orientation support
  • Double-tap detection via TabSelectionProtocol

PortraitNavigationController

UINavigationController subclass that locks orientation to portrait. Used for screens that should not rotate (search tab, some modal flows).

For Agents

Reading Order

When working with the Client module, read files in this order:

  1. Start with the protocols: ConfigType.swift, ScreenConfigFactory.swift, FactoryTypes.swift to understand the public API surface
  2. Understand the flow: AppCoordinator.swift (lines 209-237 for start(), lines 382-419 for showContent())
  3. Tab creation: MainCoordinators+TabSetup.swift to see how tabs map to coordinators
  4. Specific coordinator: Read the tab coordinator relevant to your task
  5. Analytics: AnalyticsManager.swift if adding or modifying event tracking

Key Files

TaskStart Here
Understanding Config's APIConfigType.swift
Modifying app initializationConfig.swift, Config+Actions.swift
Adding a new tabTabBarItem.swift (add case), MainCoordinators+TabSetup.swift (add coordinator creation)
Adding screen configurationFactoryTypes.swift (add to relevant sub-protocol)
Adding analytics eventsAnalyticsManager.swift (add conformance or extend existing one)
Debugging push notificationsNotificationManager.swift, UserNotificationManager.swift, MainCoordinator+RemoteNotifications.swift
Understanding feature flagsFirebaseFlagProvider.swift, then FlaggingManager in Core
Content gating behaviorUnauthorizedUserActionManager.swift

Tips

  • The ScreenConfig global accessor is the most common way to access screen configurations throughout Bricks. Search for ScreenConfig. to find usage patterns.
  • Config.shared is the central state object. Most coordinators receive it as a constructor parameter rather than accessing the singleton directly.
  • Static coordinators (ContentDetailsCoordinator.shared, SearchCoordinator.shared, etc.) are accessed as singletons from anywhere. They are initialized in AppCoordinator.start() and must not be accessed before that.
  • ProfileCoordinator is split across 8 files. When modifying profile behavior, check all ProfileCoordinator+*.swift extensions.

On this page