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
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() |
varbody:someView{Chart{ForEach(weeklyData){ series inForEach(series.temperatureData, id: \.day){ data inLineMark(
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)}}iflet 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)){ _ inAxisTick()AxisGridLine()AxisValueLabel(format:.dateTime.weekday(.abbreviated), centered:true)}}.chartXSelection(value: $rawSelectedDate)}
// Mock data
staticletweeklydata:[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
privatefunc prepareWeeklyData()->[WeeklyWeatherData.WeatherSeries]{guardlet weatherData = weatherManager.weatherData else{return[]}letmaxTemperatureSeries=WeeklyWeatherData.WeatherSeries(
temperatureType:"Max Temperature",
temperatureData: weatherData.daily.time.indices.map{ index in(day: weatherData.daily.time[index], temperature: weatherData.daily.temperature2mMax[index])})letminTemperatureSeries=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]}





