Chapter is a SwiftUI-based iOS application targeting iOS 17.0+, built with modern Swift patterns including async/await, Combine, and dependency injection.
@mainstruct ChapterApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate @StateObject var snapchatManager = SnapchatManager.shared let container = AppContainer.shared var body: some Scene { WindowGroup { MasterTabView(authManager: AuthManager.shared) .environmentObject(container) .environmentObject(snapchatManager) } }}
The app initializes:
Firebase for push notifications
Mixpanel for analytics
TipKit for user onboarding tips
AppContainer for dependency injection
See Chapter/ChapterApp.swift:8-51 for the full initialization sequence.
The AppDestination enum (100+ cases) defines every routable screen:
enum AppDestination: Hashable { case university(UniversityV2) case course(Course_V2) case groupChat(GroupChat) case userProfile(GroupUser) case accommodation(AccommodationV2) case event(CalendarEvent) case society(Society) // ... 90+ more cases}
final class DeepLinkManager { static let shared = DeepLinkManager() func handle(url: URL) { // Parses URL and navigates to appropriate destination // Example: chapter://university/123 }}
@MainActorclass AppContainer: ObservableObject { static let shared = AppContainer() // Filter ViewModels @Published var searchUniFilter: UniversityV2FilterManager @Published var searchCourseFilter: CourseV2FilterViewModel // Core Managers (NOT @Published to avoid cascade re-renders) var authManager: AuthManager var locationManager: DeviceLocationManager var notificationManager = NotificationManager.shared // Data Services var searchCourseDataService: CourseDataServiceV2 var searchUniversityDataService: UniversityDataServiceV2 var shortlistManager: ShortlistV2Manager var whatsOnManager: WhatsOnManager // Auth State (only this triggers container updates) @Published private(set) var isAuthenticated: Bool = false @Published private(set) var userEnrollmentStatus: EnrollmentStatus?}
Performance optimization: Only isAuthenticated and userEnrollmentStatus are @Published on AppContainer. Other services manage their own state to prevent cascade re-renders throughout the app.
struct UniversityV2: Codable, Identifiable { let id: Int let name: String let location: String let rankings: UniversityRankings? let demographics: Demographics? let sports: [SportsTeam]? // ... more properties}
struct Course_V2: Codable, Identifiable { let id: UUID let name: String let uniID: Int let ucasPoints: Int? let modules: [CourseModule]? let ratings: CourseRatings? // ... more properties}
struct GroupUser: Codable, Identifiable { let id: UUID var name: String var email: String? var uni_id: Int? var enrollmentStatus: EnrollmentStatus? var grades: [Grade]? var interests: [String]? var profilePictureURL: String? // ... more properties}
class CourseDataServiceV2: ObservableObject { @Published var courses: [Course_V2] = [] @Published var isLoading = false @Published var error: Error? private var cancellables = Set<AnyCancellable>()}
struct CourseDetailView: View { @EnvironmentObject var container: AppContainer var body: some View { // Access services via container let _ = container.shortlistManager }}