A sample weather app built with WeatherKit API, demonstrating Clean Architecture and SwiftUI.
- Display weather for current location or searched cities
- Hourly and daily weather forecasts
- 2D/3D weather data visualizations using Swift Charts
- Mock data support for development and testing
- iOS 26.2+ / macOS 26.2+
- Xcode 26.2+
- Swift 6.0+
- Apple Developer account with WeatherKit capability enabled
git clone https://github.com/Koshimizu-Takehito/WeatherKitSamples.git
cd WeatherKitSamples
make setup- Add WeatherKit capability to your App ID in the Apple Developer Portal
- Open the project in Xcode and configure Signing & Capabilities
make open # Open project in XcodeOr open WeatherKitSamples.xcodeproj directly in Xcode.
To run without WeatherKit configuration, switch to mock mode with AppDependencies(isMockDataEnabled: true).
This project follows a 3-layer Clean Architecture pattern.
┌─────────────────────────────────────────────────────────┐
│ Presentation Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ Views │ │ ViewModels │ │ Charts │ │
│ │ (SwiftUI) │ │ (@Observable)│ │ (Swift Charts) │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└───────────────────────────┬─────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────┐
│ Domain Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ Entities │ │ Interfaces │ │ Use Cases │ │
│ │ │ │ (Protocols) │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└───────────────────────────┬─────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────┐
│ Data Layer │
│ ┌─────────────────────┐ ┌─────────────────────────┐ │
│ │ DataSources │ │ Repositories │ │
│ │ (WeatherKit / Mock) │ │ │ │
│ └─────────────────────┘ └─────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
WeatherKitSamples/
├── App/ # Application entry point & DI
├── Core/
│ ├── Extensions/ # Environment keys, UI helpers
│ └── WeatherFormatters.swift # Formatting utilities
├── Domain/
│ ├── Entities/ # Domain models
│ ├── Interfaces/ # Repository protocols
│ └── UseCases/ # Business logic
├── Data/
│ ├── DataSources/ # API clients (WeatherKit / Mock)
│ └── Repositories/ # Repository implementations
└── Presentation/
├── Home/ # Home screen
├── Weather/ # Weather detail screens
├── Location/ # Location search screen
└── Charts/ # Weather charts (2D/3D)
make setup # Install dependencies
make build # Build for iOS Simulator
make build-macos # Build for macOS
make lint # Run SwiftLint
make format # Format code with SwiftFormat
make fix # Run lint-fix + format
make ci # Run all CI checks
make clean # Clean build artifactsThis project uses SwiftLint and SwiftFormat.
// Separate struct definition from View conformance
struct HomeView {
@Environment(HomeViewModel.self) private var viewModel
}
extension HomeView: View {
var body: some View {
Group(content: contentView)
.toolbar(content: toolbarContent)
}
}@MainActor
@Observable
final class HomeViewModel {
enum State {
case initial, loading, loaded(WeatherEntity), error(String)
}
private(set) var state: State = .initial
func fetchWeather() async { ... }
}// Inject ViewModel via Environment
ContentView()
.dependencies(AppDependencies(isMockDataEnabled: false))This project is licensed under the MIT License - see the LICENSE file for details.