Trying to mutate array and object passed as parameters to an asynchronous function

322 views Asked by At

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()
        }

    }
}
1

There are 1 answers

0
vietstone On

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 call forecasts.append outside the asynchronous block, it will still fail. So you need another way to pass a reference type (not value type) into the function.