What's the weather? Building an Weather app on iOS with SwiftUI

Discover the journey of building a weather app in SwiftUI for iOS. Learn why SwiftUI was chosen over Storyboard and explore the app's architecture and features in this detailed breakdown.

What's the weather? Building an Weather app on iOS with SwiftUI

In this article, we will present you the process behind the design of this application that we named What's the weather? First, we will see the features of the application, why we chose SwiftUI and not storyboard, then we will see the architecture of the application and how it works, and the different services we had to use. At the end of this article, there is a demo of the application.

Features

When we launched the module, we received a clear and concise specification. From it, we were able to extract the basic functionalities which are the following:

  • Display the weather of a city with the weather according to the time, the 5 days forecast, the wind speed and direction, the temperature in celsius and Fahrenheit, the minimum and maximum temperatures as well as the pressure and humidity
  • Search for a city
  • Save and delete a city
  • List cities Beyond these features, we have chosen to implement geolocation and autocompletion when searching for a city.

Why SwiftUI?

Storyboard is very attractive when you start in iOS development because of the interface builder that allows you to design entire interfaces in drag and drop. By searching a little, we could notice very quickly that what often came back is the complexity induced by the use of Storyboard when the project becomes bigger. Having tried the Interface Builder, our first impression was that understanding it is like understanding Photoshop, there are so many tabs and buttons that you get lost. The interaction between the code and the storyboard is complicated. A string match will be used many times to link the code to the storyboard. In case there is a spelling error in the string, the application crashes during execution and not during compilation. Since we are using git, storyboard changes are complicated to track. Since the storyboards are not written in human-readable code, resolving merge conflicts is extremely difficult. After these misadventures with Storyboard, we tried SwiftUI, the first difference is that the interface is declarative so no more need for string matching to link the interface to the code. This implies that we will not be able to try to make a call to a deleted function that was linked by a string. Animations are easier to implement and above all, the application can be cross-platform (on all Apple platforms) because SwiftUI adapts the interface to the platform. Moreover, problems are detected at compile time and not during execution. Nevertheless, we had to make some concessions. SwiftUI is only usable from iOS 13.0. The community around SwiftUI is quite young and it is currently difficult to find help.

Architecture

For the architecture of our project, we chose to start with MVVM (Model View ViewModel) because we all had some basic knowledge of MVC architecture but we wanted to avoid code with interdependencies. We split our code into 4 main parts:

  • Models (structs)
  • The abstractions of the API calls (TeleportApi and OpenWeatherApi)
  • The ViewModels (classes that contain all the logic of the application)
  • The Views which are the components defining the interface of the application

The Views retrieve the data from the ViewModels which contain all the logic. The ViewModels execute the abstractions of the API calls to retrieve the data. The models are used to store the data retrieved from the API calls. Moreover, we followed an Apple tutorial where it was recommended to have only one data source to avoid unpacking between different data sources. So we grouped all the functions that allow creating, modification, or deleting a city in a single class that we named CityStore and grouped the functions that allow us to search a city in another class named CitySearchViewModel.

MVVM Pattern illustration - source

We store the list of cities in an array except for the city where the user is geolocated. We write this list in a file which is then loaded at the start of the application.

How it works

Since we have a data persistence layer in the application, when we launch it, we check if the data file exists, if it doesn't exist or if there was an error reading it, we continue running the application. At the same time, we ask for authorization to use the geolocation. The home screen of the application is the screen displaying the city at the user's location. From there we slide from one screen to another to display the cities. We have a navigation bar at the bottom of the screen with a button to access the city management screen and another to access a weather map embedded in a WebView. On the city management screen, there is a list of cities, we can delete them and reorganize them. In addition to that, you can change the unit of measurement of the application. We can switch from imperial to metric units. There is a search bar that allows you to search for a city, visualize the weather at this position and add it to the list of saved cities.

Services and libraries used

To retrieve the weather, we used the OpenWeather API which provides data on several days and also hour by hour. On the side of the auto-completion and the search of the city based on latitude and longitude, we used the Teleport API. For animations based on the current weather, we used the Lottie library. Finally, for HTTP requests, we used the Alamofire library.

Demo

Source code

The source code is available on GitLab.
To launch the project you have to get an API key from OpenWeather and add it to /Networkings/OpenWeatherApi.swift

I hope this helped you understand how Gryzle is born. If you have any questions, please send me a little message. I will be happy to help you. If you liked this article, please show some love and share it with your friends. Thank you for reading!