[2026-05-16] psychologist-app: dev-setup.md

This commit is contained in:
Alexey Martemyanov
2026-05-16 02:46:23 +06:00
parent e7c1c8bcbf
commit 6f355f3b2c
12 changed files with 5284 additions and 18 deletions
@@ -0,0 +1,615 @@
# Skip.tools: Оценка зрелости для AI-приложения с анимированным персонажем и голосом
> **Дата исследования:** 16 мая 2026
> **Версия Skip:** 1.8.14 (актуальная)
> **Контекст:** AI-приложение рефлексии на SwiftUI с анимированным blob/orb персонажем (Rive) и голосовым вводом/выводом (OpenAI Realtime API или Whisper+TTS)
---
## Вердикт TL;DR
> **⚠️ УСЛОВНО ГОТОВ — с существенными оговорками**
>
> Skip в 2026 году — это уже не эксперимент. Фреймворк активен, свободен, компилирует настоящий Jetpack Compose. Но для нашего конкретного кейса есть два критических барьера: **Rive не поддерживается официально** и требует платформо-специфичного workaround, а **WebSocket был сломан** до Skip 1.8/Swift 6.3 (сейчас починен). Рекомендация: **iOS-first MVP + Skip на неделю PoC**, принять решение по результатам.
---
## 1. Текущий статус Skip.tools (20252026)
### Жив ли проект?
**Однозначно да.** Метрики по состоянию на май 2026:
| Метрика | Значение |
|---------|---------|
| GitHub Stars | ~3,000 ⭐ |
| Forks | 101 |
| Последний релиз | v1.8.14 (8 мая 2026) |
| Лицензия | MPL-2.0 (полностью open source с v1.7) |
| Язык | Swift 100% |
| Режимы работы | Skip Fuse (нативный) / Skip Lite (транспайл) |
Важный поворот: в **феврале 2025** Skip стал соучредителем [Swift on Android Working Group](https://forums.swift.org/t/swift-on-android-working-group/77780), а **Swift 6.3** официально шипнул Swift SDK для Android. Skip 1.8 использует этот официальный SDK — больше нет зависимости от кастомного форка.
### Два режима: что выбрать?
| | **Skip Fuse** (нативный) | **Skip Lite** (транспайл) |
|---|---|---|
| Механизм | Swift компилируется нативно для Android | Swift → Kotlin (исходный код) |
| Плюсы | Полный Swift, все сторонние пакеты, детерминированная память | Прямой доступ к Kotlin/Java API, читаемый Kotlin-вывод, меньший размер |
| Минусы | +60 МБ к APK, медленная сборка | Не весь Swift транслируется, меньше пакетов |
| Рекомендация для нас | ✅ **Лучший выбор** — полный Swift, rich animations | — |
### Что поддерживается из SwiftUI?
Уровень покрытия (из официальной матрицы):
**Полная поддержка (✅):**
- `@State`, `@Binding`, `@Environment`, `@EnvironmentObject`, `@ObservedObject`, `@StateObject`, `@AppStorage`
- `AsyncImage`, `Button`, `HStack`, `VStack`, `ZStack`, `ScrollView`, `List`, `Form`
- `LinearGradient`, `RadialGradient`, `Circle`, `Rectangle`, `RoundedRectangle`, `Capsule`
- `NavigationStack`, `TabView`, `Sheet`, `Alert`
- `Text`, `TextField`, `SecureField`, `Toggle`, `Slider`, `Picker`
- `withAnimation` (есть известный баг — см. ниже)
**Частичная поддержка / проблемы:**
- `Canvas`**статус неясен** (не упоминается в матрице явно, вероятно не поддерживается)
- `TimelineView` — аналогично, не подтверждён
- `@GestureState` — только Skip Fuse
- `AppStorage` с optional values — не работает
**Известные баги (актуальные issues):**
| Issue | Проблема | Дата |
|-------|----------|------|
| [#402](https://github.com/skiptools/skip-ui/issues/402) | `withAnimation()` утекает в глобальное состояние на Android | Апр 2026 |
| [#687](https://github.com/skiptools/skip/issues/687) | State не обновляется под NavigationLink (Fuse) | Май 2026 |
| [#376](https://github.com/skiptools/skip-ui/issues/376) | NavigationLink throttling (задержка навигации) | Мар 2026 |
| [#339](https://github.com/skiptools/skip-ui/issues/339) | `.frame(maxWidth:)` игнорирует границы родителя | Фев 2026 |
| [#331](https://github.com/skiptools/skip-ui/issues/331) | Text с `%` и Markdown рендерится неправильно | Фев 2026 |
> **Критически важно для нас:** баг с `withAnimation()` (#402) напрямую влияет на анимированный персонаж.
### Приложения в production
Официально подтверждённые:
- **Skip Showcase** — каталог SwiftUI компонентов, опубликован в App Store и Google Play
- **Skip Bookings** — тревел-букинг с картами (пример)
- **Skip Weather** — погода с async networking
- В v2.3.6 Showcase добавили целую игру Block Blast на ~1000 строк чистого Swift
> Третьесторонних production-приложений в публичном доступе не найдено — Skip пока используется преимущественно инди-разработчиками.
---
## 2. Rive + Skip: совместимость
### Официальная поддержка
**❌ Нет официального пакета `skip-rive`.** Список официальных Skip-модулей:
```
skip-motion (Lottie), skip-av (AVFoundation), skip-firebase, skip-revenue (RevenueCat)...
```
Rive в нём отсутствует.
### Как Rive работает на iOS
Rive iOS runtime (`rive-app/rive-ios`, 780 ⭐, v6.20.3, MIT License) использует:
- **Objective-C++ (~32% кода)** для C++ рантайма Rive
- Интеграция в SwiftUI через `RiveViewModel` + `RiveView`
```swift
// Типичный код на iOS
import RiveRuntime
struct CharacterView: View {
@StateObject var riveVM = RiveViewModel(fileName: "blob_character")
var body: some View {
riveVM.view()
.frame(width: 300, height: 300)
}
}
```
**Проблема для Skip:** Rive iOS package содержит нативный C++ runtime и Objective-C++ bindings. Skip **не может транспилировать Objective-C++ код** — это за пределами его возможностей.
### Workaround: Platform-specific через ComposeView
Skip предоставляет мощный механизм для именно такого случая:
```swift
struct CharacterView: View {
let characterState: CharacterState
var body: some View {
#if os(Android)
// Android: используем Rive Android SDK через Compose
ComposeView { RiveAndroidComposer(state: characterState) }
#else
// iOS: нативный RiveRuntime
RiveNativeView(state: characterState)
#endif
}
}
// iOS-only код (полный Swift, без ограничений)
#if !SKIP
import RiveRuntime
struct RiveNativeView: View {
let state: CharacterState
@StateObject var riveVM = RiveViewModel(fileName: "blob_character")
var body: some View {
riveVM.view()
.onAppear { riveVM.triggerInput("setState", value: state.rawValue) }
}
}
#endif
// Android Kotlin через #if SKIP блок
#if SKIP
import app.rive.runtime.kotlin.compose.RiveAnimation
struct RiveAndroidComposer: ContentComposer {
let state: CharacterState
@Composable func Compose(context: ComposeContext) {
RiveAnimation(
resId = R.raw.blob_character,
modifier = context.modifier,
stateMachineName = "State Machine",
onInit = { controller in
controller.setBooleanState("State Machine", "isListening", state == .listening)
}
)
}
}
#endif
```
**Оценка workaround:**
- ✅ Технически реализуемо
- ✅ iOS остаётся чистым нативным RiveRuntime
- ⚠️ Нужно поддерживать две реализации
- ⚠️ Требует добавить зависимость `rive-android` в Gradle вручную через `skip.yml`
- ⏱️ Оценка трудозатрат: 2-3 дня дополнительно
### Lottie как альтернатива Rive
**`skip-motion` (официальный пакет)** — Lottie поддерживается!
```swift
import SkipMotion
struct CharacterView: View {
var body: some View {
MotionView(lottie: lottieAnimationData)
.frame(width: 300, height: 300)
}
}
```
| Параметр | Статус |
|----------|--------|
| Версия | v0.7.2 (Jan 2026) |
| iOS backend | lottie-ios v4.6.0 |
| Android backend | lottie-android v6.7.1 |
| Размер | +~1 МБ к ipa/apk |
| Управление воспроизведением | ⚠️ Раннее состояние, ограниченные контролы |
| State machine | ❌ Нет (в отличие от Rive) |
**Ключевое ограничение Lottie:** у него нет **State Machine** как у Rive. Для персонажа с динамическими состояниями (listening, thinking, speaking) это критично — нужно либо делать несколько анимаций, либо переключать между файлами. В Rive это нативно.
### SwiftUI-native анимированный персонаж (без Rive/Lottie)
Возможный подход: написать blob/orb через SwiftUI shapes + `withAnimation`:
```swift
struct BlobCharacterView: View {
@State private var animationPhase: Double = 0
var body: some View {
TimelineView(.animation) { timeline in
Canvas { context, size in
// Custom blob morphing via Bezier paths
let path = blobPath(for: timeline.date.timeIntervalSince1970)
context.fill(path, with: .color(.purple.opacity(0.8)))
}
}
.frame(width: 200, height: 200)
}
}
```
**Проблема:** `Canvas` и `TimelineView`**не подтверждены** в матрице совместимости Skip. Вероятно, не поддерживаются на Android (не найдены в списке поддерживаемых Views). Плюс баг `withAnimation()` (#402).
> **Вывод по анимации:** Rive через workaround — самый мощный вариант, но требует дополнительных усилий. Lottie безопаснее для Skip, но функционально беднее. Pure SwiftUI blob — рискованно из-за Canvas/TimelineView.
---
## 3. Голосовая интеграция + Skip
### skip-av: статус AVFoundation
Официальный пакет `skip-av` (v0.7.1, 15 мая 2026, 12 ⭐):
| API | Android-поддержка | Что работает |
|-----|-------------------|--------------|
| `AVAudioRecorder` | 🟢 **High** | `record()`, `stop()`, `pause()`, `isRecording`, `peakPower`, `averagePower` |
| `AVAudioPlayer` | 🟢 **High** | `play()`, `pause()`, `stop()`, `volume`, `rate`, `duration` |
| `AVPlayer` | 🟠 Low | Только базовый init/play/pause |
| `VideoPlayer` | 🟡 Medium | `init(player:)` |
**Бэкенд на Android:** `MediaRecorder` + `MediaPlayer` (не ExoPlayer для записи).
```swift
// Запись голоса работает на обеих платформах через skip-av
let settings: [String: Any] = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 16000,
AVNumberOfChannelsKey: 1,
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
]
// Platform-specific путь к файлу
let recordingURL: URL = {
#if SKIP
let context = ProcessInfo.processInfo.androidContext
let file = java.io.File(context.filesDir, "voice_input.m4a")
return URL(fileURLWithPath: file.absolutePath)
#else
return FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
.first!.appendingPathComponent("voice_input.m4a")
#endif
}()
audioRecorder = try AVAudioRecorder(url: recordingURL, settings: settings)
audioRecorder?.record()
```
Нужно добавить в AndroidManifest.xml:
```xml
<uses-permission android:name="android.permission.RECORD_AUDIO" />
```
### WebSocket для OpenAI Realtime API
**История баг-фикса:**
| Событие | Дата |
|---------|------|
| Проблема #559 открыта: libcurl без WebSocket | Дек 2025 |
| Фикс смерджен в swift-docker | 23 Дек 2025 |
| Swift 6.3 официально релизнут с WebSocket | Мар 2026 |
| Skip 1.8 обновлён на официальный Swift 6.3 SDK | Май 2026 |
**Текущий статус (Skip 1.8.14):** WebSocket **должен работать** — Skip 1.8 использует Swift 6.3, где проблема решена. Но статус issue #559 остаётся "Open" — рекомендуется проверить в PoC.
```bash
# Проверить активный SDK
skip android sdk list
# Должен показать swift-6.3-..._android
skip android build --version
```
**Альтернативный подход (более безопасный):** Whisper + TTS вместо Realtime API
```swift
// Более Skip-friendly архитектура:
// 1. Запись голоса AVAudioRecorder (skip-av)
// 2. Отправка файла на Whisper API URLSession (HTTP POST, не WebSocket)
// 3. Ответ через GPT-4 URLSession
// 4. TTS URLSession, воспроизведение AVAudioPlayer (skip-av)
```
HTTP через URLSession **полностью поддерживается** Skip — нет никаких проблем. Whisper+TTS архитектура безопаснее для MVP.
### WebRTC (skip-livekit)
Интересно: в официальных модулях есть `skip-livekit` — WebRTC через LiveKit. Но для OpenAI Realtime API WebRTC нужен другой конкретный эфемерный ключ, не LiveKit. Это не подходит напрямую.
### Механизм platform-specific кода
Skip предоставляет три директивы препроцессора:
```swift
// Код только для Android (в Fuse: нативный Swift; в Lite: транспилируется)
#if os(Android)
// ...
#endif
// Код транспилируется в Kotlin (можно вызывать Kotlin/Java API напрямую)
#if SKIP
import android.content.pm.PackageManager
let hasPermission = context.checkSelfPermission(
android.Manifest.permission.RECORD_AUDIO
) == PackageManager.PERMISSION_GRANTED
#endif
// Только iOS
#if !os(Android)
import AVFoundation
AVAudioSession.sharedInstance().requestRecordPermission { granted in ... }
#endif
```
**Это мощный escape hatch** — любая iOS-only функциональность доступна без ограничений в `#if !SKIP` блоках.
---
## 4. Альтернативы если Skip не готов
### iOS-first MVP без Android
**Плюсы:**
- ✅ Нет компромиссов — полный RiveRuntime, полный AVFoundation, WebRTC
- ✅ iOS = 5× выше ARPU ($140 vs $69 в год на пользователя)
- ✅ Скорость разработки — нет overhead на кросс-платформу
- ✅ App Store первичен для платных подписок
**Минусы:**
- ❌ Упускаем ~3.7B Android пользователей
- ❌ Если позже добавлять Android — переписывать
**Коммерческая оценка:** Для подписочного приложения iOS-first — **стандартная практика**. Большинство AI-приложений (Calm, Headspace, Replika) стартовали с iOS. Android добавляли позже.
### React Native 2025
| Критерий | Оценка |
|----------|--------|
| Голос (микрофон, TTS) | ✅ expo-av, хорошая поддержка |
| Rive анимация | ✅ `rive-react-native` — официальный runtime! |
| OpenAI Realtime API | ✅ нет проблем с WebSocket |
| Подписки | ✅ react-native-purchases (RevenueCat) |
| Производительность анимаций | ⚠️ JS bridge может давать jank |
| Язык для iOS-разработчика | ❌ TypeScript/JS — новый стек |
| New Architecture migration | ⚠️ Legacy arch заморожена с июня 2025 |
**Итог:** Функционально React Native покрывает все наши нужды. Но требует знания JS/TS экосистемы. Rive Runtime для React Native — официальный и зрелый.
### Flutter 2025
| Критерий | Оценка |
|----------|--------|
| Голос | ✅ `flutter_sound`, `speech_to_text` |
| Rive анимация | ✅ официальный `rive` пакет на pub.dev |
| OpenAI Realtime API | ✅ WebSocket нативный |
| Подписки | ✅ `purchases_flutter` (RevenueCat) |
| Производительность | ⚠️ +40 МБ overhead, GC паузы |
| iOS 26 "Liquid Glass" UI | ❌ Flutter команда **отказалась** адаптировать Cupertino widgets |
| Язык | ❌ Dart — новый стек |
**Критическое замечание:** GitHub issues flutter #170310 — Flutter команда подтвердила, что не будет имплементировать новый Apple '26 UI дизайн в Cupertino библиотеке в ближайшее время. Для AI-приложения это может не критично, но iOS UI выглядит устаревшим.
### Kotlin Multiplatform + Compose Multiplatform
| Критерий | Оценка |
|----------|--------|
| UI фреймворк | Compose Multiplatform (нативный Android, mimicked iOS) |
| Rive | ✅ `Rive-CMP` (community, v0.4.0, 105 ⭐) |
| Голос | ✅ kotlin-native доступ к platform APIs |
| Для Swift-разработчика | ❌ Нужен Kotlin — совсем новый стек |
| iOS UI | ⚠️ Не SwiftUI — кастомный рендеринг Skia |
Для Swift-разработчика KMP — самый далёкий вариант. Хотя технически сильный.
### Capacitor/Ionic
**Не рекомендуется** для нашего кейса. WebView-рендеринг, анимации через CSS/JS будут уступать нативным, особенно для персонажа и голоса.
---
## 5. Конкретный план PoC на 1 неделю
### Цель PoC
Ответить на три вопроса:
1. Работает ли WebSocket / Whisper API через Skip на Android?
2. Реализуем ли анимированный персонаж (Lottie или Rive workaround)?
3. Работает ли запись голоса через skip-av?
### День 1: Базовый проект
```bash
brew tap skiptools/skip && brew install skip
skip checkup
# Создаём проект в режиме Fuse
skip android sdk install # убедиться что 6.3+
skip init --fuse-app --appid=com.yourapp.reflection reflection-app ReflectionApp
# Проверяем SDK версию
skip android sdk list
```
**Критерий успеха:** Базовое SwiftUI приложение запускается параллельно на iOS Simulator и Android Emulator.
### День 2-3: Голос + сеть
```swift
// Тест 1: Запись через AVAudioRecorder
// Тест 2: HTTP POST на Whisper API (URLSession)
// Тест 3: WebSocket соединение (если нужен Realtime API)
```
```swift
// Проверка WebSocket
import Foundation
class WebSocketTest: ObservableObject {
var task: URLSessionWebSocketTask?
func test() {
let url = URL(string: "wss://echo.websocket.org")!
task = URLSession.shared.webSocketTask(with: url)
task?.resume()
task?.send(.string("Hello")) { error in
print(error == nil ? "✅ WebSocket работает!" : "\(error!)")
}
}
}
```
**Критерий успеха:** Запись работает на Android, HTTP к OpenAI проходит, WebSocket не выдаёт ошибку libcurl.
### День 4-5: Анимированный персонаж
**Вариант A (рекомендуется для PoC): Lottie через skip-motion**
```swift
// Package.swift: добавить skip-motion
.package(url: "https://source.skip.dev/skip-motion.git", "0.0.0"..<"2.0.0")
```
```swift
import SkipMotion
struct CharacterView: View {
var isListening: Bool
var body: some View {
MotionView(lottie: isListening ? listeningAnimation : idleAnimation)
.frame(width: 250, height: 250)
}
}
```
**Вариант B (для Rive):** Реализовать RiveCharacterView с #if SKIP/iOS разделением (как показано выше). Добавить rive-android в `skip.yml`:
```yaml
# Android/app/src/main/skip.yml
dependencies:
- app.rive:rive-android:9.12.0
```
**Критерий успеха:** Персонаж анимируется на обеих платформах, состояния переключаются.
### День 6-7: Интеграция и оценка
- Собрать мини end-to-end: нажал кнопку → запись → Whisper → ответ → TTS → воспроизведение → персонаж реагирует
- Замерить производительность анимации на Android (fps)
- Оценить размер APK
### Критерии успеха/провала PoC
| Критерий | Success | Fail |
|----------|---------|------|
| Голосовая запись | Работает на Android API 28+ | Крэшит или нет звука |
| HTTP к OpenAI | Запросы проходят | SSL/network ошибки |
| WebSocket | Соединение устанавливается | libcurl ошибка |
| Анимация (Lottie) | Плавная, состояния переключаются | Дёргается, не отображается |
| Rive workaround (опц.) | Загружается .riv файл | Compile error, не интегрируется |
| Общая стабильность | Нет крэшей при 10-мин сессии | Крэши, ANR на Android |
### Fallback план если PoC провалился
**Уровень 1 (мягкий фейл — одна проблема):**
- WebSocket не работает → используем Whisper+TTS по HTTP
- Rive не интегрируется → используем Lottie или SwiftUI анимации
- Lottie не устраивает → делаем чистую iOS-версию с Rive, Android откладываем
**Уровень 2 (полный фейл Skip):**
Переходим на **iOS-first MVP** (натив SwiftUI):
- 4-6 недель до первой версии
- Полный Rive, полный AVFoundation, OpenAI Realtime API
- Android: через 3-6 месяцев либо через React Native (Rive официально поддерживается), либо через Skip если к тому времени созреет
---
## 6. Итоговая рекомендация
### Рекомендованная стратегия: "Skip с Lottie + Whisper-first"
```
Неделя 1-2: PoC на Skip (план выше)
Неделя 3-6: MVP на Skip если PoC ✅
↓ если PoC ❌
iOS-first MVP (нативный SwiftUI + Rive)
```
**Рекомендованный стек для MVP на Skip:**
| Компонент | Решение |
|-----------|---------|
| UI фреймворк | SwiftUI + Skip Fuse |
| Анимация персонажа | **Lottie через skip-motion** (безопасно) или Rive с platform-specific workaround |
| Голосовой ввод | AVAudioRecorder через **skip-av** |
| STT | **Whisper API по HTTP** (не WebSocket) — максимально безопасно |
| TTS | OpenAI TTS API по HTTP + AVAudioPlayer |
| AI диалог | GPT-4o через HTTP/URLSession |
| Подписки | **skip-revenue** (RevenueCat официально поддержан) |
| Аналитика | **skip-posthog** (официально) |
| Auth | **skip-firebase** (Firebase Auth) |
**Почему Whisper+TTS вместо Realtime API:**
- WebSocket технически починен в Skip 1.8 (Swift 6.3), но нужно верифицировать в PoC
- Whisper+TTS архитектура — надёжнее и дешевле для рефлексии (нет потоковой передачи)
- Можно добавить Realtime API позже как premium-фичу
**Почему Lottie вместо Rive:**
- Официальный skip-motion пакет, нет platform-specific кода
- Для MVP не нужна полная State Machine Rive
- Rive можно добавить после MVP когда сделаете полноценный workaround
### Ограничения и риски при использовании Skip
| Риск | Уровень | Митигация |
|------|---------|-----------|
| Баг `withAnimation()` (#402) утечка в глобальное состояние | 🔴 Высокий | Тестировать в PoC, использовать `.animation()` modifier вместо `withAnimation` |
| Canvas/TimelineView не поддерживаются | 🔴 Высокий | Использовать Lottie/Rive, не делать чистый SwiftUI blob |
| WebSocket не верифицирован в production | 🟡 Средний | Whisper+TTS как план A |
| Rive workaround требует два кодабейса | 🟡 Средний | Lottie для MVP, Rive потом |
| +60 МБ к размеру APK (Skip Fuse) | 🟢 Низкий | Приемлемо для B2C приложения |
| Мало примеров third-party production apps | 🟡 Средний | Активное сообщество, официальные примеры |
### Если НЕ использовать Skip прямо сейчас
**Лучшая альтернатива для этого конкретного кейса:**
1. **iOS MVP (нативный SwiftUI)** — 4-6 недель, полный Rive, AVFoundation, Realtime API
2. **Android через 6+ месяцев:**
- Re-evaluate Skip (к тому времени Canvas поддержка появится)
- Или React Native (Rive official runtime, mature ecosystem)
**Не рекомендуется:**
- Flutter — из-за iOS 26 UI regression и неопределённости команды
- Ionic/Capacitor — для анимированного персонажа и голоса WebView недостаточен
---
## Приложения: Ссылки и источники
### Skip официальная документация
- [skip.tools/docs](https://skip.tools/docs) — главная документация
- [skip.tools/docs/modules/skip-ui/](https://skip.tools/docs/modules/skip-ui/) — матрица совместимости SwiftUI
- [skip.tools/docs/modules/skip-av/](https://skip.tools/docs/modules/skip-av/) — AVFoundation поддержка
- [skip.tools/docs/platformcustomization/](https://skip.tools/docs/platformcustomization/) — #if SKIP механизм
- [skip.tools/compare/](https://skip.tools/compare/) — сравнение с Flutter/React Native
### GitHub Issues (ключевые)
- [#559](https://github.com/skiptools/skip/issues/559) — WebSocket не работал в libcurl (починен в 6.3)
- [#402](https://github.com/skiptools/skip-ui/issues/402) — withAnimation() глобальный state баг
- [#687](https://github.com/skiptools/skip/issues/687) — NavigationLink state bug (Fuse)
### Skip-пакеты для нашего кейса
- [skip-motion](https://github.com/skiptools/skip-motion) — Lottie анимации
- [skip-av](https://github.com/skiptools/skip-av) — AVFoundation / аудио
- [skip-revenue](https://github.com/skiptools/skip-revenue) — RevenueCat подписки
- [skip-firebase](https://github.com/skiptools/skip-firebase) — Firebase Auth/Firestore
### Rive
- [rive-app/rive-ios](https://github.com/rive-app/rive-ios) — iOS runtime (v6.20.3, 780 ⭐)
- [rive-app/rive-android](https://github.com/rive-app/rive-android) — Android runtime (Compose API beta)
- [Rive-CMP](https://github.com/muazkadan/Rive-CMP) — Community Compose Multiplatform wrapper
### OpenAI Realtime API
- [swift-realtime-openai](https://github.com/m1guelpf/swift-realtime-openai) — Swift SDK (431 ⭐, поддержка WebRTC+WebSocket)
---
*Документ создан: 16 мая 2026. Актуален для Skip v1.8.14 и Swift 6.3.*