Add comprehensive error handling utilities for all screens
Created reusable error handling components that can be used across all screens in both Android and iOS apps to show retry/cancel dialogs when network calls fail. Android Components: - ApiResultHandler: Composable that automatically handles ApiResult states with loading indicators and error dialogs - HandleErrors(): Extension function for ApiResult to show error dialogs for operations that don't return display data - Updated ResidencesScreen to import ApiResultHandler iOS Components: - ViewStateHandler: SwiftUI view that handles loading/error/success states with automatic error alerts - handleErrors(): View modifier for automatic error monitoring - Both use the existing ErrorAlertModifier for consistent alerts Documentation: - Created ERROR_HANDLING.md with comprehensive usage guide - Includes examples for data loading and create/update/delete operations - Migration guide for updating existing screens - Best practices and testing guidelines These utilities make it easy to add consistent error handling with retry functionality to any screen that makes network calls, improving the user experience across the entire app. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
112
iosApp/iosApp/Helpers/ViewStateHandler.swift
Normal file
112
iosApp/iosApp/Helpers/ViewStateHandler.swift
Normal file
@@ -0,0 +1,112 @@
|
||||
import SwiftUI
|
||||
|
||||
/// A view that handles loading, error, and success states with automatic error alerts
|
||||
///
|
||||
/// Example usage:
|
||||
/// ```swift
|
||||
/// ViewStateHandler(
|
||||
/// isLoading: viewModel.isLoading,
|
||||
/// error: viewModel.errorMessage,
|
||||
/// onRetry: { viewModel.loadData() }
|
||||
/// ) {
|
||||
/// // Success content
|
||||
/// List(items) { item in
|
||||
/// Text(item.name)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
struct ViewStateHandler<Content: View>: View {
|
||||
let isLoading: Bool
|
||||
let error: String?
|
||||
let onRetry: () -> Void
|
||||
let content: Content
|
||||
|
||||
@State private var errorAlert: ErrorAlertInfo? = nil
|
||||
|
||||
init(
|
||||
isLoading: Bool,
|
||||
error: String?,
|
||||
onRetry: @escaping () -> Void,
|
||||
@ViewBuilder content: () -> Content
|
||||
) {
|
||||
self.isLoading = isLoading
|
||||
self.error = error
|
||||
self.onRetry = onRetry
|
||||
self.content = content()
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
if isLoading {
|
||||
ProgressView()
|
||||
.scaleEffect(1.5)
|
||||
} else {
|
||||
content
|
||||
}
|
||||
}
|
||||
.onChange(of: error) { errorMessage in
|
||||
if let errorMessage = errorMessage, !errorMessage.isEmpty {
|
||||
errorAlert = ErrorAlertInfo(message: errorMessage)
|
||||
}
|
||||
}
|
||||
.errorAlert(
|
||||
error: errorAlert,
|
||||
onRetry: {
|
||||
errorAlert = nil
|
||||
onRetry()
|
||||
},
|
||||
onDismiss: {
|
||||
errorAlert = nil
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Extension to add automatic error handling to any view
|
||||
extension View {
|
||||
/// Monitors an error message and shows error alert when it changes
|
||||
///
|
||||
/// Example usage:
|
||||
/// ```swift
|
||||
/// Form {
|
||||
/// // Form fields
|
||||
/// }
|
||||
/// .handleErrors(
|
||||
/// error: viewModel.errorMessage,
|
||||
/// onRetry: { viewModel.submitForm() }
|
||||
/// )
|
||||
/// ```
|
||||
func handleErrors(
|
||||
error: String?,
|
||||
onRetry: @escaping () -> Void
|
||||
) -> some View {
|
||||
modifier(ErrorHandlerModifier(error: error, onRetry: onRetry))
|
||||
}
|
||||
}
|
||||
|
||||
/// View modifier that handles errors automatically
|
||||
private struct ErrorHandlerModifier: ViewModifier {
|
||||
let error: String?
|
||||
let onRetry: () -> Void
|
||||
|
||||
@State private var errorAlert: ErrorAlertInfo? = nil
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
.onChange(of: error) { errorMessage in
|
||||
if let errorMessage = errorMessage, !errorMessage.isEmpty {
|
||||
errorAlert = ErrorAlertInfo(message: errorMessage)
|
||||
}
|
||||
}
|
||||
.errorAlert(
|
||||
error: errorAlert,
|
||||
onRetry: {
|
||||
errorAlert = nil
|
||||
onRetry()
|
||||
},
|
||||
onDismiss: {
|
||||
errorAlert = nil
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user