/WeatherForecast

Primary LanguageSwiftMIT LicenseMIT

WeatherForecast

License

Description

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.

Feature

Requirements

  • iOS 13.6
  • Xcode 11.6
  • Swift 5
  • Pod v1.9.3 or above

What I've done

  • 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

Run project

  • Navigate to project folder by cd your-project-directory
  • Run pod install
  • Open project workspace WeatherForecast.xcworkspace

MVP Concept

  • View & ViewController - delegates user interaction events to the Presenter and displays data passed by the Presenter
@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 the View 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 with Network 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
  }
})

Useful Resources

MVP & Other presentation patterns

License

Weather Forecast is released under the MIT license. See LICENSE for details.