-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathKrakowPiosDataLoader.swift
127 lines (99 loc) · 3.92 KB
/
KrakowPiosDataLoader.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//
// KrakowPiosDataLoader.swift
// SmogWatch WatchKit Extension
//
// Created by Kuba Suder on 23.12.2018.
// Copyright © 2018 Kuba Suder. Licensed under WTFPL license.
//
import Foundation
import WatchKit
private let DataURL = "http://monitoring.krakow.pios.gov.pl/dane-pomiarowe/pobierz"
private struct Response: Decodable {
let data: ResponseData
struct ResponseData: Decodable {
let series: [DataSeries]
struct DataSeries: Decodable {
enum CodingKeys: String, CodingKey {
case points = "data"
}
let points: [DataPoint]
struct DataPoint: Decodable {
let date: Date
let value: Double
struct InvalidValueError: Error {}
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
if let timestamp = try Int(container.decode(String.self)) {
self.date = Date(timeIntervalSince1970: TimeInterval(timestamp))
} else {
throw InvalidValueError()
}
if let value = try Double(container.decode(String.self)) {
self.value = value
} else {
throw InvalidValueError()
}
}
}
}
}
}
class KrakowPiosDataLoader {
let dateFormatter: DateFormatter = {
let d = DateFormatter()
d.locale = Locale(identifier: "en_US_POSIX")
d.dateFormat = "dd.MM.yyyy"
d.timeZone = TimeZone(identifier: "Europe/Warsaw")!
return d
}()
let session: URLSession = {
let config = URLSessionConfiguration.ephemeral
config.timeoutIntervalForResource = 10.0
return URLSession(configuration: config)
}()
let dataStore = DataStore()
func queryString() -> String {
let query: [String:Any] = [
"measType": "Auto",
"viewType": "Parameter",
"dateRange": "Day",
"date": dateFormatter.string(from: Date()),
"viewTypeEntityId": "pm10",
"channels": [148]
]
let jsonData = try! JSONSerialization.data(withJSONObject: query, options: [])
let json = String(data: jsonData, encoding: .utf8)!
return "query=\(json)"
}
func fetchData(_ completion: @escaping (Bool) -> ()) {
var request = URLRequest(url: URL(string: DataURL)!)
request.httpBody = queryString().data(using: .utf8)!
request.httpMethod = "POST"
NSLog("KrakowPiosDataLoader: sending request [state: %@] to %@ with %@ ...",
WKExtension.shared().applicationState.description, DataURL, queryString())
let task = session.dataTask(with: request) { (data, response, error) in
var success = false
NSLog("KrakowPiosDataLoader: response received: %@ %@ %@",
data != nil ? "\(data!.count) bytes" : "(nil)",
response != nil ? "\(response!)" : "(nil)",
error != nil ? "\(error!)" : "(no error)")
if let data = data {
if let response = try? JSONDecoder().decode(Response.self, from: data) {
if let series = response.data.series.first {
if let point = series.points.last {
self.dataStore.currentLevel = point.value
self.dataStore.lastMeasurementDate = point.date
NSLog("KrakowPiosDataLoader: saving data: %.0f at %@", point.value, "\(point.date)")
success = true
}
}
}
}
if !success {
NSLog("KrakowPiosDataLoader: no data found")
}
completion(success)
}
task.resume()
}
}