Писать асинхронный код в Swift может быть мучительно. Как хорошо знают многие разработчики Node.JS, легко столкнуться с такими проблемами, как «ад колбэков».
Хотя Swift и его экосистема разработчиков еще молоды, благодаря библиотекам с открытым исходным кодом, таким как PromiseKit, есть надежда для Swift-разработчиков, желающих писать более чистый код для обработки асинхронных задач.
Чтобы проиллюстрировать разницу в структуре кода, возьмем в качестве примера Giphy API. Вот как может выглядеть ваш код, если вы хотите загрузить GIF из Giphy API, используя встроенные языковые средства и `Giphy`.
класс, который вы найдете в нашем проекте ниже:
Это всего лишь пара вызовов функций, но вы уже можете видеть вложенность кода и то, как каждый уровень требует своей отдельной проверки ошибок. Не нужно большого воображения, чтобы понять, как такой код может быстро стать трудным для чтения и понимания даже в более сложных сценариях. Вот как сделать то же самое, если эти функции переписаны с использованием промисов:
Предоставляя этим функциям возможность возвращать промисы вместо принятия колбэков, мы можем использовать `.then()`.
чтобы дождаться завершения одного запроса, прежде чем начать следующий. А с помощью `.catch()`.
мы можем перехватить ошибку, когда она произойдет. Нет необходимости повторять этот код обработки ошибок.
Этот код становится намного проще для чтения, поэтому его легче расширять для более сложных сценариев. Чтобы получить этот более чистый, более читаемый код, нам придется потрудиться, чтобы обернуть запрос к Giphy API в промис. К счастью, PromiseKit облегчает эту задачу.
Давайте создадим приложение для отображения случайных GIF-изображений, связанных с SNES (Super Nintendo Entertainment System), которое использует промисы для управления потоком нашего сетевого кода. Нет ничего, что я люблю больше, чем 16-битные видеоигры и управляемый сетевой код!
Начните с получения этого стартового проекта с Github. Он берет на себя всю базовую настройку, чтобы мы могли сосредоточиться на важном. Откройте терминал, перейдите туда, где вы хотите, чтобы этот проект жил, и выполните следующую команду, чтобы клонировать этот репозиторий и перейти к ветке учебника:
У этого приложения есть несколько зависимостей:
— Alamofire для отправки HTTP-запросов к Giphy API.
— SwifyJSON для разумной и обоснованной обработки JSON-ответа.
— SwiftyGif для простого управления данными GIF и их отображения в
`UIImageView`
— PromiseKit для промисов.
Мы будем использовать CocoaPods для установки этих зависимостей. Сначала установите CocoaPods, если у вас его нет:
Теперь установите зависимости:
CocoaPods связывает зависимости нашего проекта, создавая новое рабочее пространство Xcode. Чтобы убедиться, что Xcode загружает эти зависимости, откройте рабочее пространство, используя файл `SNESGifs.xcworkspace`.
вместо файла проекта Xcode:
Мы готовы начать наше путешествие. Не стесняйтесь собрать проект, чтобы убедиться, что все компилируется правильно.
Обратите внимание, что мы возвращаем промис, в отличие от альтернативы с использованием функции обработчика завершения. Когда URL случайного изображения успешно извлекается из Giphy API, мы передаем его дальше, отправляя в качестве аргумента в функцию `fulfill`.
Если запрос к Giphy завершается неудачно, мы передаем эту неудачу, вызывая функцию `reject`.
После того, как у нас есть URL нашего изображения, нам все еще нужно скачать это изображение и загрузить его в `UIImageView`.
Перейдите в `ViewController.swift`.
и добавьте функцию для получения изображения по заданному URL:
Это очень похоже на то, что мы делали в функции `fetchRandomGifUrl`.
Мы снова делаем запрос с Alamofire и возвращаем промис с функцией, которая выполняет или отклоняет этот промис на основе результатов нашего HTTP-запроса.
Использование промисов таким образом позволит нам сэкономить много времени в долгосрочной перспективе.
Чтобы завершить цепочку используемых нами функций, мы напишем быструю функцию для прикрепления изображения к нашему `UIImageView`.
с помощью SwiftyGif:
До сих пор мы делаем следующее:
— Отправка HTTP-запроса к Giphy API для получения URL, соответствующего случайному GIF.
— Отправка HTTP-запроса по этому URL для загрузки этого GIF.
— Отображение этого GIF в
`UIImageView`
Вложенные сетевые запросы могут стать громоздкими, но теперь мы можем воспользоваться возможностью построения цепочек промисов. Давайте объединим все, что мы сделали до сих пор, и воспользуемся функциями, которые мы написали и которые возвращают промисы.
В `viewDidLoad`.
добавьте следующий код:
Это читается гораздо лучше, чем вложение кучи обработчиков завершения.
Теперь запустите приложение и насладитесь наградой, увидев классные GIF-изображения Super Nintendo!
*GIF приложения в работе*
Хотя экосистема может быть молодой, вы не оставлены полностью без поддержки, если хотите интуитивно понятный способ написания асинхронного кода без необходимости полагаться на «сырой» Swift. Существуют также аналогичные библиотеки, такие как BrightFutures и FutureKit. Возможно, однажды это станет встроенной функцией языка, как это происходит с промисами в JavaScript.
Я с нетерпением жду, какие потрясающие проекты вы создадите. Не стесняйтесь обращаться с вопросами:
— Email: Sagnew@twilio.com
— Twitter: @Sagnewshreds
— Github: Sagnew
— Twitch (стримы с живым кодом): Sagnewshreds