store chat history in SwiftData

Replace the per-account JSON snapshot with SwiftData @Model records
(ConversationRecord, MessageRecord, ArchiveMetadataRecord). The
in-memory
value types stay unchanged; ChatArchive now persists through a shared
ModelContainer filtered by accountJID. Legacy JSON is migrated once on
first load and then removed.
This commit is contained in:
wt committed 2026-08-18 14:49:55 +07:00
1 parent 9c8cff7168
commit a57e45111b
2 files changed
+149 -29

No files matched your search

+13 -2
View File
@@ -9,7 +9,7 @@
3. `LumaOMEMOStore` адаптирует постоянное состояние к Signal storage callbacks;
AES-GCM выполняется CryptoKit.
4. `AppModel` сводит сетевые события в UI-состояние, дедуплицирует MAM/live
сообщения и сохраняет snapshot локально.
сообщения и сохраняет snapshot локально через SwiftData.
5. SwiftUI views используют один и тот же слой моделей на iOS/iPadOS/macOS.
6. watchOS не держит отдельный XMPP-сокет: iPhone передаёт компактный snapshot,
текстовые ответы возвращаются немедленно или через гарантированную очередь,
@@ -18,6 +18,17 @@
XMPP, отправляет запись через тот же XEP-0363/OMEMO-пайплайн и возвращает
часам отдельный результат фактической отправки.
## Локальное хранение
История чатов сохраняется в SwiftData: `ChatArchive` работает поверх `@Model`-
записей `ConversationRecord`, `MessageRecord` и `ArchiveMetadataRecord`
(`Sources/Shared/Persistence/`). Доменные типы `Conversation`/`ChatMessage`
остаются value-типами в памяти, а SwiftData — только слой долговременного
хранения. Контейнер один на приложение и фильтрует записи по `accountJID`.
Вложенные Codable-значения (реакции, call-метаданные, MAM-чекпоинты) хранятся
как `Data`-атрибуты. При первом запуске после обновления старый JSON-снапшот
(`Luma/Accounts/<hash>.json`) однократно переносится в SwiftData и удаляется.
## Контакты
`RosterModule` Martin передаёт initial roster и последующие roster-push в
@@ -205,6 +216,6 @@ PushKit/CallKit и серверной APNs-инфраструктуры.
- APNs provider + XEP-0357 registration;
- современный `urn:xmpp:omemo:2` adapter и миграция устройств;
- MIX и реакции;
- SQLite/SQLCipher вместо JSON snapshot;
- шифрование SQLite-хранилища (SQLCipher-уровня) поверх SwiftData;
- PushKit/CallKit для фоновых входящих звонков и групповые звонки;
- share extension и notification service extension.