Как мне ждать асинхронного вызова в Swift? - PullRequest
0 голосов
/ 14 апреля 2020

Итак, я недавно вернулся в Swift & iOS после перерыва и столкнулся с проблемой асинхронного выполнения. Я использую iOS SDK от Giphy, чтобы сэкономить много работы, но их документация практически отсутствует, поэтому я не уверен, что может происходить под капотом в их функции, которая вызывает их API.

Я вызываю свою функцию, содержащую приведенный ниже код, из конструктора объекта stati c (я не думаю, что это проблема, поскольку я также пытался вызвать его из метода cellForItemAt для представления Collection).

Моя проблема в том, что моя функция возвращается и выполнение продолжается до завершения вызова API. Я попытался использовать DispatchQueue.main.asyn c и полностью удалить Dispatch и DispatchGroups, но безрезультатно. Единственное, что сработало, это семафор, но я помню, что читал, что это не лучшая практика?

Какие-нибудь советы были бы хороши, я слишком долго застрял в этом. Большое спасибо заранее

GiphyCore.shared.gifByID(id) { (response, error) in
        if let media = response?.data {
            DispatchQueue.main.sync {
                print(media)
                ret = media
            }
        }
    }

return ret

Ответы [ 2 ]

3 голосов
/ 14 апреля 2020

Моя проблема в том, что моя функция возвращается и выполнение продолжается до завершения вызова API.

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

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

Единственное, что сработало, это семафор, но я помню, что читал, что это не лучшая практика?

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

0 голосов
/ 14 апреля 2020

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

func functionName(completion: @escaping (YOURDATATYPE) -> Void) {
    GiphyCore.shared.gifByID(id) { (response, error) in
        if let media = response?.data {
            completion(media)
            return
        }
    }
}

Вызовите свой метод так:

functionName() { response in
    DispatchQueue.main.async {
        // UPDATE the UI here
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...