name: 移动端离线存储 description: 跨平台离线优先数据管理 version: 1.0.0 category: 数据持久化 slug: offline-storage status: 活跃
移动端离线存储技能
概述
本技能提供跨平台离线优先数据管理能力。支持配置WatermelonDB、Realm、MMKV等离线存储解决方案,并配备同步队列架构。
允许使用的工具
bash- 执行包管理器和构建工具read- 分析存储配置和模式write- 生成模型和同步逻辑edit- 更新存储实现glob- 搜索存储文件grep- 搜索模式
核心能力
WatermelonDB (React Native)
-
模式定义
- 定义表模式
- 配置列类型
- 设置关系
- 处理迁移
-
同步引擎
- 实现同步适配器
- 处理冲突解决
- 配置批量操作
- 管理同步状态
Realm (跨平台)
-
对象模式
- 定义Realm对象
- 配置主键
- 设置关系
- 处理嵌入式对象
-
Realm同步
- 配置设备同步
- 处理灵活同步
- 管理订阅
- 处理冲突
MMKV
- 键值存储
- 配置MMKV实例
- 处理加密
- 实现迁移
- 管理命名空间
同步架构
-
离线优先模式
- 设计同步队列
- 处理网络状态
- 实现重试逻辑
- 管理待处理操作
-
冲突解决
- 最后写入获胜策略
- 合并策略
- 用户解决界面
- 审计日志
目标流程
offline-first-architecture.js- 离线模式rest-api-integration.js- API同步graphql-apollo-integration.js- GraphQL同步
依赖项
- WatermelonDB (React Native)
- Realm SDK
- MMKV
- SQLite
使用示例
WatermelonDB模式
// database/schema.ts
import { appSchema, tableSchema } from '@nozbe/watermelondb';
export const schema = appSchema({
version: 1,
tables: [
tableSchema({
name: 'posts',
columns: [
{ name: 'title', type: 'string' },
{ name: 'body', type: 'string' },
{ name: 'is_published', type: 'boolean' },
{ name: 'author_id', type: 'string', isIndexed: true },
{ name: 'created_at', type: 'number' },
{ name: 'updated_at', type: 'number' },
],
}),
tableSchema({
name: 'comments',
columns: [
{ name: 'body', type: 'string' },
{ name: 'post_id', type: 'string', isIndexed: true },
{ name: 'author_id', type: 'string' },
{ name: 'created_at', type: 'number' },
],
}),
],
});
WatermelonDB模型
// database/models/Post.ts
import { Model, Q } from '@nozbe/watermelondb';
import { field, date, children, relation } from '@nozbe/watermelondb/decorators';
export class Post extends Model {
static table = 'posts';
static associations = {
comments: { type: 'has_many', foreignKey: 'post_id' },
author: { type: 'belongs_to', key: 'author_id' },
};
@field('title') title!: string;
@field('body') body!: string;
@field('is_published') isPublished!: boolean;
@field('author_id') authorId!: string;
@date('created_at') createdAt!: Date;
@date('updated_at') updatedAt!: Date;
@children('comments') comments!: Query<Comment>;
@relation('users', 'author_id') author!: Relation<User>;
}
同步队列实现
// sync/SyncQueue.ts
interface SyncOperation {
id: string;
type: 'create' | 'update' | 'delete';
entity: string;
payload: any;
timestamp: number;
retryCount: number;
}
class SyncQueue {
private queue: SyncOperation[] = [];
private isProcessing = false;
async enqueue(operation: Omit<SyncOperation, 'id' | 'timestamp' | 'retryCount'>) {
const op: SyncOperation = {
...operation,
id: uuid(),
timestamp: Date.now(),
retryCount: 0,
};
this.queue.push(op);
await this.persistQueue();
this.processQueue();
}
private async processQueue() {
if (this.isProcessing || this.queue.length === 0) return;
const isOnline = await NetInfo.fetch().then(state => state.isConnected);
if (!isOnline) return;
this.isProcessing = true;
while (this.queue.length > 0) {
const operation = this.queue[0];
try {
await this.executeOperation(operation);
this.queue.shift();
await this.persistQueue();
} catch (error) {
operation.retryCount++;
if (operation.retryCount >= 3) {
this.queue.shift();
await this.logFailedOperation(operation, error);
}
break;
}
}
this.isProcessing = false;
}
private async executeOperation(operation: SyncOperation) {
switch (operation.type) {
case 'create':
return api.post(`/${operation.entity}`, operation.payload);
case 'update':
return api.put(`/${operation.entity}/${operation.payload.id}`, operation.payload);
case 'delete':
return api.delete(`/${operation.entity}/${operation.payload.id}`);
}
}
}
质量门控
- 同步时验证数据完整性
- 冲突解决测试
- 离线功能验证
- 迁移测试通过
相关技能
ios-persistence- iOS Core Dataandroid-room- Android Roomgraphql-mobile- GraphQL离线
版本历史
- 1.0.0 - 初始发布