So if you look at the code below you will see the following line fails with:
cannot use mutating member on immutable value: 'forecasts' is a 'let' constant
caused by forecasts.append(forecast). I have a service file which you see below called ForecastService and I am using the function to asynchronously grab JSON in my view controller from an API. I am trying to pass an object and an array of objects to the function which I then want to mutate on so I can use the updated values in my view controller to update my UI. I want to construct forecast objects and push them into the the array which I initialized in the view controller.
Any clarification on how I can get around this problem would be great.
import Foundation
import Alamofire
class ForecastService {
static let sharedInstance = ForecastService()
private init() {}
func downloadForecastDetails(forecast: Forecast, forecasts: [Forecast], completed: @escaping DownloadComplete) {
let url = URL(string: FORECAST_URL)!
Alamofire.request(url).responseJSON { response in
let result = response.result.value
if let dict = result as? Dictionary<String, AnyObject> {
if let list = dict["list"] as? [Dictionary<String, AnyObject>] {
for obj in list {
let forecast = Forecast(weather: obj)
forecasts.append(forecast)
}
}
}
completed()
}
}
}
The problem is not the asynchronous block, but the mechanism of parameter
forecasts. It's copied when you call the function, even if you declare it as var. Because Array is Swift is value type, it's the Swift's policy. (https://developer.apple.com/swift/blog/?id=10) You can try to callforecasts.appendoutside the asynchronous block, it will still fail. So you need another way to pass a reference type (not value type) into the function.