'self' captured by a closure before all members were initialized
You have two options, declare the properties as optionals, or initialize them with a default value (this means they will be non-optionals)
var temp: Float?
var condition: String?
var wind: Float?
var precip: Float?
or
var temp: Float=0
var condition: String=""
var wind: Float=0
var precip: Float=0
I'd hazard to guess that your are running into a concurrency problem. You are probably trying to access your object's properties before the asynchronous call to the DarkSkyClient returns (my apologies in advance if I got this wrong). i.e., the order of events is...
- Weather object is initialized, setting temp to 0
- Call to DarkSkyClient begins, runs in the background
- Read temp variable - hey, it's 0!
- Call to DarkSkyClient completes, sets the temp to the value you really wanted. Bad
So what you really need to do is switch to an inversion of control pattern:
class Weather {
var temp: Float
var condition: String
var wind: Float
var precip: Float
init(forecast: Forecast) {
temp = (forecast.currently?.temperature)!
condition = (forecast.currently?.summary)!
wind = (forecast.currently?.windSpeed)!
precip = (forecast.currently?.precipitationProbability)!
}
static func getWeather() {
DarkSkyClient(apiKey: "<api key>").getForecast(latitude: Utils().getLat(), longitude: Utils().getLong()) { result in
switch result {
case .success(let currentForecast, _):
let weather = Weather(forecast: currentForecast)
// Display the weather somewhere
doSomethingWith(weather: weather)
case .failure(let error):
print(error)
}
}
}
}
If you're not familiar with developing with asynchronous APIs it's worth your while to read up on the subject; it can be very tricky (sadly, I don't have any recommendations for a good primer). Hope this helps!
For me, it's because I didn't call super.init()
in the initializer.
class AnObject: NSObject {
override init() {
// super.init()
let _: ()-> (Void) = {
print(String(describing: self))
}
}
}