Введение: Почему GraphQL и Swift?
Современная iOS- и macOS-разработка требует гибких и эффективных способов взаимодействия с сервером. Традиционные REST API часто приводят к проблеме over-fetching (получение лишних данных) или under-fetching (недостаток данных). GraphQL решает эти проблемы, позволяя клиенту запрашивать только те данные, которые ему нужны, в одном запросе.
В этом туториале мы создадим полноценное приложение на Swift, которое будет взаимодействовать с GraphQL API. Вы узнаете, как настроить проект, выполнять запросы, мутации и обрабатывать ошибки. В качестве клиента мы будем использовать Apollo iOS — самую популярную библиотеку для работы с GraphQL в экосистеме Apple.
Настройка проекта и установка Apollo iOS
Создание нового проекта
Откройте Xcode и создайте новый проект iOS или macOS App. Назовём его GraphQLDemo.
Установка Apollo iOS через Swift Package Manager
- В Xcode перейдите в File → Add Packages...
- Вставьте URL репозитория Apollo:
https://github.com/apollographql/apollo-ios.git - Выберите последнюю стабильную версию и нажмите Add Package.
- Убедитесь, что пакет добавлен в target вашего приложения.
Генерация кода по схеме GraphQL
Apollo использует кодогенерацию для создания типобезопасных классов. Для этого нам нужен файл схемы (schema.graphqls) и файлы с запросами (.graphql).
Создайте папку GraphQL в проекте и поместите туда:
schema.graphqls— скачайте схему вашего API или используйте публичную (например, Countries GraphQL API).Queries.graphql— файл с вашими запросами.
Пример содержимого Queries.graphql:
query GetCountries {
countries {
code
name
capital
currency
}
}
Теперь добавьте Build Phase для генерации кода. В Xcode: Target → Build Phases → + → New Run Script Phase. Вставьте скрипт:
cd "${SRCROOT}/${TARGET_NAME}"
./Pods/Apollo/scripts/run-bundled-codegen.sh codegen:generate --target=swift --includes=./**/*.graphql --localSchemaFile=./schema.graphqls ./GraphQL/API.swift
Примечание: В современных версиях Apollo iOS используется apollo-ios-cli. Рекомендуем ознакомиться с официальной документацией для актуальных инструкций.
Выполнение GraphQL запросов (Queries)
Инициализация Apollo клиента
Создадим менеджер для работы с Apollo. Откройте файл NetworkManager.swift:
import Foundation
import Apollo
class NetworkManager {
static let shared = NetworkManager()
private(set) lazy var apollo: ApolloClient = {
let url = URL(string: "https://countries.trevorblades.com/")!
return ApolloClient(url: url)
}()
}
Выполнение запроса
Теперь выполним запрос GetCountries в нашем ViewController:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
fetchCountries()
}
private func fetchCountries() {
NetworkManager.shared.apollo.fetch(query: GetCountriesQuery()) { result in
switch result {
case .success(let graphQLResult):
if let countries = graphQLResult.data?.countries {
for country in countries {
print("\(country.name) - \(country.capital ?? "N/A")")
}
}
if let errors = graphQLResult.errors {
print("GraphQL errors: \(errors)")
}
case .failure(let error):
print("Network error: \(error)")
}
}
}
}
Обратите внимание: Apollo автоматически генерирует типобезопасные классы (GetCountriesQuery), поэтому мы не работаем с сырыми JSON.
Обработка ошибок
Всегда проверяйте graphQLResult.errors — сервер может вернуть частичные данные с ошибками. Это особенность GraphQL.
Мутации (Mutations) и Подписки (Subscriptions)
Создание мутации
Добавим в Queries.graphql мутацию для добавления страны (если API поддерживает):
mutation AddCountry($code: String!, $name: String!) {
addCountry(code: $code, name: $name) {
code
name
}
}
Выполнение мутации:
func addCountry(code: String, name: String) {
NetworkManager.shared.apollo.perform(mutation: AddCountryMutation(code: code, name: name)) { result in
switch result {
case .success(let graphQLResult):
if let addedCountry = graphQLResult.data?.addCountry {
print("Added: \(addedCountry.name)")
}
case .failure(let error):
print("Mutation error: \(error)")
}
}
}
Подписки (Subscriptions) для реального времени
Подписки позволяют получать обновления в реальном времени через WebSocket. Для их использования требуется настроить транспорт WebSocket. Пример подписки:
// В файле .graphql
subscription OnCountryAdded {
countryAdded {
code
name
}
}
// В Swift коде
var cancellable: Cancellable?
func subscribeToNewCountries() {
cancellable = NetworkManager.shared.apollo.subscribe(subscription: OnCountryAddedSubscription()) { result in
switch result {
case .success(let graphQLResult):
if let country = graphQLResult.data?.countryAdded {
print("New country: \(country.name)")
}
case .failure(let error):
print("Subscription error: \(error)")
}
}
}
// Не забудьте отменить подписку, когда она больше не нужна:
cancellable?.cancel()
Важно: Для подписок Apollo iOS требует дополнительной настройки WebSocket транспорта. Подробнее — в документации Apollo Subscriptions.
Заключение: лучшие практики и дальнейшие шаги
Блоги
Рекомендаций по книгам
Читайте также
Как удалить пустые элементы из массива в PHP: полное руководство
Очереди задач в TypeScript: полное руководство для начинающих
Ограничение запросов в JavaScript: как не дать API упасть
Функциональное программирование в Java: от лямбд до Stream API
JSON в JavaScript: полный гайд по парсингу и сериализации
Блоги
Рекомендаций по книгам
Читайте также
Функциональное программирование в Java: от лямбд до Stream API