0

I was trying to make my code clean and decouple the code below, I want to remove the trailing completion handler from it and write the completion handler in another blck of code.

func uploadMarcasMetodoNovo(_ id_resenha: Int) {
    
    let resenhaDados:ResDadoModel = db.readDadosResenhaById(id_resenha)
    let resenhaMarcas:[ResMarcasModel] = db.readResMarca(id_resenha)

    // this for loop runs about for 7 times                
    for marca in resenhaMarcas { 

        contadorUploadMarcas = contadorUploadMarcas + 1
        myUploadGroupMarcas.enter()
        
        jsonRequestUploadImagemGrafica = ResMarcasModel.createJsonMarcaResenha(marca, resenhaDados.IdGedave )
        
        let json: [String: Any] = jsonRequestUploadImagemGrafica
        guard let jsonData = try? JSONSerialization.data(withJSONObject: json) else {
            print("guard jsonData error")
            return
        }
        
        let requestImagemGrafica = requestUploadFotos(jsonData)
        let task = URLSession.shared.dataTask(with: requestImagemGrafica) { data, response, error in
            if let error = error {
                print("error: \(String(describing: error))")
                return
            }
            
            print("data")
            guard let returnData = String(data: data!, encoding: .utf8) else {
                print("returnData guard fail")
                return
            }
            print("returnData")
            print(returnData)
            
            self.confirmStatusEnviada(marca)
            self.myUploadGroupMarcas.leave()
            print("end TASK")
        }
        task.resume()
    }
    
    myUploadGroupMarcas.notify(queue: DispatchQueue.main) {
        print("myUploadGroupMarcas notify")
        // more code ...
    }
}

This is the part that I write creating a separated completion handler

let myCompletionHandler: (Data?, URLResponse?, Error?) -> Void = {
  (data, response, error) in
    if let error = error {
        print("error: \(String(describing: error))")
        return
    }
    
    print("data")
    guard let returnData = String(data: data!, encoding: .utf8) else {
        print("returnData guard fail")
        return
    }
    self.confirmStatusEnviada(marca)                
    self.myUploadGroupMarcas.leave()
    
}

but it won't work because in the last two lines of code are used paramters that are out of scope. The parameter "marca" and the parameter "myUploadGroupMarcas" are out of scope. Is there a way to use these parameters inside the separated completion handler function?

3
  • You could write a small completion handler that calls your longer handler, passing the variables you need Commented Aug 9, 2021 at 5:34
  • @user1922718 Can you give me an example of how it will be this other completion handler? I am new to the use of completion handlers. Commented Aug 9, 2021 at 10:11
  • 1
    As the completion handler is inside a loop and captures also the DispatchGroup instance the effort to clean the code is counterproductive. Commented Aug 9, 2021 at 20:00

1 Answer 1

1

Ok based on our comments above, this is the route I would try: Write a short completion handler that calls your longer completion handler, passing the variables that are out of scope.

let task = URLSession.shared.dataTask(with: requestImagemGrafica) { data, response, error in

myCompletionHandler(data, response, error, marca, myUploadGroupMarcas)

}

Then you add two parameters to your completion handler in the function definition:

let myCompletionHandler: (Data?, URLResponse?, Error?, MarcaClass, myUploadGroupMarcas) -> Void

Obviously you need to replace MarcaClass with the actual class type that is marca and myUploadGroupMarcas seems to be a function so you'd need to write an appropriate parameter type for that.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.