NativeScript 本地存储 #

存储概述 #

NativeScript 提供了多种本地存储方案,满足不同场景的数据存储需求。

text
┌─────────────────────────────────────────────────────────────┐
│                    存储方案                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Application Settings                                       │
│  ├── 键值对存储                                             │
│  ├── 适合简单配置数据                                       │
│  └── 容量有限                                               │
│                                                             │
│  文件系统                                                    │
│  ├── 文件读写                                               │
│  ├── 适合大文件存储                                         │
│  └── 需要手动管理                                           │
│                                                             │
│  SQLite                                                     │
│  ├── 关系型数据库                                           │
│  ├── 适合结构化数据                                         │
│  └── 支持复杂查询                                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Application Settings #

基本用法 #

typescript
import { ApplicationSettings } from '@nativescript/core';

// 存储字符串
ApplicationSettings.setString('username', 'john');
const username = ApplicationSettings.getString('username');

// 存储数字
ApplicationSettings.setNumber('age', 25);
const age = ApplicationSettings.getNumber('age');

// 存储布尔值
ApplicationSettings.setBoolean('isLoggedIn', true);
const isLoggedIn = ApplicationSettings.getBoolean('isLoggedIn');

// 检查键是否存在
const hasKey = ApplicationSettings.hasKey('username');

// 删除键
ApplicationSettings.remove('username');

// 清空所有设置
ApplicationSettings.clear();

默认值 #

typescript
// 如果键不存在,返回默认值
const theme = ApplicationSettings.getString('theme', 'light');
const volume = ApplicationSettings.getNumber('volume', 50);
const enabled = ApplicationSettings.getBoolean('enabled', false);

存储对象 #

typescript
// 存储对象(需要序列化)
const user = {
    id: 1,
    name: 'John',
    email: 'john@example.com'
};

ApplicationSettings.setString('user', JSON.stringify(user));

// 读取对象
const userJson = ApplicationSettings.getString('user');
const savedUser = JSON.parse(userJson);

封装 Settings 服务 #

typescript
// services/settings.service.ts
import { Injectable } from '@angular/core';
import { ApplicationSettings } from '@nativescript/core';

@Injectable({
    providedIn: 'root'
})
export class SettingsService {
    private static PREFIX = 'app_';
    
    set<T>(key: string, value: T): void {
        const fullKey = SettingsService.PREFIX + key;
        
        if (typeof value === 'string') {
            ApplicationSettings.setString(fullKey, value);
        } else if (typeof value === 'number') {
            ApplicationSettings.setNumber(fullKey, value);
        } else if (typeof value === 'boolean') {
            ApplicationSettings.setBoolean(fullKey, value);
        } else {
            ApplicationSettings.setString(fullKey, JSON.stringify(value));
        }
    }
    
    get<T>(key: string, defaultValue?: T): T {
        const fullKey = SettingsService.PREFIX + key;
        
        if (!ApplicationSettings.hasKey(fullKey)) {
            return defaultValue;
        }
        
        const type = typeof defaultValue;
        
        if (type === 'string') {
            return ApplicationSettings.getString(fullKey) as T;
        } else if (type === 'number') {
            return ApplicationSettings.getNumber(fullKey) as T;
        } else if (type === 'boolean') {
            return ApplicationSettings.getBoolean(fullKey) as T;
        } else {
            const json = ApplicationSettings.getString(fullKey);
            return JSON.parse(json) as T;
        }
    }
    
    remove(key: string): void {
        ApplicationSettings.remove(SettingsService.PREFIX + key);
    }
    
    clear(): void {
        ApplicationSettings.clear();
    }
}

文件系统 #

基本概念 #

typescript
import { knownFolders, Folder, File } from '@nativescript/core';

// 已知文件夹
const appFolder = knownFolders.currentApp();      // 应用目录
const documentsFolder = knownFolders.documents(); // 文档目录
const tempFolder = knownFolders.temp();           // 临时目录

文件操作 #

typescript
import { knownFolders, File } from '@nativescript/core';

// 创建文件
const folder = knownFolders.documents();
const file = folder.getFile('data.txt');

// 写入文本
await file.writeText('Hello, World!');

// 读取文本
const text = await file.readText();

// 写入二进制
await file.writeBinary(binaryData);

// 读取二进制
const data = await file.readBinary();

// 删除文件
await file.remove();

文件夹操作 #

typescript
import { knownFolders, Folder } from '@nativescript/core';

// 创建文件夹
const folder = knownFolders.documents().getFolder('myFolder');

// 检查文件夹是否存在
const exists = Folder.exists(folder.path);

// 获取文件夹内容
const entities = await folder.getEntities();
entities.forEach(entity => {
    console.log(entity.name, entity.path);
});

// 删除文件夹
await folder.remove();

文件管理服务 #

typescript
// services/file.service.ts
import { Injectable } from '@angular/core';
import { knownFolders, File, Folder } from '@nativescript/core';

@Injectable({
    providedIn: 'root'
})
export class FileService {
    private dataFolder: Folder;
    
    constructor() {
        this.dataFolder = knownFolders.documents().getFolder('app_data');
    }
    
    async saveFile(filename: string, content: string): Promise<File> {
        const file = this.dataFolder.getFile(filename);
        await file.writeText(content);
        return file;
    }
    
    async readFile(filename: string): Promise<string> {
        const file = this.dataFolder.getFile(filename);
        if (File.exists(file.path)) {
            return await file.readText();
        }
        return null;
    }
    
    async deleteFile(filename: string): Promise<void> {
        const file = this.dataFolder.getFile(filename);
        if (File.exists(file.path)) {
            await file.remove();
        }
    }
    
    async listFiles(): Promise<string[]> {
        const entities = await this.dataFolder.getEntities();
        return entities
            .filter(e => File.exists(e.path))
            .map(e => e.name);
    }
    
    async clearAll(): Promise<void> {
        const entities = await this.dataFolder.getEntities();
        for (const entity of entities) {
            await entity.remove();
        }
    }
}

SQLite #

安装插件 #

bash
ns plugin add @nativescript/sqlite

基本用法 #

typescript
import { SQLite } from '@nativescript/sqlite';

// 创建/打开数据库
const db = await new SQLite('mydb.db');

// 创建表
await db.execSQL(`
    CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        email TEXT UNIQUE,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP
    )
`);

// 插入数据
await db.execSQL(
    'INSERT INTO users (name, email) VALUES (?, ?)',
    ['John', 'john@example.com']
);

// 查询数据
const users = await db.all('SELECT * FROM users');

// 查询单条
const user = await db.get('SELECT * FROM users WHERE id = ?', [1]);

// 更新数据
await db.execSQL(
    'UPDATE users SET name = ? WHERE id = ?',
    ['John Updated', 1]
);

// 删除数据
await db.execSQL('DELETE FROM users WHERE id = ?', [1]);

// 关闭数据库
db.close();

数据库服务 #

typescript
// services/database.service.ts
import { Injectable } from '@angular/core';
import { SQLite } from '@nativescript/sqlite';

@Injectable({
    providedIn: 'root'
})
export class DatabaseService {
    private db: SQLite;
    
    async initialize(): Promise<void> {
        this.db = await new SQLite('app.db');
        await this.createTables();
    }
    
    private async createTables(): Promise<void> {
        await this.db.execSQL(`
            CREATE TABLE IF NOT EXISTS users (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT NOT NULL,
                email TEXT UNIQUE,
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP
            )
        `);
        
        await this.db.execSQL(`
            CREATE TABLE IF NOT EXISTS products (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT NOT NULL,
                price REAL,
                description TEXT
            )
        `);
    }
    
    async query<T>(sql: string, params: any[] = []): Promise<T[]> {
        return this.db.all(sql, params);
    }
    
    async queryOne<T>(sql: string, params: any[] = []): Promise<T> {
        return this.db.get(sql, params);
    }
    
    async execute(sql: string, params: any[] = []): Promise<void> {
        await this.db.execSQL(sql, params);
    }
    
    async transaction(callback: () => Promise<void>): Promise<void> {
        await this.db.transaction(callback);
    }
    
    close(): void {
        if (this.db) {
            this.db.close();
        }
    }
}

Repository 模式 #

typescript
// repositories/user.repository.ts
import { Injectable } from '@angular/core';
import { DatabaseService } from './database.service';

export interface User {
    id?: number;
    name: string;
    email: string;
    createdAt?: Date;
}

@Injectable({
    providedIn: 'root'
})
export class UserRepository {
    constructor(private db: DatabaseService) {}
    
    async getAll(): Promise<User[]> {
        return this.db.query<User>('SELECT * FROM users ORDER BY created_at DESC');
    }
    
    async getById(id: number): Promise<User> {
        return this.db.queryOne<User>('SELECT * FROM users WHERE id = ?', [id]);
    }
    
    async create(user: User): Promise<number> {
        const result = await this.db.execute(
            'INSERT INTO users (name, email) VALUES (?, ?)',
            [user.name, user.email]
        );
        return result.insertId;
    }
    
    async update(user: User): Promise<void> {
        await this.db.execute(
            'UPDATE users SET name = ?, email = ? WHERE id = ?',
            [user.name, user.email, user.id]
        );
    }
    
    async delete(id: number): Promise<void> {
        await this.db.execute('DELETE FROM users WHERE id = ?', [id]);
    }
    
    async search(query: string): Promise<User[]> {
        return this.db.query<User>(
            'SELECT * FROM users WHERE name LIKE ? OR email LIKE ?',
            [`%${query}%`, `%${query}%`]
        );
    }
}

数据同步 #

离线数据同步 #

typescript
// services/sync.service.ts
import { Injectable } from '@angular/core';
import { UserRepository } from '../repositories/user.repository';
import { ApiService } from './api.service';
import { ConnectionType, connectivity } from '@nativescript/core';

@Injectable({
    providedIn: 'root'
})
export class SyncService {
    private isOnline: boolean;
    
    constructor(
        private userRepository: UserRepository,
        private api: ApiService
    ) {
        this.isOnline = connectivity.getConnectionType() !== ConnectionType.none;
        
        connectivity.startMonitoring((type) => {
            this.isOnline = type !== ConnectionType.none;
            if (this.isOnline) {
                this.syncPendingData();
            }
        });
    }
    
    async syncPendingData(): Promise<void> {
        // 同步待上传数据
        const pendingItems = await this.getPendingItems();
        
        for (const item of pendingItems) {
            try {
                await this.syncItem(item);
                await this.markAsSynced(item.id);
            } catch (error) {
                console.error('Sync failed:', error);
            }
        }
    }
    
    private async getPendingItems(): Promise<any[]> {
        // 获取待同步数据
        return [];
    }
    
    private async syncItem(item: any): Promise<void> {
        // 同步单个数据项
    }
    
    private async markAsSynced(id: number): Promise<void> {
        // 标记为已同步
    }
}

缓存策略 #

数据缓存服务 #

typescript
// services/cache.service.ts
import { Injectable } from '@angular/core';
import { ApplicationSettings } from '@nativescript/core';

interface CacheItem<T> {
    data: T;
    timestamp: number;
    ttl: number;
}

@Injectable({
    providedIn: 'root'
})
export class CacheService {
    private static PREFIX = 'cache_';
    
    set<T>(key: string, data: T, ttl: number = 3600000): void {
        const item: CacheItem<T> = {
            data,
            timestamp: Date.now(),
            ttl
        };
        
        ApplicationSettings.setString(
            CacheService.PREFIX + key,
            JSON.stringify(item)
        );
    }
    
    get<T>(key: string): T | null {
        const json = ApplicationSettings.getString(CacheService.PREFIX + key);
        
        if (!json) {
            return null;
        }
        
        const item: CacheItem<T> = JSON.parse(json);
        
        if (Date.now() - item.timestamp > item.ttl) {
            this.remove(key);
            return null;
        }
        
        return item.data;
    }
    
    remove(key: string): void {
        ApplicationSettings.remove(CacheService.PREFIX + key);
    }
    
    clear(): void {
        ApplicationSettings.clear();
    }
    
    has(key: string): boolean {
        return this.get(key) !== null;
    }
}

使用缓存 #

typescript
// services/user.service.ts
import { Injectable } from '@angular/core';
import { CacheService } from './cache.service';
import { ApiService } from './api.service';

@Injectable({
    providedIn: 'root'
})
export class UserService {
    constructor(
        private cache: CacheService,
        private api: ApiService
    ) {}
    
    async getUsers(): Promise<User[]> {
        const cacheKey = 'users_list';
        
        // 尝试从缓存获取
        const cached = this.cache.get<User[]>(cacheKey);
        if (cached) {
            return cached;
        }
        
        // 从 API 获取
        const users = await this.api.get<User[]>('/users');
        
        // 存入缓存
        this.cache.set(cacheKey, users, 300000); // 5分钟
        
        return users;
    }
}

最佳实践 #

存储选择指南 #

text
┌─────────────────────────────────────────────────────────────┐
│                    存储选择                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Application Settings                                       │
│  ✓ 用户偏好设置                                             │
│  ✓ 简单配置数据                                             │
│  ✓ 登录状态                                                 │
│  ✗ 大量数据                                                 │
│  ✗ 复杂结构数据                                             │
│                                                             │
│  文件系统                                                    │
│  ✓ 图片、视频等媒体文件                                     │
│  ✓ 导出数据                                                 │
│  ✓ 日志文件                                                 │
│  ✗ 需要频繁查询的数据                                       │
│                                                             │
│  SQLite                                                     │
│  ✓ 大量结构化数据                                           │
│  ✓ 需要复杂查询                                             │
│  ✓ 离线数据存储                                             │
│  ✗ 简单键值对                                               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

数据安全 #

typescript
import { SecureStorage } from '@nativescript/secure-storage';

const secureStorage = new SecureStorage();

// 安全存储敏感数据
await secureStorage.set({
    key: 'api_token',
    value: 'secret-token'
});

// 读取敏感数据
const token = await secureStorage.get({
    key: 'api_token'
});

下一步 #

现在你已经掌握了本地存储,接下来学习 状态管理,了解如何管理应用状态!

最后更新:2026-03-29