This project was built with the SwiftUI.
This app uses the OpenAPI library.
It also uses the first-party frameworks Charts, CoreLocation to serve clients
It is responsive and components are laid out with the user experience in mind.
This project allowed me to become a 'Contributor' to OpenMeteo/SDK.
I didn't do much, but it gave me the experience of creating and resolving an issue. open-meteo/sdk#66
- SwiftUI
- open-meteo Weather OpenAPI
- open-meteo Weather Library SDK
- SwiftUI AutoLayout
- Chart
- Pages with organized charts
- Chart Data Expression
- Swift Data Structure
- Peer Soft Skill
| image | image |
| image | image |
| image | image |
| Simulator Screen Recording - iPhone 15 - 2024年03月11日 at 19 44 24 |
var body: some View { Chart{ ForEach(weeklyData) { series in ForEach(series.temperatureData, id: \.day) { data in LineMark( x: .value("Day", data.day, unit: .day), y: .value("Temperature", data.temperature) ) .foregroundStyle(by: .value("TemperatureType", series.temperatureType)) .symbol(by: .value("TemperatureType", series.temperatureType)) .interpolationMethod(.catmullRom) } } if let selectedDate { RuleMark( x: .value("Selected", selectedDate, unit: .day) ) .foregroundStyle(Color.gray.opacity(0.3)) .zIndex(1) .annotation( position: .top, spacing: 0, overflowResolution: .init( x: .fit(to: .chart), y: .disabled ) ) { valueSelectionPopover } } } .chartForegroundStyleScale { colorTemperature[0ドル]! } .chartSymbolScale([ "Max Temperature": Circle().strokeBorder(lineWidth: 2), "Min Temperature": Square().strokeBorder(lineWidth: 2) ]) .chartXAxis { AxisMarks(values: .stride(by: .day)) { _ in AxisTick() AxisGridLine() AxisValueLabel(format: .dateTime.weekday(.abbreviated), centered: true) } } .chartXSelection(value: $rawSelectedDate) } // Mock data static let weeklydata: [WeatherSeries] = [ .init(temperatureType: "Max Temperature", temperatureData: [ (day: date(year: 2022, month: 5, day: 2), temperature: Float(15.3)), (day: date(year: 2022, month: 5, day: 3), temperature: Float(6.2)), (day: date(year: 2022, month: 5, day: 4), temperature: Float(19.1)), (day: date(year: 2022, month: 5, day: 5), temperature: Float(15.4)), (day: date(year: 2022, month: 5, day: 6), temperature: Float(4.5)), (day: date(year: 2022, month: 5, day: 7), temperature: Float(11)), (day: date(year: 2022, month: 5, day: 8), temperature: Float(19.9)) ]), .init(temperatureType: "Min Temperature", temperatureData: [ (day: date(year: 2022, month: 5, day: 2), temperature: Float(5.3)), (day: date(year: 2022, month: 5, day: 3), temperature: Float(-6.2)), (day: date(year: 2022, month: 5, day: 4), temperature: Float(9.1)), (day: date(year: 2022, month: 5, day: 5), temperature: Float(-15.4)), (day: date(year: 2022, month: 5, day: 6), temperature: Float(-4.5)), (day: date(year: 2022, month: 5, day: 7), temperature: Float(-11)), (day: date(year: 2022, month: 5, day: 8), temperature: Float(9.9)) ]), ] // Transformation Code private func prepareWeeklyData() -> [WeeklyWeatherData.WeatherSeries] { guard let weatherData = weatherManager.weatherData else { return [] } let maxTemperatureSeries = WeeklyWeatherData.WeatherSeries( temperatureType: "Max Temperature", temperatureData: weatherData.daily.time.indices.map { index in (day: weatherData.daily.time[index], temperature: weatherData.daily.temperature2mMax[index]) } ) let minTemperatureSeries = WeeklyWeatherData.WeatherSeries( temperatureType: "Min Temperature", temperatureData: weatherData.daily.time.indices.map { index in (day: weatherData.daily.time[index], temperature: weatherData.daily.temperature2mMin[index]) } ) return [maxTemperatureSeries, minTemperatureSeries] }