-
Notifications
You must be signed in to change notification settings - Fork 0
Project Architecture
Comprehensive overview of AgriSense iOS application architecture, design patterns, and system organization.
AgriSense follows the MVVM (Model-View-ViewModel) architecture pattern with additional service layers for complex business logic. The application is built using SwiftUI and follows Apple's modern app development guidelines.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Presentation Layer β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β SwiftUI Views β β
β β β’ Dashboard β’ Marketplace β’ Crop Management β β
β β β’ AI Assistant β’ Community β’ Profile β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ViewModel Layer β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β @StateObject / @ObservableObject β β
β β β’ AppState β’ UserManager β’ CropManager β β
β β β’ CartManager β’ OrderManager β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Service Layer β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β’ LiveAIService β’ WeatherService β β
β β β’ EnhancedTTSService β’ VoiceTranscription β β
β β β’ GeminiAIService β’ MandiPriceService β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Model Layer β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β’ Crop β’ User β’ Order β’ Product β β
β β β’ WeatherData β’ MarketPrice β’ Community β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Infrastructure Layer β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Firebase β’ Cloudinary β’ APIs β’ Local Storage β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Purpose: Separation of concerns, testability, and maintainability
Implementation:
- Model: Data structures and business logic
- View: SwiftUI views with minimal logic
- ViewModel: Observable objects managing state and business logic
Example:
// Model
struct Crop: Identifiable, Codable {
let id: String
var name: String
var type: CropType
var healthStatus: HealthStatus
}
// ViewModel
class CropManager: ObservableObject {
@Published var crops: [Crop] = []
@Published var isLoading = false
func fetchCrops() async throws {
// Business logic
}
}
// View
struct CropListView: View {
@StateObject private var cropManager = CropManager()
var body: some View {
List(cropManager.crops) { crop in
CropRowView(crop: crop)
}
}
}Purpose: Abstract data layer and provide single source of truth
Implementation:
- Managers act as repositories
- Centralized data access
- Caching strategies
Example:
class UserManager: ObservableObject {
@Published var currentUser: User?
private let db = Firestore.firestore()
func fetchUser(id: String) async throws -> User {
// Fetch from Firebase
}
func updateUser(_ user: User) async throws {
// Update in Firebase
}
}Purpose: Encapsulate complex business logic and external integrations
Services:
-
LiveAIService: AI assistant orchestration -
GeminiAIService: Gemini API integration -
WeatherService: Weather data fetching -
EnhancedTTSService: Text-to-speech -
VoiceTranscriptionService: Speech-to-text -
MandiPriceService: Market price data
Used For: Shared resources and managers
Examples:
class LocalizationManager: ObservableObject {
static let shared = LocalizationManager()
private init() {}
}
class AudioSessionManager {
static let shared = AudioSessionManager()
private init() {}
}Implementation: Combine framework with @Published properties
class AppState: ObservableObject {
@Published var isAuthenticated = false
@Published var isDarkMode = false
@Published var selectedLanguage: String = "en"
}Used For: Model creation and initialization
struct AIContextBuilder {
static func buildContext(
conversationHistory: [Message],
screenContent: String?,
cameraFeed: UIImage?
) -> AIContext {
// Build and return context
}
}Used For: AI model selection and fallback
class GeminiAIService {
private var modelStrategy: [AIModel] = [
.flash2Experimental,
.flash2Thinking,
.flash15,
.pro15
]
func processWithFallback() async throws -> Response {
for model in modelStrategy {
do {
return try await process(with: model)
} catch {
continue // Try next model
}
}
throw AIError.allModelsFailed
}
}AgriSense(iOS)/
βββ Agrisense/
β βββ AgrisenseApp.swift # App entry point
β βββ GoogleService-Info.plist # Firebase config
β βββ Info.plist # App configuration
β β
β βββ Models/ # Data models & managers
β β βββ Crop.swift
β β βββ UserManager.swift
β β βββ CartManager.swift
β β βββ OrderManager.swift
β β βββ ProductManager.swift
β β βββ CropManager.swift
β β βββ WeatherData.swift
β β βββ MarketPrice.swift
β β βββ AppState.swift
β β βββ ...
β β
β βββ Views/ # SwiftUI views
β β βββ Dashboard/
β β β βββ DashboardView.swift
β β β βββ WeatherCard.swift
β β β βββ MandiPriceCard.swift
β β βββ Assistant/
β β β βββ LiveAIView.swift
β β β βββ VoiceIndicatorView.swift
β β βββ Marketplace/
β β β βββ MarketplaceView.swift
β β β βββ ProductListView.swift
β β β βββ CartView.swift
β β βββ Authentication/
β β βββ Community/
β β βββ Profile/
β β βββ Components/ # Reusable components
β β
β βββ Services/ # Business logic services
β β βββ AI/
β β β βββ GeminiAIService.swift
β β β βββ AIModels.swift
β β β βββ AIContextBuilder.swift
β β βββ LiveAIService.swift
β β βββ EnhancedTTSService.swift
β β βββ VoiceTranscriptionService.swift
β β βββ WakeWordDetectionService.swift
β β βββ WeatherService.swift
β β βββ MandiPriceService.swift
β β βββ CameraService.swift
β β βββ WebSearchService.swift
β β
β βββ Utils/ # Utility classes
β β βββ NetworkMonitor.swift
β β βββ SecureStorage.swift
β β βββ ErrorHandling.swift
β β βββ ImageCompression.swift
β β βββ AudioSessionManager.swift
β β βββ ...
β β
β βββ CoreKit/ # Core functionality
β β βββ LocalizationManager.swift
β β
β βββ Assets.xcassets/ # Images and assets
β βββ Localization/ # Multi-language support
β βββ en.lproj/
β βββ hi.lproj/
β βββ bn.lproj/
β βββ ta.lproj/
β βββ te.lproj/
β
βββ AgrisenseTests/ # Unit tests
βββ AgrisenseUITests/ # UI tests
βββ Screenshots/ # App screenshots
βββ Agrisense.xcodeproj/ # Xcode project
ββββββββββββββββ
β LoginView β
ββββββββ¬ββββββββ
β User enters credentials
β
ββββββββββββββββ
β UserManager β
ββββββββ¬ββββββββ
β Firebase Auth
β
ββββββββββββββββ
β Firebase β
ββββββββ¬ββββββββ
β Auth Token
β
ββββββββββββββββ
β AppState β Updates isAuthenticated
ββββββββ¬ββββββββ
β
β
ββββββββββββββββ
β DashboardViewβ Navigates to main view
ββββββββββββββββ
ββββββββββββββββββββ
β LiveAIView β
ββββββββββ¬ββββββββββ
β User speaks
β
ββββββββββββββββββββββ
β WakeWordDetection β Detects "Krishi AI"
ββββββββββ¬ββββββββββββ
β Activates listening
β
ββββββββββββββββββββββ
βVoiceTranscription β Converts speech to text
ββββββββββ¬ββββββββββββ
β Transcribed text
β
ββββββββββββββββββββββ
β LiveAIService β Orchestrates AI logic
ββββββββββ¬ββββββββββββ
β Builds context
β
ββββββββββββββββββββββ
β GeminiAIService β Sends to Gemini API
ββββββββββ¬ββββββββββββ
β AI response
β
ββββββββββββββββββββββ
β EnhancedTTSService β Converts text to speech
ββββββββββ¬ββββββββββββ
β Plays audio
β
ββββββββββββββββββββββ
β LiveAIView β Updates UI with response
ββββββββββββββββββββββ
ββββββββββββββββ
β AddCropView β
ββββββββ¬ββββββββ
β User adds crop
β
ββββββββββββββββ
β CropManager β Validates input
ββββββββ¬ββββββββ
β Upload image
β
ββββββββββββββββ
β Cloudinary β Returns image URL
ββββββββ¬ββββββββ
β Image URL
β
ββββββββββββββββ
β Firestore β Saves crop data
ββββββββ¬ββββββββ
β Success
β
ββββββββββββββββ
β CropManager β Updates @Published crops
ββββββββ¬ββββββββ
β
β
ββββββββββββββββ
β CropListView β Displays updated list
ββββββββββββββββ
-
Authentication Layer
- Firebase Authentication
- Secure token storage
- Biometric authentication support
-
Network Layer
- HTTPS only
- Certificate pinning
- Request encryption
-
Data Layer
- Encrypted local storage (Keychain)
- Firestore security rules
- Input validation
-
API Layer
- Rate limiting
- API key rotation
- Request signing
See Security Documentation for details.
- Images loaded on-demand
- Firestore pagination
- Lazy stacks in lists
- Weather data cached (30 min)
- Market prices cached (1 hour)
- Image caching with URLCache
- Image compression in background
- Async/await for network calls
- Background tasks for updates
- Weak references for delegates
- Image downsampling
- Proper deallocation
- Model validation
- Manager logic
- Utility functions
- User flows
- Navigation
- Form validation
- Firebase integration
- API communication
- Service interactions
See Testing Guide for details.
protocol APIService {
func fetch<T: Decodable>(_ endpoint: String) async throws -> T
}
class SecureNetworkManager: APIService {
private let session: URLSession
private let rateLimiter: RateLimiter
func fetch<T: Decodable>(_ endpoint: String) async throws -> T {
// Rate limiting
try await rateLimiter.checkLimit()
// Build request
let request = try buildRequest(endpoint)
// Execute with retry
return try await executeWithRetry(request)
}
}class RetryMechanism {
func executeWithRetry<T>(
maxAttempts: Int = 3,
delay: TimeInterval = 1.0,
operation: () async throws -> T
) async throws -> T {
for attempt in 1...maxAttempts {
do {
return try await operation()
} catch {
if attempt == maxAttempts { throw error }
try await Task.sleep(nanoseconds: UInt64(delay * 1_000_000_000))
}
}
throw NetworkError.maxRetriesExceeded
}
}// AppState.swift
class AppState: ObservableObject {
@Published var isAuthenticated = false
@Published var isDarkMode = false
@Published var selectedLanguage = "en"
@Published var currentUser: User?
}// CropManager.swift
class CropManager: ObservableObject {
@Published var crops: [Crop] = []
@Published var isLoading = false
@Published var error: Error?
}// CropDetailView.swift
struct CropDetailView: View {
@State private var isEditing = false
@State private var showAlert = false
}// App level
@main
struct AgrisenseApp: App {
@StateObject private var userManager = UserManager()
@StateObject private var appState = AppState()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(userManager)
.environmentObject(appState)
}
}
}
// View level
struct DashboardView: View {
@EnvironmentObject var userManager: UserManager
@EnvironmentObject var appState: AppState
}ContentView
βββ MainTabView
β βββ DashboardView
β β βββ WeatherCard
β β βββ MandiPriceCard
β β βββ CropSummaryCard
β βββ MarketplaceView
β β βββ ProductGrid
β β βββ CategoryFilter
β βββ LiveAIView
β β βββ VoiceIndicator
β β βββ TranscriptView
β βββ CommunityView
β βββ ProfileView
βββ Components (Shared)
βββ CustomButton
βββ LoadingView
βββ ErrorView
βββ ImagePicker
enum AnalyticsEvent {
case userSignUp
case cropAdded
case productPurchased
case aiQueryMade
}
class AnalyticsManager {
func track(_ event: AnalyticsEvent) {
// Firebase Analytics
}
}- Code Structure - Detailed file organization
- Services Architecture - Service layer details
- Firebase Integration - Backend integration
- AI & ML Integration - AI implementation
Questions? Check the FAQ or create an issue.