-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathForecaster.swift
273 lines (230 loc) · 9.32 KB
/
Forecaster.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
//
// Forecaster.swift
// SwiftWeather
//
// Created by Chris Slowik on 2/14/17.
// Copyright © 2017 Chris Slowik. All rights reserved.
//
import Foundation
import Alamofire
import CoreLocation
class Forecaster: NSObject, CLLocationManagerDelegate {
// properties
var currTemperature : Double = 0
var temperatureString : String = ""
var weatherLocation : String = ""
var weatherString : String = ""
var weatherIcon : String = ""
var apiKey : String
let locationManager: CLLocationManager = CLLocationManager()
var locationObject: CLLocation?
init(yourKey: String) {
// set the API Key
apiKey = yourKey
// super init!!
super.init()
// initialize locationManager
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
// if its ios8
if ( NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1 ) {
locationManager.requestWhenInUseAuthorization()
}
locationManager.startUpdatingLocation()
//println("started updating")
}
func updateWeatherInfo(_ latitude: CLLocationDegrees, longitude: CLLocationDegrees) {
let url = "http://api.openweathermap.org/data/2.5/weather?lat=\(latitude)&lon=\(longitude)&APPID=\(apiKey)"
//let params = ["lat":latitude, "lon":longitude, "APPID":apiKey] as [String : Any]
//print(params)
Alamofire.request(url).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
if let data = response.result.value{
print(data)
self.updateWeatherSuccess(data as! NSDictionary)
NotificationCenter.default.post(name: Notification.Name(rawValue: "weatherHasUpdated"), object: nil)
}
break
case .failure(_):
print(response.result.error!)
break
}
}
}
// update properties
func updateWeatherSuccess(_ jsonResult: NSDictionary!) {
//self.loading.text = nil
//self.loadingIndicator.hidden = true
//self.loadingIndicator.stopAnimating()
// If the temperature is able to be read, assume the rest of the json is there too.
if let tempResult = ((jsonResult["main"] as! NSDictionary)["temp"] as? Double) {
var temperature: Double
//self.weatherLocation = (jsonResult["name"] as String) this crap is broken! free api...
if let sys = (jsonResult["sys"] as? NSDictionary) {
if let country = (sys["country"] as? String) {
if (country == "US") {
// Convert temperature to Fahrenheit if user is within the US
temperature = round(((tempResult - 273.15) * 1.8) + 32)
}
else {
// Otherwise, convert temperature to Celsius
temperature = round(tempResult - 273.15)
}
// Set the temperature property
currTemperature = temperature
temperatureString = "\(Int(temperature))°"
}
if let weather = jsonResult["weather"] as? NSArray {
let condition = (weather[0] as! NSDictionary)["id"] as! Int
let sunrise = sys["sunrise"] as! Double
let sunset = sys["sunset"] as! Double
// removing ability to check for night, pending response from openweathermap support
// sunrise/sunset numbers appear to reset before sunset local, giving false indicator of night
let isNight = false
let now = Date().timeIntervalSince1970
print(sunrise)
print(sunset)
print(now)
//if (now < sunrise || now > sunset) {
// isNight = true
//}
self.updateWeather(condition, isNight: isNight)
return
}
}
}
weatherString = "Unavailable!"
weatherIcon = "partly-cloudy"
temperatureString = "--"
currTemperature = 0
}
// converts a received weather condition to an icon name.
// documentation: http://bugs.openweathermap.org/projects/api/wiki/Weather_Condition_Codes
func updateWeather(_ condition: Int, isNight: Bool) {
//thunderstorms
if (condition < 300) {
self.weatherIcon = "thunderstorm"
self.weatherString = "Thunderstorm"
}
// light rain
else if (condition < 500) {
self.weatherIcon = "light-rain"
self.weatherString = "Light Rain"
}
//rain
else if (condition < 600) {
self.weatherIcon = "rain"
self.weatherString = "Rain"
if (condition >= 502 && condition < 510) {
self.weatherIcon = "heavy-rain"
self.weatherString = "Heavy Rain"
}
}
//snow
else if (condition < 700) {
self.weatherIcon = "snow"
self.weatherString = "Snow"
if (condition == 611) {
self.weatherIcon = "sleet"
self.weatherString = "Sleet"
}
}
// fog and other conditions
else if (condition < 771) {
self.weatherIcon = "fog"
self.weatherString = "Fog"
}
// tornado, squall
else if (condition < 800) {
self.weatherIcon = "tornado"
self.weatherString = "Tornado"
}
// clear
else if (condition == 800) {
if (isNight){
self.weatherIcon = "clear-night"
self.weatherString = "Clear Night"
}
else {
self.weatherIcon = "clear-day"
self.weatherString = "Clear Sky"
}
}
// partly cloudy
else if (condition < 804) {
if (isNight) {
self.weatherIcon = "partly-cloudy-night"
}
else {
self.weatherIcon = "partly-cloudy"
}
self.weatherString = "Partly Cloudy"
}
// cloudy
else if (condition == 804) {
self.weatherIcon = "cloudy"
self.weatherString = "Cloudy"
}
// another tornado check!
else if (condition == 900) {
self.weatherIcon = "tornado"
self.weatherString = "Tornado"
}
// hurricane
else if (condition == 901 || condition == 902) {
self.weatherIcon = "hurricane"
self.weatherString = "Hurricane"
}
// cold
else if (condition == 903) {
self.weatherIcon = "snow"
self.weatherString = "Very Cold"
}
// hot
else if (condition == 904) {
self.weatherIcon = "clear-day"
self.weatherString = "Very Hot"
}
// wind
else if (condition == 905) {
self.weatherIcon = "wind"
self.weatherString = "Windy"
}
// hail
else if (condition == 906) {
self.weatherIcon = "hail"
self.weatherString = "Hail"
}
// Weather condition is not available
else {
self.weatherIcon = ""
self.weatherString = "unavailable"
}
}
func updateLocationName(_ currentPlacemark : CLPlacemark) {
weatherLocation = currentPlacemark.locality!
print("location")
if (weatherIcon != "") { NotificationCenter.default.post(name: Notification.Name(rawValue: "weatherHasUpdated"), object: nil) }
}
//CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location:CLLocation = locations[locations.count-1]
if (location.horizontalAccuracy > 0) {
locationObject = location
locationManager.stopUpdatingLocation()
updateWeatherInfo(location.coordinate.latitude, longitude: location.coordinate.longitude)
// get the city name
CLGeocoder().reverseGeocodeLocation(location, completionHandler:
{(placemarks, error) in
if (error != nil) {print("reverse geocode fail: \(error!.localizedDescription)")}
let pm = placemarks! as [CLPlacemark]
if pm.count > 0 { self.updateLocationName(placemarks![0] as CLPlacemark) }
})
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
//self.loading.text = "Can't get your location!"
}
}