Commit f301fe0f by Dmitry Stepanets

Processing minutely API

parent 85443f4e
......@@ -3,54 +3,4 @@
uuid = "55281C35-FE9F-4CED-865E-FBED0E7393F6"
type = "0"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "BD6801C5-CD0B-467D-9B94-1250A8FA6E1D"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "BlendMinutelySource/BlendMinutelySource/BlendMinutelySource.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "49"
endingLineNumber = "49"
landmarkName = "getMinutelyForecast(forLocation:completion:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "A2A04C12-64A5-4FC6-A9A4-2CECEE6DBFE9"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "OneWeatherCore/OneWeatherCore/Model/LocationManager.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "378"
endingLineNumber = "378"
landmarkName = "updateMinutelyForecast(for:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "958DC1E7-7576-44D0-B8D7-5CD5ECB0CDC1"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "OneWeatherCore/OneWeatherCore/Model/LocationManager.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "318"
endingLineNumber = "318"
landmarkName = "updateEverythingIfNeeded()"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
......@@ -14,6 +14,7 @@ public enum BlendMinutelySourceError: Error {
case badServerResponse(Error?)
case dataEncodingError(String)
case alreadyBeingUpdated
case invalidParameters
}
public class BlendMinutelySource: MinutelyForecastSource {
......@@ -32,9 +33,19 @@ public class BlendMinutelySource: MinutelyForecastSource {
}()
//Public
#if DEBUG
public let healthUpdateInterval = TimeInterval(2 * 60) // 2 minutes
#else
public let healthUpdateInterval = TimeInterval(15 * 60) // 15 minutes
#endif
public init() {}
public func getMinutelyForecast(forLocation location: Location, completion: @escaping MinutelyForecastCompletion) {
guard location.region != nil, location.cityName != nil else {
completion(.failure(BlendMinutelySourceError.invalidParameters))
return
}
let endpointURL = URL(string: kEndpoitURL)!
let queryItems = [URLQueryItem(name: "lat", value: location.lat),
URLQueryItem(name: "lon", value: location.lon),
......@@ -82,16 +93,7 @@ public class BlendMinutelySource: MinutelyForecastSource {
do {
let blendForecast = try decoder.decode(BlendMinutelyForecast.self, from: forecastData)
let forecast = MinutelyForecast(lastUpdateTime: Date(),
forecastInterval: blendForecast.forecastInterval,
tempUnit: blendForecast.tempUnit,
windUnit: blendForecast.windUnit,
pressureUnit: blendForecast.pressureUnit,
forecast: blendForecast.forecast.map{ MinutelyItem(time: $0.time,
temp: $0.temp,
precipitation: $0.precipitation,
windSpeed: $0.windSpeed,
pressure: $0.pressure) })
let forecast = self.covnertToAppModel(itemToConvert: blendForecast)
completion(.success(forecast))
}
catch {
......@@ -100,4 +102,19 @@ public class BlendMinutelySource: MinutelyForecastSource {
}
.resume()
}
private func covnertToAppModel(itemToConvert: BlendMinutelyForecast) -> MinutelyForecast {
let items = itemToConvert.forecast.map { MinutelyItem(time: $0.time,
temp: .init(value: Double($0.temp), unit: .fahrenheit),
precipitation: $0.precipitation,
windSpeed: .init(value: Double($0.windSpeed), unit: .milesPerHour),
pressure: .init(value: Double($0.pressure), unit: .inchesOfMercury)) }
let minutelyForecast = MinutelyForecast(lastUpdateTime: Date(),
forecastInterval: itemToConvert.forecastInterval,
tempUnit: .fahrenheit,
windUnit: .milesPerHour,
pressureUnit: .inchesOfMercury,
forecast: items)
return minutelyForecast
}
}
......@@ -374,8 +374,22 @@ public class LocationManager {
}
public func updateMinutelyForecast(for location: Location) {
minutelyForecastSource.getMinutelyForecast(forLocation: location) { result in
print("Break")
if let lastTimeUpdated = location.minutely?.lastUpdateTime {
guard Date().timeIntervalSince(lastTimeUpdated) >= minutelyForecastSource.healthUpdateInterval else {
log.verbose("Update minutely forecast (\(location)): fresh enough (last updated at \(lastTimeUpdated)), skip update.")
return
}
}
log.info("Update minutely forecast for: \(location)")
minutelyForecastSource.getMinutelyForecast(forLocation: location) {[weak self] result in
guard let self = self else { return }
switch result {
case .success(let minutelyForecast):
self.make
case .failure(let error):
self.log.error("Update minutely (\(location) error: \(error)")
}
}
}
......
......@@ -7,15 +7,15 @@
import Foundation
public struct MinutelyForecast: Codable {
public struct MinutelyForecast {
public let lastUpdateTime: Date
public let forecastInterval: Int
public let tempUnit: Temperature
public let windUnit: WindSpeed
public let pressureUnit: Pressure
public let tempUnit: UnitTemperature
public let windUnit: UnitSpeed
public let pressureUnit: UnitPressure
public let forecast: [MinutelyItem]
public init(lastUpdateTime: Date, forecastInterval: Int, tempUnit: Temperature, windUnit: WindSpeed, pressureUnit: Pressure, forecast: [MinutelyItem]) {
public init(lastUpdateTime: Date, forecastInterval: Int, tempUnit: UnitTemperature, windUnit: UnitSpeed, pressureUnit: UnitPressure, forecast: [MinutelyItem]) {
self.lastUpdateTime = lastUpdateTime
self.forecastInterval = forecastInterval
self.tempUnit = tempUnit
......
......@@ -7,14 +7,14 @@
import Foundation
public struct MinutelyItem: Codable {
public struct MinutelyItem {
let time: Date
let temp: Int
let temp: Temperature
let precipitation: Double
let windSpeed: Int
let pressure: Int
let windSpeed: WindSpeed
let pressure: Pressure
public init(time: Date, temp: Int, precipitation: Double, windSpeed: Int, pressure: Int) {
public init(time: Date, temp: Temperature, precipitation: Double, windSpeed: WindSpeed, pressure: Pressure) {
self.time = time
self.temp = temp
self.precipitation = precipitation
......
......@@ -10,5 +10,7 @@ import Foundation
public typealias MinutelyForecastCompletion = (_ result: Result<MinutelyForecast, Error>) -> ()
public protocol MinutelyForecastSource {
var healthUpdateInterval: TimeInterval { get }
func getMinutelyForecast(forLocation location: Location, completion: @escaping MinutelyForecastCompletion)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment