Библиотека 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