Capacitor에서 키-값 저장소를 사용할 때 @capacitor/preferences for a handful of small settings, a SQLite-backed key-value store for anything larger or more numerous, and the Keychain or Keystore for secrets. This guide compares the options available on Capacitor 8, shows working code for each, and explains how to move from one to another without losing user data.
__CAPGO_KEEP_0__ 8에서 사용 가능한 옵션을 비교하고, 각 옵션의 작동 예를 보여주며, 사용자 데이터를 잃지 않고 하나에서 다른 것으로 이동하는 방법을 설명합니다.
한눈에 보기
localStorage / IndexedDB |
@capacitor/preferences |
빠른 SQL KeyValueStore |
@capgo/capacitor-data-storage-sqlite |
@capgo/capacitor-native-biometric setData |
|
|---|---|---|---|---|---|
| 백업 | 웹뷰 저장소 | UserDefaults / SharedPreferences (Translated text remains the same as the original, as UserDefaults / SharedPreferences is a literal token and should not be translated.) | SQLite 파일 | SQLite 파일 | 키 체인 / 키 스토어 |
| OS 저장소 정리에도 버틸 수 있습니다 | 보장되지 않습니다 | 네 | 네 | 네 | 네 |
| 값 타입 | 문자열 (localStorage) | 문자열 | JSON 값, 숫자, 불 Uint8Array |
문자열 | 문자열 |
| 좋은 크기 범위 | 작은 | 작은, 몇 KB당 한 값 | __CAPGO_KEEP_0__ | __CAPGO_KEEP_0__ | __CAPGO_KEEP_0__ |
| __CAPGO_KEEP_0__ | No | No | __CAPGO_KEEP_0__ | __CAPGO_KEEP_0__ | __CAPGO_KEEP_0__ |
| __CAPGO_KEEP_0__ | __CAPGO_KEEP_0__ | group option |
store 선택 |
테이블 | 키 이름 |
| 접두사로 검색 | 아니오 | 아니오 | 키 목록 | filtervalues |
아니오 |
| 웹 | 예 | localStorage |
SQLite Wasm (OPFS) | IndexedDB | 비밀을 위한 것이 아닙니다. |
localStorage를 사용하지 않는 이유
localStorage Capacitor 내부에서 WebView 내의 IndexedDB가 작동하지만, 데이터는 WebView에 속하며, 앱의 네이티브 스토리지에 속하지 않습니다. 운영 체제는 저장공간이 부족할 때 WebView의 저장공간을 회수할 수 있으며, Capacitor의 문서에서는 중요한 데이터를 저장할 때 WebView를 사용하지 않는 것을 권장합니다. 앱의 호스트 이름이나 스키마를 변경하는 경우 WebView의 데이터는 앱의 데이터와 분리됩니다. capacitor.config Capacitor 키-값 저장소는 WebView의 원본을 변경하여 다른 빈 저장소로 WebView를 지시합니다.
Cache로 사용할 수 있습니다. 다른 모든 경우에는 원본 데이터와 같은 원본 데이터를 사용하는 네이티브 백업 옵션 중 하나를 사용하세요.
설정 옵션 1: Capacitor 작은 설정의 선호도
@capacitor/preferences Capacitor의 공식 키-값 스토리지 플러그인은 가벼운 키-값 데이터를 위한 것입니다. iOS에서 이 플러그인은 UserDefaultsAndroid에 있습니다. SharedPreferences웹에서 localStorage.
bun add @capacitor/preferences
bunx cap sync
import { Preferences } from '@capacitor/preferences';
interface Settings {
theme: 'light' | 'dark' | 'system';
fontScale: number;
}
const DEFAULTS: Settings = { theme: 'system', fontScale: 1 };
export async function loadSettings(): Promise<Settings> {
const { value } = await Preferences.get({ key: 'settings' });
return value ? { ...DEFAULTS, ...JSON.parse(value) } : DEFAULTS;
}
export async function saveSettings(settings: Settings): Promise<void> {
await Preferences.set({ key: 'settings', value: JSON.stringify(settings) });
}
이용 가능한 항목으로 사용하세요: 테마, 언어, 온보딩 플래그, 마지막으로 선택한 탭, 기능 토글.
사용하지 않는 경우
- 비밀. 값은 앱 샌드박스 내의 평문으로 저장되고, 장치 백업에 포함됩니다.
- 큰 값.
UserDefaults그리고SharedPreferences큰 값을 로드하면 그들의 전체 파일을 메모리에 로드해야 하므로, 큰 JSON 블록은 읽기와 쓰기 모두 느립니다. - 많은 키를 목록화하거나 prefix로 지우려면.
keys()모든 것을 반환하므로, JavaScript에서 필터링합니다.
Preferences.configure({ group: 'MyApp' }) 키가 저장되는 네임스페이스를 변경합니다. 기본 그룹은 CapacitorStorage.
Option 2: SQLite 키-값 저장소
캐시된 API 응답, 초안, 오프라인 큐 또는 수백 개의 항목을 저장하면, SQLite 파일이 더 좋은 곳입니다. 큰 값을 처리하고, 쓰기는 원자적이며, 암호화할 수 있습니다.
빠른 SQL 키-값 저장소
@capgo/capacitor-fast-sql SQLite 연결 위에 있는 KeyValueStore 클래스를 생성합니다. __kv_store 테이블, 값의 유형을 유지하고 하나의 데이터베이스에 여러 이름이 지정된 저장소가 지원됩니다.
bun add @capgo/capacitor-fast-sql
bunx cap sync
빠른 SQL은 iOS 지역 네트워킹 (iOS local networking in)과 같은 두 가지 원시 설정이 필요합니다. Info.plistCapacitor 앱에서 SQLite를 사용하는 방법 Capacitor 앱의 Capacitor 요약:.
import { KeyValueStore } from '@capgo/capacitor-fast-sql';
const cache = await KeyValueStore.open({ database: 'app', store: 'api-cache' });
// Objects, arrays, numbers, booleans, null and Uint8Array are stored as-is
await cache.set('user:42', { id: 42, name: 'Ada', roles: ['admin'] });
await cache.set('lastSync', Date.now());
const user = (await cache.get('user:42')) as { id: number; name: string } | null;
const exists = await cache.has('lastSync');
const allKeys = await cache.keys();
await cache.remove('user:42');
await cache.clear(); // only clears the 'api-cache' store
await cache.close();
API 요약: open(options), fromConnection(connection, store), set, get 두 가지 패턴을 기억하세요: null 여러 저장소, 하나의 데이터베이스. has, remove, clear, keys, close.
Capacitor 옵션
이름 공간을 사용하여 키를 지정할 수 있습니다. 그리고 store context settings, drafts context api-cache iOS와 Android에서 동시에 사용할 수 있으며 독립적으로 삭제할 수 있습니다.
실제 테이블 옆에 키-값이 있습니다. 앱이 이미 관계 데이터를 위해 Fast SQL을 사용 중이라면, 두 번째 연결을 열지 않고 재사용하는 것이 좋습니다:
import { FastSQL, KeyValueStore } from '@capgo/capacitor-fast-sql';
const db = await FastSQL.connect({ database: 'app' });
const drafts = await KeyValueStore.fromConnection(db, 'drafts');
// You own `db`: drafts.close() does not disconnect it
키-값 블록이 특정 조건을 만족할 때(예: 1주일 이상의 초안만), 같은 데이터베이스 내에 프로퍼 테이블로 옮길 수 있습니다.
암호화된 키-값 저장소
KeyValueStore.open 동일한 옵션을 받습니다. FastSQL.connect, encrypted 및 encryptionKey iOS와 Android에서:
import { KeyValueStore } from '@capgo/capacitor-fast-sql';
import { NativeBiometric } from '@capgo/capacitor-native-biometric';
async function getKey(): Promise<string> {
const { isSaved } = await NativeBiometric.isDataSaved({ key: 'kv.key' });
if (isSaved) return (await NativeBiometric.getData({ key: 'kv.key' })).value;
const bytes = crypto.getRandomValues(new Uint8Array(32));
const key = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
await NativeBiometric.setData({ key: 'kv.key', value: key });
return key;
}
const secureStore = await KeyValueStore.open({
database: 'secure-kv',
encrypted: true,
encryptionKey: await getKey(),
});
이것은 native 빌드에서 SQLCipher가 필요합니다. 설정 및 키가 백업 복원 후 잃어버렸을 때 할 일은 __CAPGO_KEEP_0__ Capacitor SQLite 데이터베이스 암호화 방법.
@capgo/capacitor-SQLite 데이터 저장소
@capgo/capacitor-data-storage-sqlite SQLite (원래 Jean Pierre Quéau, 현재 Capgo에서 관리)에서 전용 키-값 플러그인입니다.
bun add @capgo/capacitor-data-storage-sqlite
bunx cap sync
import { CapgoCapacitorDataStorageSqlite as Store } from '@capgo/capacitor-data-storage-sqlite';
await Store.openStore({ database: 'appStore', table: 'settings' });
await Store.set({ key: 'locale', value: 'fr' });
await Store.set({ key: 'profile', value: JSON.stringify({ name: 'Ada' }) });
const { value } = await Store.get({ key: 'locale' });
const { result: hasProfile } = await Store.iskey({ key: 'profile' });
const { keys } = await Store.keys();
// Switch table inside the same store
await Store.setTable({ table: 'drafts' });
const { values } = await Store.filtervalues({ filter: 'note%' }); // values whose key starts with "note"
await Store.remove({ key: 'note-1' });
await Store.clear(); // clears the current table
filtervalues 키 (prefix, suffix, contains)에서 패턴을 적용합니다. LIKE SQL 패턴을 키에 적용합니다.note% prefix, suffix, contains %note SQL 문자열에 패턴을 삽입하므로, 사용자 입력이 아닌 제어 가능한 필터만 전달하세요.
IndexedDB를 사용하여 웹에서 작동합니다. localforage분리적으로 설치해야 하는
bun add localforage
암호화에 대한 정보: openStore({ encrypted: true, mode: 'secret' }) SQLCipher를 사용하여 capacitor.config under plugins.CapgoCapacitorDataStorageSqlite.encryptionSecret패스워드는 앱 번들 내에 포함되어 있으며, 패스워드를 설정하지 않으면 기본값으로 돌아갑니다.
빠른 SQL 키-값 저장소 또는 데이터 저장소-sqlite?
- 선택 빠른 SQL
KeyValueStore만약에 타입이 지정된 값이나 수동 JSON이 아닌 값, 바이너리 값, 런타임 암호화 키, 또는 이미 테이블과 필터 기능, JSON 수출 및 임포트, 또는 Electron 지원을 사용하는 경우. - 선택 데이터 저장소 - SQLite 만약에 테이블과 필터 기능, JSON 수출 및 임포트, 또는 Electron 지원이 필요하다면.
옵션 3: 비밀 키를 위한 키 체인과 키 스토어
인증 토큰, 리프레시 토큰, API 키 및 데이터베이스 암호화 키는 플랫폼 보안 저장소에 속해야 합니다. @capgo/capacitor-native-biometric (8.6.0 이상) iOS 키 체인과 Android 키 스토어 위에 일반 키-값 API를 노출합니다.
bun add @capgo/capacitor-native-biometric
bunx cap sync
import { AccessControl, NativeBiometric } from '@capgo/capacitor-native-biometric';
// Silent read and write
await NativeBiometric.setData({ key: 'session.refreshToken', value: token });
const { value: refreshToken } = await NativeBiometric.getData({ key: 'session.refreshToken' });
// Require Face ID / Touch ID / fingerprint to read
await NativeBiometric.setData({
key: 'wallet.pin',
value: pin,
accessControl: AccessControl.BIOMETRY_ANY,
});
const { value: secretPin } = await NativeBiometric.getSecureData({
key: 'wallet.pin',
reason: 'Confirm it is you',
});
await NativeBiometric.deleteData({ key: 'session.refreshToken' });
값을 작게 유지하세요. Android 키 스토어 기반 암호화가 약 8 KB당 가장 잘 작동하는 것으로 문서화되었습니다. 많은 데이터를 보호해야 한다면, 하나의 랜덤 키를 여기에 저장하고 SQLite 데이터베이스를 암호화하세요. offline 토큰 저장소 토큰 처리에 더 깊게 다룹니다.
iOS 앱이 삭제된 후에도 Keychain 항목이 살아남을 수 있습니다. 앱을 처음 설치하고 첫 번째 런칭 후에, 앱이 깨끗한 슬레이트를 기대하는 경우, 설치 전의陈腐한 비밀을 지우십시오 (설정에서 '처음 실행 완료' 플래그를 저장하고, 삭제 시 플래그가 없으면 Keychain 항목을 지우십시오).
선택: 결정 목록
- 비밀인가요? 토큰, 비밀번호, PIN, 키. Keychain 또는 Keystore 저장소를 사용하십시오.
- 몇 개의 작은 설정인가요? 설정(Preferences)을 사용하십시오.
- 많은 항목, 큰 JSON, 이진 데이터, 또는 그룹별로 삭제하고 싶은 캐시가 있나요? SQLite 키-값 저장소를 사용하십시오.
- 필터링, 정렬, 또는 조인할 필요가 있나요? 키-값 데이터가 아니에요. 테이블을 생성하십시오, SQLite 가이드를 참조하십시오, 또는 타입화된 레이어인 Kysely.
기존 데이터를 저장소 간에 이동하는 방법
SQLite 저장소로 이동하는 경우 localStorage SQLite 저장소로 이동하는 경우 Preferences 또는 Preferences에서 Preferences를 SQLite 저장소로 이동하는 경우는 한 번만 앱이 시작할 때 데이터를 읽기 전에 수행하고 기록합니다.
import { Preferences } from '@capacitor/preferences';
import { KeyValueStore, type KeyValueValue } from '@capgo/capacitor-fast-sql';
export async function migrateToSqliteStore(): Promise<KeyValueStore> {
const kv = await KeyValueStore.open({ database: 'app', store: 'settings' });
if (await kv.has('__migrated_v1')) return kv;
const { keys } = await Preferences.keys();
for (const key of keys) {
const { value } = await Preferences.get({ key });
if (value === null) continue;
let parsed: KeyValueValue = value;
try {
parsed = JSON.parse(value) as KeyValueValue;
} catch {
// keep plain strings as strings
}
await kv.set(key, parsed);
}
// Also copy from localStorage if older versions used it
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key && !(await kv.has(key))) {
await kv.set(key, localStorage.getItem(key));
}
}
await kv.set('__migrated_v1', true);
// Remove the old copies only after a release or two, once you are confident
return kv;
}
기존 저장소에서 보안 저장소로 복사된 즉시 비밀번호를 제거하십시오. Preferences에 토큰이 남아 있는 경우 원래 노출을 유지합니다.
이 code은 자바스크립트에서 실행되므로 code을 포함하여 __CAPGO_KEEP_1__을 포함하여 배포할 수 있습니다. Capgo live updateSQLite 플러그인은 자체적으로 네이티브이므로 플러그인을 먼저 배포한 후 code을 배포해야 합니다.
Troubleshooting
Preferences 값은 null 웹에서 업데이트된 후 원본이 변경되었습니다 (포트, 호스트 이름 또는 스키마) localStorage 다른 빈 저장소입니다.
빠른 SQL KeyValueStore.open iOS에서 예외를 발생시킵니다. 지역 HTTP 채널이 차단되었습니다. 추가 NSAllowsLocalNetworking to Info.plist 재빌드 네이티브 앱
get string이 반환되었습니다. 데이터 스토리지 sqlite에서 object를 기대했었습니다. 그것은 문자열만 저장합니다. JSON.parse 값을 저장합니다.
새로운 전화기에 백업을 복원한 후 비밀을 찾을 수 없습니다. 신뢰할 수 있는 저장소는 다시 로그인하여 인증서를 다시 획득할 수 있는 인증서의 캐시로 처리해야 합니다.
iOS에서 다시 설치한 후 설정이 사라집니다. 그러나 토큰은 여전히 남아 있습니다. 기대: 앱과 함께 삭제되는 설정은 Preferences 이고, Keychain 항목은 남아 있을 수 있습니다. 위의 첫 번째 실행 플래그 패턴을 사용하세요.
Summary
- 설정: 작은, 비_sensitive 설정.
- SQLite 키-값 저장소 (Fast SQL
KeyValueStore또는@capgo/capacitor-data-storage-sqlite): 많은 또는 큰 값, 캐시, 초안, 암호화가 가능합니다. - Keychain 또는 Keystore (
@capgo/capacitor-native-biometricsetData): 비밀과 암호화 키.
플러그인 참조: Fast SQL 문서, 데이터 저장소 - SQLite 문서, 그리고 자연어 생체 인증 플러그인 페이지.