12 KiB
12 KiB
Architecture Guide
Detailed architecture documentation for AppClientBaseSwift iOS application.
Overview
AppClientBaseSwift is a native iOS application built using MVVM (Model-View-ViewModel) architecture pattern with SwiftUI for declarative UI. The app follows Apple's modern development best practices including:
- Swift Concurrency (async/await)
- Combine for reactive data binding
- Protocol-oriented programming for testability
- Keychain Services for secure storage
Architecture Diagram
┌─────────────────────────────────────────────────────────────────────────┐
│ PRESENTATION LAYER │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ SwiftUI Views │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ SplashView │ │ HomeView │ │ ExploreView │ │ ProfileView │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ LoginView │ │RegisterView │ │ForgotPasswd │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ @StateObject / @EnvironmentObject │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ViewModels (@MainActor) │ │
│ │ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │ │
│ │ │ AuthViewModel │ │ HomeViewModel │ │ProfileViewModel│ │ │
│ │ └────────────────┘ └────────────────┘ └────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
Dependency Injection (Protocol-based)
┌─────────────────────────────────────────────────────────────────────────┐
│ SERVICE LAYER │
│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │
│ │ APIService │ │ AuthManager │ │
│ │ • request<T>() │ │ • @Published authState │ │
│ │ • get(), post() │ │ • login(), register() │ │
│ │ • URLSession │ │ • Keychain storage │ │
│ └─────────────────────────────┘ └─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ DATA LAYER │
│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │
│ │ Models │ │ Constants │ │
│ │ • User (Codable) │ │ • APIConfig │ │
│ │ • HomeItem │ │ • StorageKeys │ │
│ │ • AuthState │ │ • DesignSystem │ │
│ └─────────────────────────────┘ └─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
Component Details
1. Presentation Layer
Views
| Component | Responsibility |
|---|---|
SplashView |
Animated splash screen, delayed navigation |
ContentView |
Root TabView container, auth state routing |
AuthContainerView |
Auth flow navigation (Login/Register/Forgot) |
HomeView |
Home tab with greeting, promo, services |
ExploreView |
Discovery and search features |
ProfileView |
User profile and settings |
ViewModels
@MainActor
final class HomeViewModel: ObservableObject {
@Published var isLoading: Bool = false
@Published var items: [HomeItem] = []
@Published var errorMessage: String?
private let apiService: APIServiceProtocol
func loadData() async { ... }
}
2. Service Layer
APIService
HTTP client following Single Responsibility Principle:
protocol APIServiceProtocol {
func request<T: Decodable>(
endpoint: String,
method: HTTPMethod,
body: Encodable?,
headers: [String: String]?
) async throws -> T
}
Features:
- Generic request/response handling
- Automatic JSON encoding/decoding (snake_case ↔ camelCase)
- Bearer token injection
- HTTP status code handling
AuthManager
Singleton for authentication state:
final class AuthManager: ObservableObject {
@MainActor static let shared = AuthManager()
@Published var authState: AuthState = .unknown
}
AuthState Enum:
enum AuthState {
case unknown // Initial state
case unauthenticated // Logged out
case authenticated(User) // Logged in
}
Data Flow
sequenceDiagram
participant V as View
participant VM as ViewModel
participant S as Service
participant API as Backend API
V->>VM: User Action (button tap)
VM->>VM: Set isLoading = true
VM->>S: await service.request()
S->>API: HTTP Request
API-->>S: JSON Response
S-->>VM: Decoded Model
VM->>VM: Update @Published
VM-->>V: SwiftUI re-render
Authentication Flow
stateDiagram-v2
[*] --> Unknown: App Launch
Unknown --> Authenticated: Token Valid
Unknown --> Unauthenticated: No Token
Unauthenticated --> Login
Login --> Authenticated: Success
Login --> Register: Navigate
Register --> Authenticated: Success
Authenticated --> HomeScreen
HomeScreen --> Unauthenticated: Logout
Design Decisions
1. Why MVVM?
| Benefit | Description |
|---|---|
| Testability | ViewModel can be tested independently without UI |
| Separation of Concerns | View only displays, logic in ViewModel |
| SwiftUI Compatibility | @ObservableObject + @Published are native |
| Reactive Updates | Combine-based automatic UI refresh |
2. Why Protocol-based DI?
// Protocol enables mocking for tests
protocol APIServiceProtocol { ... }
// Production
final class APIService: APIServiceProtocol { ... }
// Test mock
final class MockAPIService: APIServiceProtocol { ... }
3. Why Keychain over UserDefaults?
| Keychain | UserDefaults |
|---|---|
| ✅ Encrypted at rest | ❌ Plain text |
| ✅ Secure enclave | ❌ Accessible |
| ✅ App-specific | ❌ Shared prefs |
4. Why @MainActor on ViewModels?
- Ensures all
@Publishedupdates happen on main thread - Prevents concurrency issues with SwiftUI
- Explicit thread safety contract
Security Architecture
┌────────────────────────────────────────────────────────────┐
│ SECURITY LAYERS │
├────────────────────────────────────────────────────────────┤
│ Layer 1: Transport Security (HTTPS/TLS) │
│ • All API calls use HTTPS │
├────────────────────────────────────────────────────────────┤
│ Layer 2: Token Security (Keychain) │
│ • Access token stored in Keychain │
│ • Refresh token stored in Keychain │
├────────────────────────────────────────────────────────────┤
│ Layer 3: Session Security │
│ • Token expiry validation │
│ • Automatic token refresh │
├────────────────────────────────────────────────────────────┤
│ Layer 4: Input Validation │
│ • Email format validation │
│ • Password strength checking │
└────────────────────────────────────────────────────────────┘
Future Considerations
| Feature | Priority | Description |
|---|---|---|
| Certificate Pinning | High | TLS certificate validation |
| Biometric Auth | High | Face ID / Touch ID login |
| Offline Mode | Medium | Local caching with SwiftData |
| Push Notifications | Medium | APNs integration |
Related Documentation
- README.md - Quick start guide