Всякий раз, когда вы вводите адрес в Google Maps или ищете видео на YouTube, вы, возможно, замечали, что предложения автозаполнения обновляются через регулярные промежутки времени, а не при каждом изменении поискового запроса.

Если учесть масштаб этих платформ, такое ограничение запросов является необходимой оптимизацией. Это помогает предотвратить ненужные HTTP-запросы, обеспечивая при этом бесперебойную работу пользователей.

Сегодня мы рассмотрим простую реализацию, которую вы можете использовать для воспроизведения этого поведения в своих приложениях.

Давайте продолжим наш вариант использования автозаполнения предложений и представим, что у нас есть функция, которая делает асинхронный HTTP-запрос и возвращает обновленный список предложений:

func getAutocompleteSuggestions(from query: String,
                                completion: (([String]) -> Void)?)

В идеале мы хотели бы иметь возможность вызывать эту функцию непосредственно в обратном вызове делегата нашего searchBar или textField и иметь какой-то другой механизм, гарантирующий запуск запроса только один раз каждые X секунды.

Выполнение

Мы можем создать следующую утилиту ThrottleExecution для выполнения этих требований:

struct ThrottleExecution {

    private static var previousExecution = Date.distantPast

    static func execute(minimumInterval: TimeInterval, queue: DispatchQueue, _ block: @escaping () -> Void) {
        if abs(previousExecution.timeIntervalSinceNow) > minimumInterval {
            previousExecution = Date()
            queue.async { block() }
        }
    }

}

Этот метод гарантирует, что block будет выполняться только один раз в указанном TimeInterval. Итак, если этот метод вызывается 100 раз в течение 9 секунд, и мы должны были передать 5 секунд как minimumInterval, блок будет выполнен только дважды; при первом вызове метода и еще раз через 5 секунд.

Применение

С помощью всего лишь этой простой утилиты ThrottleExecution мы можем эффективно ограничить частоту выполнения и настроить DispatchQueue любой задачи в нашем приложении:

ThrottleExecution.execute(minimumInterval: 0.3, queue: .main) { [weak self] in
    guard let self = self, let query = self.searchTextField.text else { return }

    self.getAutocompleteSuggestions(from: query) { searchSuggestions in
        // Update UI with new searchSuggestions
    }
}

Если вас интересуют другие статьи о iOS-разработке и Swift, загляните на мой канал YouTube или подпишитесь на меня в Twitter.

Если вы независимый разработчик iOS, обязательно ознакомьтесь с моей рассылкой:



Indie Watch
Сегодня мы рассмотрим «Нуар
Джеффри Куикена. Noir — это расширение Safari для iOS, которое автоматически добавляет темный режим…indie.watch»



У меня есть новый разработчик для каждой проблемы, поэтому не стесняйтесь отправлять свои инди-приложения для iOS!

У вас скоро интервью для iOS?

Ознакомьтесь с моей книгой Ace The iOS Interview!