Как написать обработчик завершения в отдельном блоке кода в Swift с параметрами вне области видимости

avatar
fabiobh
9 августа 2021 в 03:40
84
1
0

Я пытался сделать свой код чистым и отделить приведенный ниже код, я хочу удалить из него завершающий обработчик завершения и написать обработчик завершения в другом блоке кода.

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 ...
    }
}

Это часть, которую я пишу, создавая отдельный обработчик завершения

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

но это не сработает, потому что в последних двух строках кода используются параметры, выходящие за рамки. Параметр "marca" и параметр "myUploadGroupMarcas" выходят за рамки. Есть ли способ использовать эти параметры внутри отдельной функции обработчика завершения?

Источник
user1922718
9 августа 2021 в 05:34
0

Вы можете написать небольшой обработчик завершения, который вызывает ваш более длинный обработчик, передавая нужные вам переменные.

fabiobh
9 августа 2021 в 10:11
0

@user1922718 user1922718 Можете ли вы привести пример того, как будет работать этот другой обработчик завершения? Я новичок в использовании обработчиков завершения.

vadian
9 августа 2021 в 20:00
1

Поскольку обработчик завершения находится внутри цикла и также захватывает экземпляр DispatchGroup, попытки очистить код контрпродуктивны.

Ответы (1)

avatar
user1922718
9 августа 2021 в 18:09
1

Хорошо, основываясь на наших комментариях выше, я бы попробовал следующий маршрут: написать короткий обработчик завершения, который вызывает ваш более длинный обработчик завершения, передавая переменные, которые находятся вне области действия.

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

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

}

Затем вы добавляете два параметра в обработчик завершения в определении функции:

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

Очевидно, что вам нужно заменить MarcaClass фактическим типом класса, который является marca и myUploadGroupMarcas, похоже, является функцией, поэтому вам нужно написать для этого соответствующий тип параметра.