Skip to content

Instantly share code, notes, and snippets.

@pepicrft
Created September 13, 2016 08:59
Show Gist options
  • Select an option

  • Save pepicrft/23adc65ff7ff200aa84c8ec59b353800 to your computer and use it in GitHub Desktop.

Select an option

Save pepicrft/23adc65ff7ff200aa84c8ec59b353800 to your computer and use it in GitHub Desktop.
// 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