Нативное iOS приложение для сохранения и организации контента с голосовыми заметками и интеллектуальным поиском.
Voice Bookmarks позволяет быстро сохранять различные типы контента (файлы, ссылки, изображения, видео) с добавлением голосовых заметок на русском языке. Приложение использует AI для автоматической категоризации и предоставляет семантический поиск по сохраненному контенту.
Проект полностью документирован краткими комментариями по сути, которые помогают разработчикам быстро понимать архитектуру и логику работы приложения.
- Share Extension — сохранение контента из любых iOS приложений
- Буфер обмена — быстрое сохранение из буфера обмена
- Множественные форматы — поддержка текста, изображений, аудио, видео, PDF и других файлов
- Автоматическое определение типа — определение типа контента по расширению и содержимому
- Голосовые заметки — распознавание речи на русском языке с улучшенной обработкой
- Обработка транскрипции — автоматическое исправление ошибок распознавания, добавление пунктуации
- Слияние частичных результатов — умное объединение частичных результатов распознавания речи
- Голосовой поиск — поиск с помощью голосовых команд
- AI-категоризация — автоматическое распределение контента по категориям
- Иерархические папки — поддержка вложенных папок и категорий
- Семантический поиск — поиск по содержимому с поддержкой естественного языка
- Поиск внутри файлов — глубокий поиск по содержимому сохраненных файлов
- Выполнение команд — генерация HTML-ответов на основе сохраненного контента
- Кеширование — кеширование закладок и папок для быстрого доступа (5 минут)
- Офлайн режим — работа без интернета с автоматической синхронизацией при восстановлении связи
- Очередь загрузок — автоматическая обработка отложенных загрузок с защитой от дубликатов
- Мониторинг сети — автоматическое определение состояния сети и обработка очереди
- Безопасное хранение — UUID пользователя хранится в Keychain
- Система логирования — структурированное логирование с категориями и уровнями
- App Groups — безопасный обмен данными между приложением и Share Extension
- iOS 15.0+
- Xcode 15.0+
- Swift 5.9+
- Версия: 1.0
- Build: 1
- Клонируйте репозиторий:
git clone https://github.com/yourusername/VoiceBookmarks.git
cd VoiceBookmarks- Откройте проект в Xcode:
open VoiceBookmarks.xcodeproj-
Настройте конфигурацию приложения (обязательно перед использованием):
Подробная инструкция: См. файл CONFIGURATION.md
Откройте
VoiceBookmarks/Utils/Constants.swiftи замените:static let baseURL = "https://your-api-server.com"
на адрес вашего API сервера.
В Xcode:
- Выберите проект в навигаторе
- Выберите target
VoiceBookmarks - Перейдите в вкладку "Signing & Capabilities"
- Настройте Bundle Identifier (например:
com.yourcompany.yourapp) - Добавьте App Groups capability
- Добавьте ваш App Group identifier (например:
group.com.yourcompany.yourapp) - Повторите для target
VoiceBookmarksShareExtension
Затем обновите в
Constants.swift:// В enum Keychain static let service = "com.yourcompany.yourapp.keychain" // В enum AppGroups static let identifier = "group.com.yourcompany.yourapp"
И в
LoggerService.swift:private let osLog = OSLog(subsystem: "com.yourcompany.yourapp", category: "app")
Откройте
VoiceBookmarks/Info.plistи обновите:<key>CFBundleURLSchemes</key> <array> <string>yourapp</string> </array>
Замените
yourappна ваш URL scheme.Также обновите в
ShareViewController.swift:let url = URL(string: "yourapp://share-extension")
-
Запустите на симуляторе или устройстве
- Из буфера обмена: Откройте приложение, нажмите на экран и используйте кнопку "Вставить"
- Из других приложений: Используйте Share Extension для сохранения контента из любого приложения
- Голосовая заметка: Удерживайте палец на контенте для записи голосовой заметки
- Текстовый поиск: Введите запрос в поле поиска
- Голосовой поиск: Удерживайте палец на папке для голосового поиска
- Поиск внутри файла: Удерживайте палец на файле для вложенного поиска
- Tap на папке — открыть список файлов в папке
- Long press на папке — голосовой поиск в папке
- Long press на файле — поиск внутри файла
- Swipe вниз — закрыть экран
- Swipe вверх — сохранить файл (в просмотре)
Приложение включает продвинутую обработку транскрипции речи:
- Автоматическое исправление ошибок — исправление типичных ошибок распознавания речи
- Добавление пунктуации — автоматическое добавление запятых, точек, тире
- Слияние результатов — умное объединение частичных результатов распознавания
- Удаление дубликатов — автоматическое удаление повторяющихся слов и фраз
- Нормализация текста — приведение текста к читаемому виду с правильными пробелами
- Base URL: Настраивается в
Constants.swift(по умолчанию:https://your-api-server.com) - Авторизация: Header
X-User-IDс UUID пользователя - Timeout: 30 секунд
- Retry: до 3 попыток с задержкой 1 секунда
VoiceBookmarks/Utils/Constants.swift
/api/auth/anonymous— анонимная авторизация/api/folders— управление папками/категориями/api/bookmarks— работа с закладками/api/search— семантический поиск/api/download— загрузка файлов/api/categories/{category}/bookmarks— закладки по категории
Полная спецификация API доступна в swagger.yaml
- Backend: Python FastAPI
- Vector DB: Weaviate (Documents + Chunks)
- Storage: Supabase Storage
- AI: OpenAI (GPT-4, Vision, Whisper)
Проект построен на архитектуре MVVM с использованием SwiftUI и dependency injection:
- Models — модели данных (Bookmark, Folder, ContentType, SearchResponse, CommandResponse)
- Views — SwiftUI представления с компонентами для различных типов контента
- ViewModels — бизнес-логика и состояние (ShareViewModel, SearchViewModel, WebViewModel)
- Services — сервисы для работы с сетью, файлами, речью, кешированием
- Persistence — Core Data для локального хранения офлайн очереди
- AuthService — анонимная авторизация и управление userId
- BookmarkService — загрузка, сохранение и удаление закладок
- SearchService — семантический поиск и выполнение команд
- NetworkService — HTTP запросы с retry логикой и обработкой ошибок
- NetworkMonitor — мониторинг состояния сети
- OfflineQueueService — управление офлайн очередью с автоматической синхронизацией
- SpeechService — распознавание речи на русском языке
- TextPostProcessor — постобработка транскрипции (исправление ошибок, пунктуация)
- TranscriptionMerger — слияние частичных результатов распознавания речи
- FileService — работа с файлами и данными
- ClipboardService — работа с буфером обмена
- BookmarkCacheService — кеширование закладок по категориям
- FolderCacheService — кеширование иерархии папок
- LoggerService — структурированное логирование с категориями
- KeychainService — безопасное хранение данных в Keychain
- GlobalToastManager — глобальные уведомления
- Dependency Injection — все сервисы создаются в точке входа приложения
- Thread Safety — использование actors и locks для защиты от гонок данных
- Error Handling — централизованная обработка ошибок с логированием
- Offline First — приоритет локального кеша и офлайн очереди
- Reactive Programming — использование Combine для реактивных обновлений UI
Проект использует только нативные фреймворки iOS, внешние зависимости отсутствуют:
- SwiftUI — пользовательский интерфейс
- Combine — реактивное программирование и потоки данных
- UIKit — интеграция с системными компонентами
- Core Data — локальное хранение офлайн очереди
- UserDefaults — кеширование и настройки (с App Groups для Share Extension)
- Keychain — безопасное хранение пользовательских данных
- Network — мониторинг состояния сети (NWPathMonitor)
- URLSession — HTTP запросы к API
- Speech — распознавание речи на русском языке (SFSpeechRecognizer)
- AVFoundation — обработка видео и аудио
- WebKit — отображение контента (WKWebView для HTML, PDF, изображений)
- Security — хранение данных в Keychain
- App Groups — безопасный обмен данными между приложением и расширениями
Проект включает comprehensive тестовое покрытие:
- Unit тесты — тестирование моделей, сервисов, ViewModels
- UI тесты — автоматизированное тестирование пользовательского интерфейса
- Share Extension тесты — тестирование функциональности Share Extension
# Запуск всех тестов
xcodebuild test -scheme VoiceBookmarks -destination 'platform=iOS Simulator,name=iPhone 15'
# Запуск только unit тестов
xcodebuild test -scheme VoiceBookmarks -only-testing:VoiceBookmarksTests -destination 'platform=iOS Simulator,name=iPhone 15'
# Запуск только UI тестов
xcodebuild test -scheme VoiceBookmarks -only-testing:VoiceBookmarksUITests -destination 'platform=iOS Simulator,name=iPhone 15'Приложение поддерживает специальные режимы для UI тестов:
--UITestSeedFolders— использование мокового SearchService для тестирования--UITestShareSeed— специальный режим для тестирования Share Extension
VoiceBookmarks/
├── VoiceBookmarks/ # Основное приложение
│ ├── App/
│ │ └── VoiceBookmarksApp.swift # Точка входа, инициализация сервисов
│ ├── Models/ # Модели данных
│ │ ├── Bookmark.swift # Модель закладки с нормализацией типа
│ │ ├── Folder.swift # Иерархические папки
│ │ ├── ContentType.swift # Типы контента (text, audio, video, image, file)
│ │ ├── SearchResponse.swift # Результаты поиска
│ │ ├── CommandResponse.swift # Результаты выполнения команд
│ │ └── ...
│ ├── Views/ # SwiftUI представления
│ │ ├── MainTabView.swift # Главный экран с вкладками
│ │ ├── Components/ # Переиспользуемые компоненты
│ │ │ ├── ContentPreviewView.swift # Превью контента
│ │ │ ├── ToastView.swift # Уведомления
│ │ │ ├── TranscriptionView.swift # Отображение транскрипции
│ │ │ └── ...
│ │ ├── Search/ # Экран поиска
│ │ │ ├── SearchView.swift
│ │ │ ├── FolderListView.swift # Список папок
│ │ │ ├── FileListView.swift # Список файлов
│ │ │ └── ...
│ │ ├── Share/ # Экран сохранения
│ │ │ └── ShareView.swift
│ │ └── WebView/ # Просмотр контента
│ │ ├── WebContentView.swift
│ │ ├── ImagePreviewView.swift
│ │ ├── VideoPreviewView.swift
│ │ └── ...
│ ├── ViewModels/ # Бизнес-логика
│ │ ├── ShareViewModel.swift # Логика сохранения контента
│ │ ├── SearchViewModel.swift # Логика поиска
│ │ ├── WebViewModel.swift # Логика просмотра контента
│ │ └── TranscriptionProcessingExtension.swift
│ ├── Services/
│ │ ├── API/ # API сервисы
│ │ │ ├── AuthService.swift
│ │ │ ├── BookmarkService.swift
│ │ │ └── SearchService.swift
│ │ └── Core/ # Основные сервисы
│ │ ├── NetworkService.swift
│ │ ├── NetworkMonitor.swift
│ │ ├── OfflineQueueService.swift
│ │ ├── SpeechService.swift
│ │ ├── TextPostProcessor.swift # Обработка транскрипции
│ │ ├── TranscriptionMerger.swift # Слияние результатов
│ │ ├── BookmarkCacheService.swift
│ │ ├── FolderCacheService.swift
│ │ ├── LoggerService.swift
│ │ └── ...
│ ├── Persistence/
│ │ └── PersistenceController.swift # Core Data контроллер
│ └── Utils/
│ ├── Constants.swift # Централизованные константы
│ ├── SharedUserDefaults.swift # Общий UserDefaults для App Group
│ └── Extensions/ # Расширения Swift
├── VoiceBookmarksShareExtension/ # Share Extension
│ ├── ShareViewController.swift
│ └── ShareExtensionView.swift
├── VoiceBookmarksTests/ # Unit тесты
│ ├── Models/
│ ├── Services/
│ ├── ViewModels/
│ └── Mocks/ # Моки для тестирования
├── VoiceBookmarksUITests/ # UI тесты
├── VoiceBookmarksShareExtensionTests/ # Тесты Share Extension
├── VoiceBookmarks.xcodeproj/ # Xcode проект
├── swagger.yaml # API спецификация
└── LICENSE # Лицензия Apache 2.0
Приложение запрашивает следующие разрешения:
- Микрофон (
NSMicrophoneUsageDescription) — для записи голосовых заметок - Распознавание речи (
NSSpeechRecognitionUsageDescription) — для голосового ввода на русском языке
Разрешения запрашиваются только при первом использовании соответствующих функций.
Все настройки централизованы в Constants.swift:
- API: base URL, таймауты, endpoints, заголовки
- Speech: locale (ru-RU), таймауты распознавания, максимальная длительность
- Files: максимальный размер (500 MB), качество сжатия
- UI: анимации, размеры, цвета, иконки
- Keychain: ключи для хранения данных
- App Groups: identifier для обмена данными
- Core Data: имя модели и контейнера
- Categories: предопределенные категории
Перед публикацией в публичный репозиторий все чувствительные данные заменены на placeholder значения:
- API Base URL:
https://your-api-server.com(замените на ваш сервер) - App Group Identifier:
group.com.yourcompany.yourapp(замените на ваш) - Keychain Service:
com.yourcompany.yourapp.keychain(замените на ваш bundle identifier) - URL Scheme:
yourapp(замените на ваш) - OSLog Subsystem:
com.yourcompany.yourapp(замените на ваш bundle identifier)
Все эти значения необходимо настроить перед использованием приложения (см. раздел "Установка").
Для работы Share Extension необходимо настроить App Group:
- Identifier: Настраивается в Xcode Capabilities (по умолчанию:
group.com.yourcompany.yourapp) - Используется для обмена данными между приложением и Share Extension
- Не забудьте обновить значение в
Constants.swiftпосле настройки в Xcode
Contributions are welcome! Please feel free to submit a Pull Request.
Проект распространяется под лицензией Apache License 2.0. См. файл LICENSE для подробностей.
Для вопросов и предложений создайте issue в репозитории.
