Функция возвращает результат до отработки completionHandler`а другой функции, как исправить?

столкнулся с такой проблемой, и не могу понять, какие есть пути решения данной проблемы.

Для начала предположим, что у меня есть следующая функция

func summ(x: Int, y: Int, completionHandler: @escaping (Int) -> ()) {
    let result: Int = x + y
    completionHandler(result)
}

Далее мы хотим в другой функции как то обработать результат функции, указанной выше, и вернуть обработанное значение.

func summ(x: Int, y: Int, completionHandler: @escaping (Int) -> ()) {
    let result: Int = x + y
    completionHandler(result)
}


func getResult(x: Int, y: Int) -> (String) {
    let resultString: String = ""

    summ(x, y) { result in
        resultString = "Результат: \(String(result))" 
    }

    return resultString
}

Но при вызове let resultString = getResult(x = 15, y = 10) я получаю просто пустую строку. При попытках найти ошибку, понял, что в данный метод создает let resultString: String = "" а после чего сразу возвращает эту переменную return resultString, и только После этого начинает работу completionHandler

Я бы хотел, чтобы мой return возвращал значение ПОСЛЕ того, как полностью отработает completionHandler, а не до этого.

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

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

Про возможное решение, которое мне не совсем подходит:

let resultString: String = ""

func summ(x: Int, y: Int, completionHandler: @escaping (Int) -> ()) {
    let result: Int = x + y
    completionHandler(result)
}


func getResult(x: Int, y: Int) {
    summ(x, y) { result in
        resultString = "Результат: \(String(result))"
        self.resultString = resultString
    }
}

Ответы (1 шт):

Автор решения: Eugene Krivenja

Если отбросить новые фичи языка, то наверное это может выглядеть так:

func getResult(x: Int, y: Int) -> (String) {
    var resultString: String = ""

    let dispatchGroup = DispatchGroup()
    dispatchGroup.enter()

    summ(x: x, y: y) { result in
        resultString = "Результат: \(String(result))" 
        dispatchGroup.leave()
    }
    dispatchGroup.wait()

    return resultString
}

Получается блокирующая функция, которую нельзя вызывать из .main

UPD: Все-таки для начинающего DispatchGroup слишком сложно, можно обойтись классическим решением попроще (никаких глобальных переменных и ожиданий значений из асинхронных функций):

func summ(x: Int, y: Int, completionHandler: @escaping (Int) -> ()) {
    let result: Int = x + y
    completionHandler(result)
}

func getResult(x: Int, y: Int) {
    summ(x, y) { result in
        updateResult("Результат: \(String(result))")
    }
}

func updateResult(strResult: String) {
    // здесь делайте все что вам нужно с новым значением
}
→ Ссылка