A comprehensive native iOS weather application built with SwiftUI that provides detailed weather forecasts, historical data comparison, and interactive visualizations.
- Current weather conditions with detailed metrics
- 7-day forecast with daily temperature ranges and conditions
- Hourly forecast with detailed breakdowns
- Weather data visualization with historical comparisons
- Interactive weather cards for each forecast day
- Location searching and current location detection
- Global location support with international weather data
- Detailed day view with extended information
- Weather alerts display
- Unit conversion (°C/°F) with regional defaults
- Responsive layout for all iOS devices
- Support for both National Weather Service API (US) and OpenWeather API (international)
- Offline mode with CoreData-based caching
- WidgetKit integration for home and lock screens
This project uses the MVVM (Model-View-ViewModel) architecture pattern:
- Models: Define data structures and business logic
- ViewModels: Manage state, business logic, and data transformation
- Views: SwiftUI components that present data to the user
- Services: Handle API communication and data persistence
ios-weather-dashboard/
├── WeatherApp/
│ ├── App/
│ │ ├── AppDelegate.swift # App delegate with background processing
│ │ └── WeatherApp.swift # Main app entry point
│ ├── Models/
│ │ ├── NWSModels.swift # NWS API specific models
│ │ ├── Weather.xcdatamodeld # CoreData model for persistence
│ │ └── WeatherModels.swift # Core data structures
│ ├── ViewModels/
│ │ ├── WeatherViewModel.swift # Core state management
│ │ ├── WeatherViewModel+Cache.swift # Caching functionality
│ │ ├── WeatherViewModel+CoreData.swift # CoreData integration
│ │ ├── WeatherViewModel+Alerts.swift # Weather alerts handling
│ │ ├── WeatherViewModel+BackgroundRefresh.swift # Background updating
│ │ └── WeatherViewModel+LocationIntegration.swift # Location handling
│ ├── Views/
│ │ ├── ContentView.swift # Main container view
│ │ ├── CurrentWeatherView.swift # Current conditions display
│ │ ├── WeatherCardView.swift # Daily forecast card
│ │ ├── WeatherChartView.swift # Data visualization
│ │ ├── LocationSelectorView.swift # Location picker UI
│ │ ├── LocationManagementView.swift # Saved locations management
│ │ ├── SavedLocationsView.swift # Saved locations display
│ │ └── WeatherDashboardView.swift # Main dashboard UI
│ ├── Services/
│ │ ├── WeatherService.swift # Weather data protocol
│ │ ├── WeatherAPIService.swift # API integration
│ │ ├── MockWeatherService.swift # Mock data for testing
│ │ ├── CoreDataManager.swift # Data persistence system
│ │ ├── WeatherAlertService.swift # Alert monitoring
│ │ └── LocationManager.swift # Location handling
│ └── Info.plist # App configuration
├── WeatherWidgetExtension/ # WidgetKit extension
│ ├── WeatherWidget.swift # Home screen widget
│ ├── WeatherLockScreenWidget.swift # Lock screen widget
│ ├── WidgetDataProvider.swift # Data provider for widgets
│ └── Info.plist # Widget configuration
├── WeatherAppTests/ # Unit tests
│ └── WeatherViewModelTests.swift # ViewModel tests
└── Documentation/ # Additional documentation
The application follows a reactive programming paradigm using Combine:
-
Data Flow:
- ViewModels expose
@Published
properties that the Views observe - Data changes trigger automatic UI updates through the observation system
- Services return
AnyPublisher
types for asynchronous operations
- ViewModels expose
-
Dependency Injection:
- Services are injected into ViewModels via constructors
- This allows for easier testing and swapping of implementations
-
Protocol-Based Design:
- Services implement protocols (e.g.,
WeatherServiceProtocol
) - Enables multiple implementations (production, mock) sharing common interfaces
- Services implement protocols (e.g.,
-
Error Handling:
- Robust error system with dedicated error types and handling logic
- Errors are propagated up and displayed in user-friendly formats
- Fallback to cached data when network requests fail
-
Data Persistence:
- CoreData-based persistence for weather data and user preferences
- Multi-tiered caching strategy with expiration policies
- Data migrations from legacy storage systems
- Core MVVM architecture setup
- Model definitions for weather data
- Main view implementations (current weather, cards, chart, location)
- Weather service with API integrations for US and international locations
- Location services with reliable country detection
- CoreData integration for robust data persistence
- Test suite with >85% code coverage
- User preferences system
- Location management with multiple saved locations
- Widget extension implementation
- International API integration with OpenWeather
- Background refresh implementation
- Enhanced location handling for non-US locations
- CoreData Integration: Replaced UserDefaults with a comprehensive CoreData persistence layer for better performance and data relationships
- Enhanced Location Handling: Implemented robust detection and handling of non-US locations with automatic API switching
- Comprehensive Testing Strategy: Added extensive unit, UI, and performance tests with >85% code coverage
- Widget Support: Completed full implementation of home screen and lock screen widgets
- Dynamic Island integration (iOS 16+)
- Dark mode optimizations
- Advanced charts for historical data
- Push notification handling for severe weather alerts
The project is being implemented in phases as outlined in the Implementation Roadmap:
- Phase 1: Core Functionality - API integration and architecture improvements
- Phase 2: UI Enhancements - Design system and view improvements
- Phase 3: Extensions and Features - Widgets and advanced features
- Phase 4: Testing and Refinement - Comprehensive testing and polishing
- Xcode 14.0+
- iOS 15.0+ (iOS 16.0+ recommended for all features)
- Swift 5.7+
- An API key from OpenWeather (for international data)
- Clone the repository:
git clone https://github.com/needsupport/ios-weather-dashboard.git
cd ios-weather-dashboard
- Open the project in Xcode:
open WeatherApp.xcodeproj
-
Configure API keys:
- Add your OpenWeather API key to the project
- You can set it using the ApiKeyManager in the app:
ApiKeyManager.shared.setOpenWeatherMapApiKey("YOUR_API_KEY")
- Or add it in the ApiKeyManager initialization in WeatherAPIService.swift for development
-
Set up App Groups for Widget Support:
- In Xcode, select the app target and go to "Signing & Capabilities"
- Add the "App Groups" capability
- Create a group identifier (e.g., "group.com.yourcompany.ios-weather-dashboard")
- Do the same for the Widget Extension target
- Update the group name in WeatherWidgetDataProvider if needed
-
Build and run the application on your device or simulator
For development without an API key:
- Navigate to
WeatherApp/ViewModels/WeatherViewModel.swift
- In the
init()
method, replaceself.weatherService = WeatherService()
withself.weatherService = MockWeatherService()
The project includes comprehensive testing:
- Unit Tests: For ViewModels, Services, and Models
- UI Tests: For critical user flows
- Performance Tests: For measuring and tracking app performance
- Snapshot Tests: For verifying UI visual consistency
Run the tests to verify:
- Data fetching and error handling
- Temperature unit conversion
- Icon mapping
- Location handling including international support
- Cache expiration behavior
- CoreData operations
The app implements several performance optimizations:
- Lazy loading of view components
- CoreData-based persistence with optimized fetch requests
- Conditional rendering to reduce view complexity
- Efficient redrawing of chart components
- Background task management for optimal battery usage
- Batch fetching for large result sets
- Strategic denormalization for widget access
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m 'Add some AmazingFeature'
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.