Complete guide to authentication and login in TheCompanyApp.
Authentication Architecture
TheCompanyApp uses a two-tier authentication system:
Primary Auth: iCloud
Device-level authentication via Apple ID
Required for app installation and iCloud sync
Handled by iOS automatically
Secondary Auth: UserPass
Company-level authentication
Required for accessing specific company data
User-configurable credentials per company
Login Flow Overview
App Launch
↓
Check iCloud Status
↓
Load Companies List
↓
Select Company
↓
Check UserPass Exists
↓
Login Screen
↓
Validate Credentials
↓
Grant Access to Company Data
Step-by-Step Login Process
Step 1: App Launch
When you open TheCompanyApp:
Splash Screen displays briefly
App checks iCloud sign-in status
Core Data container initializes with dual stores
If Not Signed In to iCloud:
Alert appears: "iCloud Required"
Instructions to sign in via Settings app
App cannot proceed without iCloud
If Signed In:
Continue to company list loading
Step 2: Load Companies List
TheCompanyApp fetches all companies accessible to you:
Query Logic (ContentView.swift):
This retrieves:
Private Store: Companies you own
Shared Store: Companies shared with you
Companies List View:
Displays all available companies
Shows company name, logo, tier
Indicates if you're owner or participant
Step 3: Company Selection
First Launch (No Companies):
Welcome screen appears
Options: "Create Company" or "Join with Share Link"
Returning User:
Last selected company auto-selected (via @AppStorage("selectedCompanyID"))
Or tap different company from list
Selecting a Company:
Tap company row in list
App stores selection in AppStorage
Proceeds to login check
Step 4: UserPass Check
For the selected company, app checks:
If UserPass Exists:
Show login screen with username/password fields
Pre-fill username from UserPass
If UserPass Missing (shared company, first access):
func login() {
// Fetch UserPass for this company
let request: NSFetchRequest<UserPass> = UserPass.fetchRequest()
request.predicate = NSPredicate(
format: "companyID == %@ AND userName == %@ AND password == %@",
companyID as CVarArg,
enteredUsername,
enteredPassword
)
guard let userPass = try? viewContext.fetch(request).first else {
// Invalid credentials
showError = true
errorMessage = "Invalid username or password"
return
}
// Success
isAuthenticated = true
navigateToDashboard()
}
@AppStorage("selectedCompanyID") var selectedCompanyIDString: String = ""
var body: some View {
if selectedCompanyIDString.isEmpty {
// Show company selection
CompanyListView()
} else {
// Show main app
MainTabView()
}
}
@AppStorage("selectedCompanyID") var selectedCompanyIDString: String = ""
@State private var isAuthenticated: Bool = false
@State private var currentCompany: Companies?
@State private var currentUserPass: UserPass?
@State private var currentAccessControl: AccessControl?