Держите API в вашем приложении управляемым и структурированным

Использование API-интерфейсов в вашем приложении для iOS может быть пугающим, и, хотя есть множество способов добиться того же, их обслуживание может быть немного сложным и утомительным.
Я изо всех сил пытался эффективно управлять кодом, в котором были определены API, поскольку он становился длиннее с каждым новым запросом.
В этой статье я поделюсь с вами лучшим из найденных мной способов комфортного обслуживания всех вызовов API с помощью Alamofire.
В этом руководстве предполагается, что вы знаете:
- Swift 5
- Xcode
- Какао-стручки
Приступим сейчас
Подготовка
Мы собираемся использовать Alamofire для этого урока, если вы знаете, как устанавливать и использовать модули в своем приложении, вы можете пропустить этот раздел.
Для тех из вас, кто не знаком с Cocoapods, продолжайте :)
1. Инициализируйте подфайл.
Перейдите в каталог проекта в терминале и выполните следующую команду.
pod init
2. Добавьте зависимость Alamofire.
Откройте Podfile и добавьте код для установки Alamofire.
pod 'Alamofire'
3. Установите Alamofire.
Теперь вернитесь в терминал и запустите эту команду, чтобы установить модуль модуля
pod install
Теперь вы можете запустить Xcode, открыв файл .xcworkspace.
Создание Менеджера для API
Мы собираемся создать новый файл Swift с именем APIManager.swift, который будет содержать диспетчер вызовов API.
В рамках этой статьи мы будем вызывать простые API, которые возвращают результат в этом формате.
{
"userId": 1,
"id": 1,
"title": "Dummy Title",
"body": "For Medium post on API management using Alamofire"
}
В этой статье я продемонстрирую 3 вызова API -
- GET вызов для получения единственной записи
- GET вызов для получения нескольких записей
- POST-вызов для отправки записи на сервер
1. Создайте модель для ответа API.
Прежде чем мы начнем использовать API, мы должны создать модель для них.
Со времен Swift 4 создание моделей для API стало проще простого благодаря протоколам Decodable и Encodable.
Мы будем создавать структуру под названием Resource, которая соответствует протоколу Decodable. Это должно выглядеть примерно так -

После того, как мы создали модель, мы можем начать работу над APIManager.
2. Создайте APIManager.
Теперь мы создадим enum APIManager, который будет соответствовать протоколу URLRequestConvertible, определенному в библиотеке Alamofire.
URLRequestConvertible позволяет нам разбивать URLRequests и изменять все аспекты запроса, такие как HTTPMethod, Parameters, Path, Encoding и Headers.

Причина, по которой нам нужно создать этот APIManager как перечисление, состоит в том, чтобы формулировать случаи для различных запросов API.
Мы определили конечную точку для API и вместе с ней 3 случая для вызовов API. Если в запросе есть какие-либо параметры, которые нужно передать, он должен быть объявлен в этом случае.
i) Настройте случаи для запросов

Здесь мы указали пути для каждого запроса API, что говорит само за себя.
ii) Добавьте переменные, чтобы указать метод HTTP и кодировку для запросов.

Метод HTTP для запросов указывается внутри другой переменной, называемой методом. Я использую кодировку по умолчанию для своих запросов, если вашему API требуется другой тип кодировки, вы можете указать его.
iii) Расширьте функцию, предоставляемую URLRequestConvertible, которая возвращает URLRequest для каждого случая.

Запросы генерируются с использованием пути, кодировки и метода, указанных выше для каждого случая. Для вызовов POST вы можете передать параметры, как я для случая createResource. Заголовки также добавляются сюда при необходимости.
iv) Создайте функции для использования API

Мы завершаем перечисление APIManager, добавляя вызывающие функции для вызова случаев URLRequestConvertible.
Мы передаем созданный нами кейс URLRequestConvertible методу Alamofire -
AF.request(URLRequestConvertible())
Метод ответа вызывается для получения ответа на запрос. Здесь мы использовали метод responseJSON для получения ответа API.
Наконец, мы конвертируем ответ API с помощью JSONDecoder и преобразуем его в нашу Decodable struct Resource.
Поскольку второй API возвращает несколько ресурсов, мы преобразуем его в массив ресурсов.
let resources = try! jsonDecoder.decode([Resource].self, from: jsonData)
Приведя данные к нашей указанной модели, мы возвращаем их с помощью завершенияHandler.
На этом наш APIManager завершен.
Это было давно, можем ли мы теперь вызвать API? 🤔
Да, это правильно. У нас есть все, что нам нужно, функции, определенные в APIManager, используются для вызова API.
Теперь мы можем вызывать API в наших viewControllers и использовать их соответствующим образом.

Но стоит ли так структурировать наши API?
Вы могли подумать, что в таком способе структурирования API-интерфейсов нет необходимости, и вам лучше вызвать API-интерфейсы напрямую с помощью Alamofire.
Поверьте, когда количество API-интерфейсов, используемых в вашем приложении, увеличится, это поможет вам сохранить структуру и порядок, поскольку все API-интерфейсы определены в одном месте. Вы даже можете изменить корпуса в соответствии с вашими потребностями, исходя из ваших требований.
У этого есть и другие преимущества -
Вы также можете обобщить вызывающие функции в одном шаблоне, чтобы вы могли сформировать единственную функцию для аналогичных API -

Созданная выше функция принимает URLRequestConvertible и модель. Для API, возвращающих данные аналогичным образом, можно использовать ту же универсальную функцию.

Мы можем вызвать общую функцию, передав наш определенный URLRequestConvertible и модель Resource для вызова GET API, возвращающего единичную запись.
Теперь это значительно сокращает количество строк кода, которые нам нужно написать для вызывающих функций в нашем APIManager, и экономит много времени!
Заключение
Если вы воспользуетесь этим способом структурирования своих API-интерфейсов для своих приложений iOS, ваше управление кодом определенно улучшится, и вы сэкономите много времени.
Если вам нужен код, он доступен в моем репозитории Github SimpleAFire.
Мы подошли к концу этой статьи, я надеюсь, что она была полезной, и вы кое-что узнали!
Спасибо за внимание!