Swift 5 : Escaping closure captures 'inout' parameter

痞子三分冷 提交于 2021-02-08 07:24:50

问题


I already have the response data that I received from the server. This response data have some bakers data.

Now I want to calculate the distance of the user and bakery and then store it in the same modal class. I have created a function for it. And as this function need to be used in 4,5 view controllers, my plan is to create as an extension of UIViewController

func getDistanceUserBakery(bakeryData : inout [BakeryRecord], completion : @escaping (Int?) -> () ) {

    for index in 0...(bakeryData.count-1) {
        //1
        let googleApiAdd = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&"
        //2
        let origin = "origins=\(UserLocation.coordinates.latitude),\(UserLocation.coordinates.longitude)"
        //3
        let destination = "&destinations=\(bakeryData[index].location?.coordinates?[1] ?? 0.0),\(bakeryData[index].location?.coordinates?[0] ?? 0.0)"
        //4
        let googleKey = "&key=\(GOOGLE_KEY)"
        //5
        let url = googleApiAdd + origin + destination + googleKey

        let request = URLRequest(url: URL(string: url)!)

        //6 - this line is showing the error.

        let task = URLSession.shared.dataTask(with: request) {(data, response, error) in
            guard let data = data else {
                completion(nil)
                Toast.show(message: "Unable to calculate distance from user to bakery", controller: self)
                return }
            let stringResponse = String(data: data, encoding: .utf8)!
            let dictData = stringResponse.convertToDictionary()
            do {
                let jsonData = try JSONSerialization.data(withJSONObject: dictData as Any, options: .prettyPrinted)
                let decoder = JSONDecoder()
                let model = try decoder.decode(GoogleDistance.self, from: jsonData)
                bakeryData[index].disanceInMiles = model.rows?[0].elements?[0].distance?.text ?? "NaN"
                completion(index)
            } catch let parsingError {
                print("Error data :", parsingError)
                completion(nil)
            }
        }
        task.resume()
    }

This is how I call this function once I have received the data from my server,

  self.getDistanceUserBakery(bakeryData: &self.bakeryData) { index in
                    if index != nil {
                        DispatchQueue.main.async {
                            // here I am thinking as the bakeryData will hold the new value for distanceInMiles, the collectionView will start showing up that result on reload.
                            self.resultCollection.reloadItems(at: [IndexPath(item: index!, section: 0)])
                        }
                    }
                }

Now the Question:

As I know, when you pass parameters as inout, there values can be changed from inside your function, and those changes reflect in the original value outside the function.

But when I try the code , it says Escaping closure captures 'inout' parameter 'bakeryData'. In my code , //6 is producing the error.

How to fix this error?


回答1:


As @Paulw11 suggested in comments,

Is BakeryData a struct? If so then simply make it a class. If you make BakerData a class then the array contains reference types and you can update the element's properties

I changed the struct to class and it did work.



来源:https://stackoverflow.com/questions/59943008/swift-5-escaping-closure-captures-inout-parameter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!