SwiftUI Unleashed: Creating a Simple Weather App
Welcome back, iOS developers! In our ongoing exploration of SwiftUI, we've seen how its declarative syntax, data binding, and layout system are transforming the way we build UIs for Apple platforms. But now, it's time to put theory into practice. In this guide, we'll create a simple Weather App, highlighting SwiftUI's capabilities while subtly illustrating how efficiently you can build apps with this powerful UI framework.
Setting the Stage
Let's begin by imagining the app. Our weather app will fetch data from a weather API, display today's weather, and forecast the next five days' weather. While building this, we'll utilize data binding, API calls, SwiftUI views, and navigation.
Before starting, add the Swift Package 'Alamofire' to your Xcode project for managing our network requests.
Building the Model
We'll start by creating the model for our weather data. For brevity, our model will only contain temperature and weather description.
struct Weather: Decodable {
let temperature: Double
let weatherDescription: String
enum CodingKeys: String, CodingKey {
case temperature = "temp"
case weatherDescription = "weather"
}
}
Fetching Weather Data
Let's create a WeatherService
class to fetch the weather data from the API:
import Alamofire
class WeatherService {
func fetchWeather(completion: @escaping (Weather) -> Void) {
AF.request("https://api.weatherapi.com/v1/forecast.json?key=YOUR_API_KEY&q=SanFrancisco&days=5").responseJSON { response in
if let data = response.data {
let decoder = JSONDecoder()
if let weatherResponse = try? decoder.decode(Weather.self, from: data) {
completion(weatherResponse)
}
}
}
}
}
Replace "YOUR_API_KEY"
with your actual Weather API key.
Building the UI
With the model and service set up, let's now create our app's main view:
struct ContentView: View {
@ObservedObject var viewModel = WeatherViewModel()
var body: some View {
NavigationView {
VStack(alignment: .center, spacing: 10) {
Text("Today: \(viewModel.weather?.temperature ?? 0)°")
.font(.largeTitle)
Text(viewModel.weather?.weatherDescription ?? "")
.font(.title)
List(viewModel.forecast) { day in
Text("Day \(day.day): \(day.temperature)°")
}
}
.navigationBarTitle("San Francisco")
}
.onAppear {
self.viewModel.fetchWeather()
}
}
}
Our ContentView
includes a NavigationView
with a VStack
. The VStack
displays today's temperature and description, and a list of the forecast for the next five days.
Creating the ViewModel
Our WeatherViewModel
will be responsible for calling WeatherService
to fetch weather data:
class WeatherViewModel: ObservableObject {
@Published var weather: Weather?
@Published var forecast: [Weather] = []
let weatherService = WeatherService()
func fetchWeather() {
weatherService.fetchWeather { weather in
DispatchQueue.main.async {
self.weather = weather
// Assume the first day is today, and the remaining days are the forecast.
self.forecast = Array(weather.dropFirst())
}
}
}
}
Conclusion
Congratulations, you've just built a simple SwiftUI weather app that fetches and displays data from an API. This project highlights SwiftUI's ease of use and efficiency, but it only scratches the surface of what's possible.
If you're excited about the potential of SwiftUI and are considering building an iOS application, remember you don't have to do it alone. As an independent iOS developer, I've helped countless clients bring their ideas to life, and I'm ready to assist you on your journey. From brainstorming to deployment, I can provide the support you need to make your app a success. Feel free to contact me to discuss your project. Let's create something amazing together!
Looking to create an impressive SwiftUI application? Get in touch to discuss how we can utilize SwiftUI to transform your app vision into a delightful user experience.
Have been looking for this info for quite a while