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