WeatherForecast is an iOS application built on MVP (Model View Presenter) concept
Application support people search weather in whole city in the world in next 7 days.
- iOS 13.6
- Xcode 11.6
- Swift 5
- Pod v1.9.3 or above
- Written by Swift.
- Able to retrieve the weather information from OpenWeatherMaps API.
- Allow user to input the searching term.
- Able to proceed searching with a condition of the search term length more than 3 characters
- Render the searched results as a list of weather items.
- Support cache and preventing bunch of API request when user searh city
- Manage caching mechanism & lifecycle.
- Handle failures for internet connection and request error
- Support the disability to scale large text
- Support the disability to read out the text
- Test Coverage: 60% code of the app
- Navigate to project folder by
cd your-project-directory
- Run
pod install
- Open project workspace
WeatherForecast.xcworkspace
View & ViewController
- delegates user interaction events to thePresenter
and displays data passed by thePresenter
@objc func reload(_ searchBar: UISearchBar) {
guard let query = searchBar.text, query.trimmingCharacters(in: .whitespaces) != "", query.count > 3 else {
return
}
self.presenter.loadWeatherForecast(query)
}
Presenter
- contains the presentation logic as call api and so on then tells theView
what to present
func loadWeatherForecast(_ city: String) {
// Check internet connection
guard InternetConnection.isConnectedToInternet() else {
self.view?.showReachabilityAlert()
return
}
self.view?.startLoading()
apiManager.fetchForeCastWeatherFromCity(city, successCallback: { [weak self] weatherItems in
guard let self = self else { return }
self.view?.finishLoading()
self.view?.refreshView(weatherItems)
}) { [weak self] error in
guard let self = self else { return }
self.view?.finishLoading()
self.view?.showDownloadErrorAlert(error: error)
}
}
Model
- communicates withNetwork
layer
AF.request(urlRequest).responseDecodable(of: WeatherForecast.self, completionHandler: { response in
switch response.result {
case .success:
guard let weatherForecast = response.value else { return }
self.cache.insert(weatherForecast.listWeatherItems, forKey: city.lowercased(), lifeTime: self.cacheLifeTime())
successCallback(weatherForecast.listWeatherItems)
case .failure:
guard let error = response.error?.underlyingError else { return }
errorCallback(error)
break
}
})
Weather Forecast is released under the MIT license. See LICENSE for details.