Created
September 13, 2016 08:59
-
-
Save pepicrft/23adc65ff7ff200aa84c8ec59b353800 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Constants.swift | |
| import Foundation | |
| internal enum Keys: String { | |
| case Forecast | |
| } | |
| //ForecastEntity.swift | |
| import Foundation | |
| import ForecastKit | |
| public struct ForecastEntity { | |
| public var summary: String = "" | |
| public var temperature: Float = 0.0 | |
| } | |
| // MARK: - Init | |
| internal extension ForecastEntity { | |
| init(forecast: Forecast) { | |
| self.summary = forecast.summary | |
| self.temperature = forecast.temperature | |
| } | |
| } | |
| // MARK: - Data | |
| internal extension ForecastEntity { | |
| internal func toData() -> Data { | |
| var dictionary: [String: AnyObject] = [:] | |
| dictionary["temperature"] = self.temperature as AnyObject? | |
| dictionary["summary"] = self.summary as AnyObject? | |
| return try! JSONSerialization.data(withJSONObject: dictionary, options: []) | |
| } | |
| internal init?(data: Data) { | |
| guard let object = try? JSONSerialization.jsonObject(with: data, options: []), | |
| let dictionary: [String: AnyObject] = object as? [String: AnyObject], | |
| let temperature = dictionary["temperature"] as? Float, | |
| let summary = dictionary["summary"] as? String else { return nil } | |
| self.temperature = temperature | |
| self.summary = summary | |
| } | |
| } | |
| // WeatherObservable.swift | |
| import Foundation | |
| public class WeatherObservable: NSObject { | |
| // MARK: - Attributes | |
| internal let userDefaults: UserDefaults | |
| internal let observer: (ForecastEntity) -> Void | |
| // MARK: - Init | |
| public init(userDefaults: UserDefaults = UserDefaults.standard, observer: @escaping (ForecastEntity) -> Void) { | |
| self.userDefaults = userDefaults | |
| self.observer = observer | |
| super.init() | |
| self.userDefaults.addObserver(self, | |
| forKeyPath: Keys.Forecast.rawValue, | |
| options: NSKeyValueObservingOptions.new, | |
| context: nil) | |
| } | |
| public override func observeValue(forKeyPath keyPath: String?, | |
| of object: Any?, | |
| change: [NSKeyValueChangeKey : Any]?, | |
| context: UnsafeMutableRawPointer?) { | |
| self.notifyObserverIfData() | |
| } | |
| private func notifyObserverIfData() { | |
| guard let data = self.userDefaults.value(forKey: Keys.Forecast.rawValue) as? Data, | |
| let forecast = ForecastEntity(data: data) else { return } | |
| DispatchQueue.main.async { [weak self] in | |
| self?.observer(forecast) | |
| } | |
| } | |
| // MARK: - Private | |
| deinit { | |
| self.userDefaults.removeObserver(self, forKeyPath: Keys.Forecast.rawValue) | |
| } | |
| } | |
| // WeatherService.swift | |
| import Foundation | |
| import ForecastKit | |
| import LocationKit | |
| import CoreLocation | |
| public class WeatherService { | |
| // MARK: - Properties | |
| internal let locationManager: LocationManager | |
| internal let forecastClient: ForecastClient | |
| internal let userDefaults: UserDefaults | |
| // MARK: - Init | |
| public init(appKey: String, userDefaults: UserDefaults = UserDefaults.standard) { | |
| self.locationManager = LocationManager() | |
| self.forecastClient = ForecastClient(appKey: appKey) | |
| self.userDefaults = userDefaults | |
| } | |
| // MARK: - Public | |
| public func sync(completion: @escaping (Error?) -> Void) { | |
| self.locationManager.authorize { [weak self] status in | |
| if status != .authorizedWhenInUse { return } | |
| self?.locationManager.location(observer: { [weak self] (location) in | |
| let latitude = Double(location.coordinate.latitude) | |
| let longitude = Double(location.coordinate.longitude) | |
| self?.forecastClient.fetch(latitude: latitude, longitude: longitude, completion: { (forecast, error) in | |
| if let forecast = forecast { | |
| self?.save(forecast: forecast) | |
| } | |
| completion(error) | |
| }) | |
| }) | |
| } | |
| } | |
| // MARK: - Private | |
| private func save(forecast: Forecast) { | |
| let data = ForecastEntity(forecast: forecast).toData() | |
| self.userDefaults.setValue(data, forKey: Keys.Forecast.rawValue) | |
| self.userDefaults.synchronize() | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment