GraphQL API с Swift: пошаговый туториал для iOS и macOS

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

GraphQL API с Swift: пошаговый туториал

GraphQL становится стандартом для современных API благодаря гибкости и эффективности. В отличие от REST, где вы получаете фиксированную структуру данных, GraphQL позволяет запрашивать только то, что нужно. В этом туториале мы разберём, как интегрировать GraphQL API в приложения на Swift для iOS и macOS, используя библиотеку Apollo iOS. Вы научитесь выполнять запросы, мутации и обрабатывать ошибки.

1. Настройка проекта и установка Apollo iOS

Первый шаг — создать новый проект Xcode и добавить зависимость Apollo iOS через Swift Package Manager (SPM).

Шаг 1.1: Создание проекта

Откройте Xcode и создайте новый проект (iOS App или macOS App). Выберите SwiftUI или UIKit — наш пример будет работать с обеими платформами.

Шаг 1.2: Установка Apollo iOS через SPM

  1. В Xcode перейдите в File → Add Packages...
  2. Вставьте URL репозитория: https://github.com/apollographql/apollo-ios.git
  3. Выберите последнюю стабильную версию (например, 1.15.0) и нажмите Add Package.
  4. В появившемся окне выберите ваш проект и добавьте пакет Apollo.

Шаг 1.3: Генерация схемы и кода

Apollo iOS использует кодогенерацию на основе схемы GraphQL. Сначала скачайте схему вашего API (обычно через introspection query). Для теста мы будем использовать публичное API Countries GraphQL (https://countries.trevorblades.com).

Создайте файл schema.graphqls в корне проекта и поместите в него схему (её можно получить через GraphQL Playground). Затем добавьте скрипт генерации в Build Phases:

// Пример скрипта в Build Phases
if which apollo-ios-cli >/dev/null; then
    apollo-ios-cli generate
else
    echo "Apollo CLI не установлен. Установите через: brew install apollo-ios-cli"
fi

Установите CLI через Homebrew: brew install apollo-ios-cli.

2. Выполнение базового GraphQL-запроса

Теперь, когда проект настроен, напишем код для выполнения запроса. Мы будем получать список стран с их кодами и названиями.

Шаг 2.1: Создание GraphQL-запроса

В папке проекта создайте файл Countries.graphql и добавьте запрос:

query GetCountries {
    countries {
        code
        name
    }
}

После этого запустите кодогенерацию (через Build или терминал). Apollo создаст структуры GetCountriesQuery и GetCountriesQuery.Data.

Шаг 2.2: Настройка ApolloClient

Создайте менеджер сети:

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)
    }()
}

Шаг 2.3: Выполнение запроса в SwiftUI

Пример для SwiftUI:

import SwiftUI

struct ContentView: View {
    @State private var countries: [GetCountriesQuery.Data.Country] = []
    
    var body: some View {
        List(countries, id: \.code) { country in
            Text("\(country.name) (\(country.code))")
        }
        .onAppear {
            loadCountries()
        }
    }
    
    func loadCountries() {
        NetworkManager.shared.apollo.fetch(query: GetCountriesQuery()) { result in
            switch result {
            case .success(let graphQLResult):
                if let countries = graphQLResult.data?.countries {
                    self.countries = countries
                }
            case .failure(let error):
                print("Ошибка запроса: \(error.localizedDescription)")
            }
        }
    }
}

Запустите приложение. Если всё настроено верно, вы увидите список стран из API.

3. Работа с мутациями и аргументами

GraphQL не только читает данные, но и изменяет их через мутации. Рассмотрим пример с добавлением нового элемента (если API поддерживает). Для демонстрации будем использовать аргументы в запросе.

Шаг 3.1: Запрос с аргументами

Добавим в файл Countries.graphql новый запрос для получения страны по коду:

query GetCountry($code: ID!) {
    country(code: $code) {
        name
        capital
        currency
    }
}

После генерации кода вы получите GetCountryQuery с параметром code.

Шаг 3.2: Выполнение запроса с аргументами

func loadCountry(code: String) {
    NetworkManager.shared.apollo.fetch(query: GetCountryQuery(code: code)) { result in
        switch result {
        case .success(let graphQLResult):
            if let country = graphQLResult.data?.country {
                print("Страна: \(country.name), столица: \(country.capital ?? "нет")")
            }
        case .failure(let error):
            print("Ошибка: \(error)")
        }
    }
}

Шаг 3.3: Мутация (пример с гипотетическим API)

Для мутации необходимо объявить её в .graphql файле:

mutation CreateCountry($input: CountryInput!) {
    createCountry(input: $input) {
        code
        name
    }
}

В Swift вызывайте мутацию аналогично запросу, но используя perform:

let input = CountryInput(code: "RU", name: "Россия")
NetworkManager.shared.apollo.perform(mutation: CreateCountryMutation(input: input)) { result in
    // Обработка результата
}

4. Обработка ошибок и пагинация

Работа с реальным API требует обработки ошибок и работы с большими объёмами данных. Рассмотрим эти аспекты.

Шаг 4.1: Обработка ошибок GraphQL

GraphQL может возвращать частичные ошибки. Apollo предоставляет структуру GraphQLResult с полем errors:

func handleResult<T: GraphQLQuery>(result: Result<GraphQLResult<T.Data>, Error>) {
    switch result {
    case .success(let graphQLResult):                

Блоги

Рекомендаций по книгам