Redis Swift клиент: RediStack для iOS/macOS

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

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

Начать курс

RediStack: Асинхронный Redis клиент для Swift (iOS/macOS)

RediStack — это современный, полностью асинхронный клиент для работы с Redis, написанный на Swift. Библиотека построена на основе фреймворка SwiftNIO, что обеспечивает высокую производительность и низкое потребление памяти. RediStack идеально подходит для iOS и macOS приложений, требующих быстрого кэширования, управления сессиями, очередей сообщений или Pub/Sub функциональности.

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

  • Полная асинхронность на базе Swift Concurrency (async/await) и Combine
  • Поддержка всех основных типов данных Redis: строки, списки, множества, хеши, потоки
  • Встроенная поддержка Pub/Sub с автоматическим переподключением
  • Автоматическое пулингование соединений (Connection Pool)
  • Поддержка Redis Cluster и Sentinel
  • SSL/TLS шифрование для безопасного соединения
  • Типобезопасные команды с автодополнением в Xcode

Установка с помощью Swift Package Manager

Добавьте RediStack в ваш Package.swift или через Xcode:

// Package.swift
dependencies: [
    .package(url: "https://github.com/RediStack/RediStack.git", from: "1.6.0")
],
targets: [
    .target(name: "YourApp", dependencies: ["RediStack"])
]

Быстрый старт: подключение к Redis

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

import RediStack
import NIO

// Создаем EventLoopGroup
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)

// Настраиваем пул соединений
let pool = RedisConnectionPool(
    configuration: .init(
        initialServerConnectionAddresses: [try .init(hostname: "localhost", port: 6379)],
        maximumConnectionCount: .maximumActiveConnections(5)
    ),
    boundEventLoop: eventLoopGroup.next()
)

// Асинхронная работа с Redis
Task {
    do {
        // Установка и получение строки
        try await pool.set("greeting", to: "Hello from Swift!")
        let value = try await pool.get("greeting", as: String.self)
        print("Получено: \(value ?? "nil")") // "Получено: Hello from Swift!"
        
        // Работа со списками
        try await pool.lpush(["apple", "banana", "cherry"], into: "fruits")
        let fruits = try await pool.lrange(from: "fruits", firstIndex: 0, lastIndex: -1, as: [String].self)
        print("Фрукты: \(fruits)") // ["cherry", "banana", "apple"]
    } catch {
        print("Ошибка Redis: \(error)")
    }
}

Пример: Pub/Sub (издатель-подписчик)

RediStack поддерживает полноценный Pub/Sub с автоматическим восстановлением подписки:

import RediStack
import NIO

let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 2)
let pool = RedisConnectionPool(...)

// Подписчик
Task {
    let subscriber = pool.makeSubscriber(eventLoop: eventLoopGroup.next())
    
    // Подписка на канал
    await subscriber.subscribe(to: "notifications") { channel, message in
        print("Получено на канале \(channel): \(message.string ?? "")")
    }
    
    // Обработка ошибок подписки
    subscriber.onError = { error in
        print("Ошибка Pub/Sub: \(error)")
    }
}

// Издатель (отправка сообщения)
Task {
    try await pool.publish("Новое уведомление", to: "notifications")
}

Работа с хешами и транзакциями

Пример использования хешей и атомарных операций с помощью транзакций:

// Установка полей хеша
try await pool.hmset("user:1001", with: [
    "name": "Иван Петров",
    "email": "ivan@example.com",
    "age": "30"
])

// Получение всех полей
let user = try await pool.hgetall(from: "user:1001")
print("Имя: \(user["name"]?.string ?? "")") // "Имя: Иван Петров"

// Транзакция (атомарное выполнение)
try await pool.transaction { transaction in
    transaction.increment("counter") // INCR counter
    transaction.set("last_update", to: Date().timeIntervalSince1970)
}

Обработка ошибок и переподключение

RediStack автоматически обрабатывает временные ошибки и переподключается к серверу:

// Настройка стратегии повторных попыток
let config = RedisConnectionPool.ConnectionPoolConfiguration(
    initialServerConnectionAddresses: [try .init(hostname: "redis.example.com", port: 6379)],
    maximumConnectionCount: .maximumActiveConnections(10),
    retryStrategy: .exponentialBackoff(maxDelay: .seconds(30)),
    connectionBackoffFactor: 2
)

// Обработка ошиб                    

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