GraphQL в Swift: Полное руководство по библиотеке Apollo iOS

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

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

Начать курс

Библиотека Apollo iOS для работы с GraphQL на Swift

Apollo iOS — это мощная и гибкая библиотека для работы с GraphQL в экосистеме Apple. Она предоставляет разработчикам iOS и macOS удобный инструмент для выполнения запросов, мутаций и подписок на серверы GraphQL. В отличие от REST API, GraphQL позволяет клиенту запрашивать только необходимые данные, что снижает объем трафика и ускоряет работу приложений. Apollo iOS полностью поддерживает Swift, включая современные возможности языка, такие как async/await, Combine и SwiftUI.

Основные возможности Apollo iOS

  • Генерация кода: Автоматическое создание типобезопасных моделей данных на основе GraphQL-схемы.
  • Кэширование: Встроенная поддержка нормализованного кэша для оптимизации повторных запросов.
  • Поддержка Swift Concurrency: Полная интеграция с async/await для асинхронных операций.
  • Подписки через WebSocket: Реализация real-time обновлений с помощью GraphQL subscriptions.
  • Combine и SwiftUI: Возможность использования с реактивными фреймворками Apple.
  • Мультиплатформенность: Работает на iOS, macOS, tvOS и watchOS.

Установка библиотеки

Для установки Apollo iOS используйте Swift Package Manager. Добавьте пакет в Xcode через меню File → Add Packages и укажите URL:

https://github.com/apollographql/apollo-ios.git

Версия: последняя стабильная (на момент написания — 1.15.0).

Настройка Apollo Client

Первый шаг — создание экземпляра ApolloClient с URL вашего GraphQL-сервера. Пример базовой настройки:

import Apollo

class NetworkService {
    static let shared = NetworkService()
    private(set) lazy var apollo: ApolloClient = {
        let url = URL(string: "https://api.example.com/graphql")!
        return ApolloClient(url: url)
    }()
}

Выполнение запросов (Queries)

Apollo iOS генерирует код на основе GraphQL-схемы. Сначала определите запрос в файле .graphql:

query GetUser($id: ID!) {
    user(id: $id) {
        id
        name
        email
        posts {
            title
        }
    }
}

После генерации кода выполните запрос:

import Apollo

func fetchUser(id: String) async throws -> GetUserQuery.Data.User? {
    let query = GetUserQuery(id: id)
    let result = try await NetworkService.shared.apollo.fetch(query: query)
    return result.data?.user
}

Мутации (Mutation)

Для изменения данных используйте мутации. Пример создания нового поста:

mutation CreatePost($title: String!, $content: String!) {
    createPost(input: { title: $title, content: $content }) {
        id
        title
        createdAt
    }
}

Выполнение мутации в Swift:

func createPost(title: String, content: String) async throws -> CreatePostMutation.Data.CreatePost? {
    let mutation = CreatePostMutation(title: title, content: content)
    let result = try await NetworkService.shared.apollo.perform(mutation: mutation)
    return result.data?.createPost
}

Работа с подписками (Subscriptions)

Для real-time обновлений используйте подписки. Пример подписки на новые сообщения:

subscription OnNewMessage {
    newMessage {
        id
        text
        sender {
            name
        }
    }
}

Реализация в Swift с использованием Combine:

import Combine

var cancellables = Set<AnyCancellable>()

func subscribeToMessages() {
    let subscription = OnNewMessageSubscription()
    NetworkService.shared.apollo.subscribe(subscription: subscription)
        .sink { completion in
            print("Subscription completed: \(completion)")
        } receiveValue: { result in
            if let message = result.data?.newMessage {
                print("New message: \(message.text)")
            }
        }
        .store(in: &cancellables)
}

Кэширование и нормализация

Apollo iOS автоматически нормализует данные и сохраняет их в кэше. Это позволяет избежать повторных запросов к серверу. Настройка кэша с кастомной политикой:

let cache = InMemoryNormalizedCache()
let store = ApolloStore(cache: cache)
let client = ApolloClient(networkTransport: transport, store: store)

Интеграция с SwiftUI

Для использования в SwiftUI можно создать ObservableObject-обертку:

import SwiftUI
import Apollo

class UserViewModel: ObservableObject {
    @Published var user: GetUserQuery.Data.User?
    
    func loadUser(id: String) async {
        do {
            let result = try await NetworkService.shared.apollo.fetch(query: GetUserQuery(id: id))
            await Main                    

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