### Clone and Install Demo Dependencies Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Clone the repository and install all project and demo dependencies using pnpm. ```sh git clone https://github.com/aparajita/capacitor-secure-storage.git cd capacitor-secure-storage pnpm install -r ``` -------------------------------- ### Example: User Login Flow Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/SUMMARY.txt A realistic example demonstrating how to store and retrieve user authentication tokens securely. ```typescript // Assume 'token' is obtained after successful login const token = 'your_auth_token_here'; // Store the token securely await secureStorage.set('authToken', token); // Later, retrieve the token to authenticate subsequent requests const storedToken = await secureStorage.get('authToken'); if (storedToken) { // Use storedToken for API calls console.log('Retrieved token:', storedToken); } else { console.log('Token not found, user may need to log in again.'); } ``` -------------------------------- ### User Login Flow Example Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/SecureStorage.md A comprehensive example demonstrating a typical user authentication flow using SecureStorage. It covers initialization, login with secure token storage, and logout with data clearing. ```typescript import { SecureStorage, StorageError, StorageErrorType } from '@aparajita/capacitor-secure-storage' interface AuthState { isAuthenticated: boolean username: string | null token: string | null } class AuthManager { private state: AuthState = { isAuthenticated: false, username: null, token: null, } async initialize(): Promise { // Set app-wide prefix await SecureStorage.setKeyPrefix('myapp_') // Try to restore session const token = await SecureStorage.get('auth-token') const username = await SecureStorage.get('username') if (token && username) { this.state.isAuthenticated = true this.state.token = token as string this.state.username = username as string } } async login(username: string, password: string): Promise { try { // In real app, call your auth API const response = await fetch('/api/login', { method: 'POST', body: JSON.stringify({ username, password }), }) if (!response.ok) throw new Error('Login failed') const { token } = await response.json() // Store credentials securely await SecureStorage.set('username', username) await SecureStorage.set('auth-token', token) this.state.isAuthenticated = true this.state.username = username this.state.token = token } catch (error) { console.error('Login error:', error) throw error } } async logout(): Promise { try { // Clear sensitive data await SecureStorage.clear() this.state.isAuthenticated = false this.state.username = null this.state.token = null } catch (error) { console.error('Logout error:', error) throw error } } getState(): AuthState { return this.state } } // Usage const auth = new AuthManager() await auth.initialize() // Login await auth.login('user@example.com', 'password') console.log(auth.getState()) // { isAuthenticated: true, ... } // Access token const token = auth.getState().token // Logout await auth.logout() ``` -------------------------------- ### Install Capacitor Secure Storage Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Install the plugin using your preferred package manager. ```sh pnpm add @aparajita/capacitor-secure-storage # npm install, yarn add ``` -------------------------------- ### Import SecureStorage Plugin Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/SUMMARY.txt Import the SecureStorage plugin to use its methods. This is a common starting point for most operations. ```typescript import { SecureStoragePlugin } from '@aparajita/capacitor-secure-storage'; const secureStorage = new SecureStoragePlugin(); ``` -------------------------------- ### Store and Retrieve User Data Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/index.md Demonstrates how to save and retrieve structured user data using the `set` and `get` methods. The `set` method accepts any JSON-serializable data, and `get` retrieves it, returning null if the key is not found. ```typescript interface User { id: string email: string name: string } async function saveUser(user: User): Promise { await SecureStorage.set('user', user) } async function getUser(): Promise { const user = await SecureStorage.get('user') return user as User | null } ``` -------------------------------- ### Login Flow Example Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/README.md Demonstrates a typical login flow using Secure Storage to store and retrieve user credentials. It includes initialization, storing tokens, checking login status, and logging out. ```typescript import { SecureStorage, StorageError, StorageErrorType } from '@aparajita/capacitor-secure-storage' // Initialize await SecureStorage.setKeyPrefix('myapp_') // Store credentials after login await SecureStorage.set('user-email', 'user@example.com') await SecureStorage.set('auth-token', 'jwt-token-value') // Check if logged in const token = await SecureStorage.get('auth-token') if (token) { console.log('User is logged in') } // Logout (clear all data) await SecureStorage.clear() ``` -------------------------------- ### Minimal Example: Store, Retrieve, and Remove Data Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/index.md Demonstrates basic usage of storing, retrieving, and removing data using SecureStorage. Includes error handling for retrieval operations. ```typescript import { SecureStorage, StorageError, StorageErrorType } from '@aparajita/capacitor-secure-storage' // Store await SecureStorage.set('api-token', 'secret-token') // Retrieve const token = await SecureStorage.get('api-token') console.log(token) // 'secret-token' // Error handling try { const value = await SecureStorage.get('key') } catch (error) { if (error instanceof StorageError) { console.error(`Error ${error.code}: ${error.message}`) } } // Clean up await SecureStorage.remove('api-token') ``` -------------------------------- ### Basic SecureStorage Usage Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/SecureStorage.md Demonstrates common operations like setting, getting, listing, removing, and clearing data. Includes basic error handling for storage operations. ```typescript import { SecureStorage, StorageError, StorageErrorType } from '@aparajita/capacitor-secure-storage' // Store data await SecureStorage.set('api-token', 'secret-token-value') // Retrieve data const token = await SecureStorage.get('api-token') console.log(token) // "secret-token-value" // List all keys with current prefix const keys = await SecureStorage.keys() // Remove data const existed = await SecureStorage.remove('api-token') // Clear all data with current prefix await SecureStorage.clear() // Handle errors try { await SecureStorage.get('key') } catch (error) { if (error instanceof StorageError) { console.error(`Error: ${error.code} - ${error.message}`) } } ``` -------------------------------- ### Example Date Formats Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Demonstrates valid ISO 8601 datetime formats that can be parsed as dates in storage. These include date only, date with time, and date with time and milliseconds. ```text 2020-08-27 ``` ```text 2020-08-27T13:27:07 ``` ```text 2020-08-27T13:27:07.413Z ``` -------------------------------- ### get() Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/SecureStorage.md Retrieves data associated with a given key. This method is available on all platforms. ```APIDOC ## get() ### Description Retrieves data associated with a given key. ### Method Not specified (assumed to be a method call within the SDK) ### Parameters - **key** (string) - Required - The key of the data to retrieve. ### Response #### Success Response - **value** (any) - The retrieved data. #### Response Example (No example provided in the source) ``` -------------------------------- ### Key Prefix Usage Example Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/configuration.md Demonstrates setting a user-specific key prefix to manage distinct user data. It shows how to store, retrieve keys, and switch prefixes for different users. Note that changing the prefix does not affect previously stored data. ```typescript import { SecureStorage } from '@aparajita/capacitor-secure-storage' // Set custom prefix for user-scoped data await SecureStorage.setKeyPrefix(`user-${userId}_`) // Store user-scoped data (stored as "user-123_authToken") await SecureStorage.set('authToken', 'token-value') // Get all keys for this user (only "user-123_"-prefixed keys) const keys = await SecureStorage.keys() // Change prefix for different user await SecureStorage.setKeyPrefix(`user-456_`) // Can now access different user's data with same key name await SecureStorage.set('authToken', 'different-token') ``` -------------------------------- ### Handling OS-Level Errors Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/errors.md Demonstrates how to catch `osError` exceptions, which indicate platform-specific I/O failures. The example logs the error message for further investigation. ```typescript try { await SecureStorage.set('key', value) } catch (error) { if (error instanceof StorageError) { if (error.code === StorageErrorType.osError) { console.error('OS-level error occurred:', error.message) // Specific handling based on platform and message } } } ``` -------------------------------- ### Handle Null Return Values from get() Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/data-types-usage.md The `get()` method can return null if the key does not exist. Always check for null before attempting to use the retrieved value to prevent runtime errors. ```typescript // ❌ WRONG const value = await SecureStorage.get('key') // Could be null console.log(value.toString()) // Error if null // ✅ CORRECT const value = await SecureStorage.get('key') if (value !== null) { console.log(value.toString()) } ``` -------------------------------- ### Handling Unknown Errors Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/errors.md Provides an example of how to catch `unknownError`, a general catch-all for unexpected storage failures. It suggests logging the error for debugging and reporting. ```typescript try { await SecureStorage.set('key', value) } catch (error) { if (error instanceof StorageError && error.code === StorageErrorType.unknownError) { console.error('Unexpected error occurred:', error.message) // Report to error tracking service } } ``` -------------------------------- ### StorageError Handling Example Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/types.md Demonstrates how to catch and inspect StorageError instances, checking the error code to handle specific failure scenarios like missing keys or corrupted data. ```typescript import { StorageError, StorageErrorType } from '@aparajita/capacitor-secure-storage' try { await SecureStorage.get('my-key') } catch (error) { if (error instanceof StorageError) { if (error.code === StorageErrorType.missingKey) { console.log('No key provided') } else if (error.code === StorageErrorType.invalidData) { console.log('Data is corrupted:', error.message) } } } ``` -------------------------------- ### Usage Example for Keychain Access Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/configuration.md Demonstrates how to set the default keychain access level for sensitive credentials on iOS and how to override it for specific operations. Ensure to check the platform before applying iOS-specific settings. ```typescript import { SecureStorage, KeychainAccess } from '@aparajita/capacitor-secure-storage' import { Capacitor } from '@capacitor/core' if (Capacitor.getPlatform() === 'ios') { // Set default for sensitive credentials await SecureStorage.setDefaultKeychainAccess(KeychainAccess.whenUnlocked) // All future set() calls use this access level await SecureStorage.set('api-token', 'secret-token') // Or override per-operation await SecureStorage.set( 'extremely-sensitive-key', 'value', true, // convertDate false, // sync KeychainAccess.whenPasscodeSetThisDeviceOnly ) } ``` -------------------------------- ### Conditional Configuration for Secure Storage Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Provides an example of setting up Secure Storage with platform-specific configurations. It demonstrates how to apply different settings for iOS, such as synchronization and keychain access, while having no special requirements for Android or Web. ```typescript import { SecureStorage, KeychainAccess } from '@aparajita/capacitor-secure-storage' import { Capacitor } from '@capacitor/core' async function initializeStorage(): Promise { // Common setup await SecureStorage.setKeyPrefix('myapp_') // Platform-specific setup if (Capacitor.getPlatform() === 'ios') { await SecureStorage.setSynchronize(true) await SecureStorage.setDefaultKeychainAccess(KeychainAccess.whenUnlocked) } // No special setup needed for Android or Web } ``` -------------------------------- ### Secure Storage Set Examples for JSON Serialization Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Demonstrates how various data types (string, number, boolean, object, array, date) are stored using SecureStorage.set, showing their JSON-stringified representation. ```typescript // String - stored as-is await SecureStorage.set('str', 'hello') // Stored as: "hello" ``` ```typescript // Number await SecureStorage.set('num', 42) // Stored as: 42 ``` ```typescript // Boolean await SecureStorage.set('bool', true) // Stored as: true ``` ```typescript // Object await SecureStorage.set('obj', { a: 1 }) // Stored as: {"a":1} ``` ```typescript // Array await SecureStorage.set('arr', [1, 2, 3]) // Stored as: [1,2,3] ``` ```typescript // Date (when convertDate=true) await SecureStorage.set('date', new Date('2024-01-15T10:30:00Z')) // Stored as: "2024-01-15T10:30:00.000Z" ``` -------------------------------- ### Get Key Prefix Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/SUMMARY.txt Retrieve the currently configured key prefix using `getKeyPrefix()`. This is useful for debugging or dynamic key management. ```typescript const prefix = await secureStorage.getKeyPrefix(); // prefix will be 'myApp_' ``` -------------------------------- ### iCloud Sync Usage Example Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/configuration.md Demonstrates enabling iCloud sync on iOS and storing data that will sync. It also shows how to check the sync status and disable it. Note that when sync is enabled, `keys()` may return duplicates from both iCloud and local keychains. ```typescript import { SecureStorage } from '@aparajita/capacitor-secure-storage' import { Capacitor } from '@capacitor/core' // Enable iCloud sync on iOS if (Capacitor.getPlatform() === 'ios') { await SecureStorage.setSynchronize(true) } // Store data that will sync to iCloud await SecureStorage.set('user-email', 'user@example.com') // Check current sync status const isSyncing = await SecureStorage.getSynchronize() console.log(`Data sync enabled: ${isSyncing}`) // Disable sync (data remains in storage, just stops syncing) await SecureStorage.setSynchronize(false) ``` -------------------------------- ### Android KeyStore Not Initialized Error Example Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Details the error code and cause for a KeyStore initialization failure on Android, which may indicate system corruption. Device restart or clearing app data is suggested. ```typescript // Error code: osError // Cause: Rare, usually indicates system KeyStore corruption // Solution: Device restart, clear app data ``` -------------------------------- ### Low-Level Storage Operations Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/index.md Provides methods for basic storage operations: setting, getting, and removing raw string values. ```APIDOC ## Low-Level Storage (3 methods) ### `setItem()` #### Description Stores a raw string value. ### Method `setItem(key: string, value: string): Promise` ### Parameters #### Path Parameters - **key** (string) - Required - Non-empty key string #### Request Body - **value** (string) - Required - Raw string to store ### Response #### Success Response (200) - **void** - Operation successful ### `getItem()` #### Description Retrieves a raw string value associated with a key. ### Method `getItem(key: string): Promise` ### Parameters #### Path Parameters - **key** (string) - Required - Non-empty key string ### Response #### Success Response (200) - **string | null** - The stored string value, or null if the key is not found ### `removeItem()` #### Description Deletes the value associated with a key. ### Method `removeItem(key: string): Promise` ### Parameters #### Path Parameters - **key** (string) - Required - Non-empty key string ### Response #### Success Response (200) - **void** - Operation successful ``` -------------------------------- ### Get All Keys from Secure Storage Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/DOCUMENTATION_INDEX.md Retrieves a list of all keys currently stored. Supports an optional synchronization parameter. ```typescript keys(sync?: boolean): Promise ``` -------------------------------- ### Enable Synchronization (iOS) Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/SUMMARY.txt Enable iCloud synchronization for stored items on iOS using `setSynchronize()`. This requires proper iCloud setup in your project. ```typescript await secureStorage.setSynchronize(true); // Items will be synchronized across user's devices via iCloud ``` -------------------------------- ### Best Practices for Storing Large Data with Capacitor Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Provides a TypeScript example demonstrating how to store large data using Capacitor's Filesystem and Secure Storage. It involves writing data to the filesystem and storing a reference in secure storage. ```typescript import { SecureStorage } from '@aparajita/capacitor-secure-storage' import { Filesystem, Directory } from '@capacitor/filesystem' // Store large data in filesystem, reference in storage async function storeLargeData(key: string, largeData: unknown): Promise { // Store actual data on filesystem await Filesystem.writeFile({ path: `secure/${key}.json`, data: JSON.stringify(largeData), directory: Directory.Documents, }) // Store reference in secure storage await SecureStorage.set(key, `secure/${key}.json`) } // Retrieve large data async function retrieveLargeData(key: string): Promise { const path = await SecureStorage.get(key) as string const file = await Filesystem.readFile({ path, directory: Directory.Documents, }) return JSON.parse(file.data as string) } ``` -------------------------------- ### get(key, convertDate?, sync?) Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/SecureStorage.md Retrieves data from secure storage using a specified key. It supports optional parameters to control date conversion and synchronization behavior. Returns the stored data or null if the key does not exist. ```APIDOC ## get(key, convertDate?, sync?) ### Description Retrieves data from storage. It can optionally convert ISO 8601 date strings to Date objects and override global synchronization settings. ### Method `get` ### Parameters #### Path Parameters * None #### Query Parameters * None #### Request Body * None #### Parameters - **key** (`string`) - Required - The key to retrieve data for. Throws `StorageError` if empty. - **convertDate** (`boolean`) - Optional - Defaults to `true`. If `true`, ISO 8601 date strings are parsed into Date objects. - **sync** (`boolean`) - Optional - Overrides global synchronization settings (iOS only). ### Return Type `Promise` - Returns `null` if the key does not exist. - Returns the stored data type: `string`, `number`, `boolean`, object, array, or `Date`. ### Throws `StorageError` - `missingKey` if `key` is null or empty. - `invalidData` if retrieved data is corrupted or not valid JSON. - `osError` if storage system fails. ### Usage Example ```typescript import { SecureStorage } from '@aparajita/capacitor-secure-storage' const username = await SecureStorage.get('username') console.log(username) const profile = await SecureStorage.get('user-profile') if (profile && typeof profile === 'object') { console.log(profile.name) } const lastLogin = await SecureStorage.get('last-login') if (lastLogin instanceof Date) { console.log(lastLogin.toLocaleDateString()) } // Disable date conversion const isoString = await SecureStorage.get('last-login', false) console.log(typeof isoString) // Force read from iCloud (iOS) const value = await SecureStorage.get('key', true, true) ``` ``` -------------------------------- ### Secure Storage Get with Date Conversion Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Shows how to retrieve a date from Secure Storage with `convertDate=true`, resulting in a Date object. The retrieved date is logged in ISO 8601 format. ```typescript const date = new Date('2024-01-15T10:30:00Z') await SecureStorage.set('date', date, true) // convertDate=true // Retrieved as: const retrieved = await SecureStorage.get('date', true) // convertDate=true console.log(retrieved instanceof Date) // true console.log(retrieved.toISOString()) // "2024-01-15T10:30:00.000Z" ``` -------------------------------- ### iOS Keychain Accessibility Levels Example Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Illustrates how different Keychain accessibility levels impact data access based on device lock state. 'whenUnlocked' fails if the device is locked, while 'afterFirstUnlock' succeeds even when locked until the next restart. ```typescript import { SecureStorage, KeychainAccess } from '@aparajita/capacitor-secure-storage' // This will fail if device is locked await SecureStorage.set('key', 'value', true, false, KeychainAccess.whenUnlocked) // Error: osError - keychain access failed // This will succeed even if locked (until next restart) await SecureStorage.set('key', 'value', true, false, KeychainAccess.afterFirstUnlock) // Success - accessible after first unlock ``` -------------------------------- ### iOS Sync Not Available Error Example Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Shows the error code and cause when iCloud Keychain is not enabled on an iOS device. The solution requires user action in device settings. ```typescript // Error code: osError // Cause: iCloud Keychain not enabled on device // Solution: User must enable in Settings > iCloud > Keychain ``` -------------------------------- ### Web Quota Exceeded Error Example Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Shows the error code and message for exceeding web storage quotas. Solutions involve clearing data or requesting persistent storage. ```typescript // Error code: osError // Message: "QuotaExceededError" // Solution: Clear some data or request persistent storage ``` -------------------------------- ### Web localStorage Not Available Error Example Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Explains the error code and cause when localStorage is unavailable on the web, typically due to private browsing or disabled localStorage. Using normal browsing mode is recommended. ```typescript // Error code: osError // Cause: Private browsing, localStorage disabled // Solution: Use normal browsing mode ``` -------------------------------- ### Run Web Demo from Demo Directory Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Navigate to the demo directory and run the web application. ```sh cd demo-pods # or cd demo-spm pnpm dev ``` -------------------------------- ### Run Web Demo with Swift Package Manager Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Run the web demo that uses Swift Package Manager for dependency management. ```sh pnpm demo.spm.browser ``` -------------------------------- ### Run iOS Demo from Demo Directory Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Navigate to the demo directory and run the iOS application. ```sh cd demo-pods # or cd demo-spm pnpm ios ``` -------------------------------- ### Get a String Value Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/SUMMARY.txt Retrieve a string value using its key with the `get()` method. Ensure the key exists before attempting retrieval. ```typescript const value = await secureStorage.get('mykey'); // value will be 'myvalue' or null if the key doesn't exist ``` -------------------------------- ### Run Android Demo from Demo Directory Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Navigate to the demo directory and run the Android application. ```sh cd demo-pods # or cd demo-spm pnpm android ``` -------------------------------- ### Run Web Demo with CocoaPods Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Run the web demo that uses CocoaPods for dependency management. ```sh pnpm demo.pods.browser ``` -------------------------------- ### getSynchronize() Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/SecureStorage.md Gets the current iCloud synchronization status. This method is available on iOS. ```APIDOC ## getSynchronize() ### Description Gets the current iCloud synchronization status. ### Method Not specified (assumed to be a method call within the SDK) ### Parameters None ### Response #### Success Response - **synchronize** (boolean) - The current iCloud sync status. #### Response Example (No example provided in the source) ``` -------------------------------- ### Array Internal Format Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/data-types-usage.md Displays the JSON representation of stored arrays, including homogeneous and heterogeneous examples. ```json [1, 2, 3, 4, 5] ["string", 42, true, {"nested": "object"}, [1, 2, 3]] ``` -------------------------------- ### Get Current Key Prefix with getKeyPrefix Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/index.md Retrieve the currently active key prefix for storage operations. ```typescript getKeyPrefix(): Promise ``` -------------------------------- ### Build the Plugin Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Build the plugin locally before running the demos. This is necessary as the demos reference a local build. ```sh pnpm build ``` -------------------------------- ### Run Android Demo with Swift Package Manager Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Run the Android demo that uses Swift Package Manager for dependency management. ```sh pnpm demo.spm.android ``` -------------------------------- ### Run iOS Demo with CocoaPods Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Run the iOS demo that uses CocoaPods for dependency management. ```sh pnpm demo.pods.ios ``` -------------------------------- ### Get All Keys Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/SUMMARY.txt Retrieve an array of all stored keys using the `keys()` method. This is useful for iterating over stored data. ```typescript const allKeys = await secureStorage.keys(); // allKeys will be an array of strings ``` -------------------------------- ### Get Current Key Prefix Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/DOCUMENTATION_INDEX.md Retrieves the currently configured key prefix used for scoping storage keys. ```typescript getKeyPrefix(): string ``` -------------------------------- ### Run iOS Demo with Swift Package Manager Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Run the iOS demo that uses Swift Package Manager for dependency management. ```sh pnpm demo.spm.ios ``` -------------------------------- ### Get Synchronization Status with getSynchronize (iOS) Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/index.md Retrieve the current synchronization status for storage operations on iOS. This method is iOS-specific. ```typescript getSynchronize(): Promise ``` -------------------------------- ### Run Android Demo with CocoaPods Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/README.md Run the Android demo that uses CocoaPods for dependency management. ```sh pnpm demo.pods.android ``` -------------------------------- ### Initialize Storage with Custom Settings Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/index.md Configure the storage plugin by setting a custom key prefix and platform-specific options like iCloud sync and keychain access for iOS. This is typically done at application startup. ```typescript import { SecureStorage, KeychainAccess } from '@aparajita/capacitor-secure-storage' import { Capacitor } from '@capacitor/core' async function initializeStorage(): Promise { // Set prefix await SecureStorage.setKeyPrefix('myapp_') // iOS configuration if (Capacitor.getPlatform() === 'ios') { await SecureStorage.setSynchronize(true) await SecureStorage.setDefaultKeychainAccess(KeychainAccess.whenUnlocked) } } await initializeStorage() ``` -------------------------------- ### Get Data from Secure Storage Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/DOCUMENTATION_INDEX.md Retrieves data associated with a given key. Supports optional parameters for date conversion and synchronization. ```typescript get(key: string, convertDate?: boolean, sync?: boolean): Promise ``` -------------------------------- ### iOS Keychain Locked Error Example Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Illustrates the error code and message when the iOS Keychain is locked and access is prevented by the KeychainAccess level. ```typescript // Error code: osError // Message: "Keychain query did not complete..." // Cause: Device locked, `KeychainAccess` level prevents access ``` -------------------------------- ### Core Methods Summary Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/README.md This section provides a quick overview of the core methods available in the SecureStorage plugin, including their purpose and return types. ```APIDOC ## Core Methods at a Glance | Method | Purpose | Returns | |--------|---------|---------| | `set(key, data, convertDate?, sync?, access?)` | Store data | `Promise` | | `get(key, convertDate?, sync?)` | Retrieve data | `Promise` | | `remove(key, sync?)` | Delete item | `Promise` | | `clear(sync?)` | Delete all items | `Promise` | | `keys(sync?)` | List all keys | `Promise` | | `setKeyPrefix(prefix)` | Set scope prefix | `Promise` | | `getKeyPrefix()` | Get scope prefix | `Promise` | | `setSynchronize(sync)` | Enable iCloud sync (iOS) | `Promise` | | `getSynchronize()` | Check iCloud sync (iOS) | `Promise` | | `setDefaultKeychainAccess(access)` | Set iOS access level | `Promise` | See [api-reference/index.md](./api-reference/index.md) for complete method list. ``` -------------------------------- ### Get Current Key Prefix Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/configuration.md Retrieves the currently active key prefix. This is useful for understanding how keys are scoped. The default prefix is 'capacitor-storage_'. ```typescript const currentPrefix = await SecureStorage.getKeyPrefix() // Returns: string ``` -------------------------------- ### Configuration Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/DOCUMENTATION_INDEX.md Methods for setting and retrieving the key prefix for scoping storage and managing iCloud synchronization settings. ```APIDOC ## Configuration ### `setKeyPrefix(prefix)` #### Description Sets a prefix to scope storage operations, ensuring data isolation. ### `getKeyPrefix()` #### Description Retrieves the currently configured key prefix. ``` -------------------------------- ### Get Item with Specific Data Type Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/SUMMARY.txt Retrieve stored items using `getItem()`. The plugin automatically deserializes values based on their stored type. ```typescript const settings = await secureStorage.getItem<{ theme: string, notifications: boolean }>('userSettings'); // settings will be { theme: 'dark', notifications: true } or null ``` -------------------------------- ### Get String Item from Secure Storage Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/DOCUMENTATION_INDEX.md A low-level method to retrieve a string value associated with a key. This returns the raw string without type conversion. ```typescript getItem(key: string): Promise ``` -------------------------------- ### Distinguish Key Not Found from Errors Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/errors.md The `get()` method returns `null` and `remove()` returns `false` when a key does not exist, allowing you to differentiate these cases from actual errors. ```typescript const value = await SecureStorage.get('key') // null means not found const existed = await SecureStorage.remove('key') // false means not found ``` -------------------------------- ### Core Methods Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/index.md This section details the core methods available for interacting with the secure storage. These methods allow for storing, retrieving, and removing data, as well as managing keys and synchronization. ```APIDOC ## Core Methods This section details the core methods available for interacting with the secure storage. These methods allow for storing, retrieving, and removing data, as well as managing keys and synchronization. ### `clear(sync?)` **Purpose:** Remove all items with the current prefix. **Platform:** All ### `get(key, convertDate?, sync?)` **Purpose:** Retrieve data by key. **Platform:** All ### `getItem(key)` **Purpose:** Get raw string (low-level). **Platform:** All ### `getKeyPrefix()` **Purpose:** Get current key prefix. **Platform:** All ### `getSynchronize()` **Purpose:** Get iCloud sync status. **Platform:** iOS ### `keys(sync?)` **Purpose:** List all keys with the current prefix. **Platform:** All ### `remove(key, sync?)` **Purpose:** Delete data by key. **Platform:** All ### `removeItem(key)` **Purpose:** Remove value (low-level). **Platform:** All ### `set(key, data, convertDate?, sync?, access?)` **Purpose:** Store data by key. **Platform:** All ### `setDefaultKeychainAccess(access)` **Purpose:** Set iOS keychain access level. **Platform:** iOS ### `setItem(key, value)` **Purpose:** Store raw string (low-level). **Platform:** All ### `setKeyPrefix(prefix)` **Purpose:** Set key prefix for scoping. **Platform:** All ### `setSynchronize(sync)` **Purpose:** Enable iCloud sync. **Platform:** iOS ``` -------------------------------- ### Get iCloud Sync Setting Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/SecureStorage.md Retrieves the current iCloud synchronization status. Returns a promise that resolves to a boolean indicating if sync is enabled. This is only applicable on iOS platforms. ```typescript const isSyncing = await SecureStorage.getSynchronize() console.log(isSyncing) // true or false ``` -------------------------------- ### Store and Retrieve String Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/data-types-usage.md Demonstrates how to store and retrieve string values. Strings are stored as-is and always returned as strings. ```typescript import { SecureStorage } from '@aparajita/capacitor-secure-storage' // Store await SecureStorage.set('username', 'john.doe') // Retrieve const username = await SecureStorage.get('username') console.log(typeof username) // 'string' console.log(username) // 'john.doe' ``` -------------------------------- ### Initialize Secure Storage Configuration Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/configuration.md Configures Secure Storage settings at app startup, including setting a key prefix and configuring iOS-specific options like iCloud sync and default keychain access. This ensures consistent behavior across sessions. ```typescript import { SecureStorage, KeychainAccess } from '@aparajita/capacitor-secure-storage' import { Capacitor } from '@capacitor/core' async function initializeSecureStorage(): Promise { // Set app-wide key prefix await SecureStorage.setKeyPrefix(`app_v${APP_VERSION}_`) // Configure iOS-specific settings if (Capacitor.getPlatform() === 'ios') { await SecureStorage.setSynchronize(true) // Enable iCloud sync await SecureStorage.setDefaultKeychainAccess(KeychainAccess.whenUnlocked) } } // Call during app initialization await initializeSecureStorage() ``` -------------------------------- ### Android SharedPreferences Corruption Error Example Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Presents the error code and cause for corrupted SharedPreferences data on Android. Solutions include removing the corrupted item or restarting the device. ```typescript // Error code: invalidData // Cause: Corrupted data file in SharedPreferences // Solution: Remove corrupted item, device restart ``` -------------------------------- ### Configure Secure Storage Settings Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/README.md Set a key prefix for scoping storage items and enable iCloud synchronization. These settings are configured at runtime. ```typescript await SecureStorage.setKeyPrefix('myapp_') // Enable iCloud sync (iOS only) await SecureStorage.setSynchronize(true) // Set keychain access level (iOS only) await SecureStorage.setDefaultKeychainAccess(KeychainAccess.whenUnlocked) ``` -------------------------------- ### Configure Storage by Environment Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/configuration.md Adjusts Secure Storage configuration based on the build environment (e.g., development vs. production). This allows for different prefixes and iCloud sync settings depending on the deployment target. ```typescript async function configureByEnvironment(): Promise { const isDevelopment = process.env.NODE_ENV === 'development' // Use different prefix for dev vs production const prefix = isDevelopment ? 'dev_' : 'prod_' await SecureStorage.setKeyPrefix(prefix) // Enable iCloud sync only in production (iOS) if (Capacitor.getPlatform() === 'ios') { await SecureStorage.setSynchronize(!isDevelopment) } } ``` -------------------------------- ### Store Various Data Types with SecureStorage Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/SecureStorage.md Illustrates how to store different data types including strings, objects, and Dates. Shows how to override iOS-specific settings like keychain access and iCloud sync. ```typescript import { SecureStorage, KeychainAccess } from '@aparajita/capacitor-secure-storage' // Store string await SecureStorage.set('username', 'john.doe') // Store object await SecureStorage.set('user-profile', { name: 'John Doe', email: 'john@example.com', role: 'admin', }) // Store Date (converted to ISO string) await SecureStorage.set('last-login', new Date()) // Store with iOS keychain override await SecureStorage.set( 'sensitive-key', 'secret-value', true, undefined, KeychainAccess.whenPasscodeSetThisDeviceOnly ) // Store with iCloud sync override (iOS) await SecureStorage.set('sync-key', 'value', true, true) // force sync // Error handling try { await SecureStorage.set('', 'value') // empty key } catch (error) { if (error instanceof StorageError && error.code === StorageErrorType.missingKey) { console.error('Invalid key') } } ``` -------------------------------- ### Get Data from Secure Storage Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/SecureStorage.md Retrieve data associated with a given key. Supports optional date conversion and iCloud sync override on iOS. Returns null if the key does not exist. ```typescript import { SecureStorage, StorageError, StorageErrorType } from '@aparajita/capacitor-secure-storage' // Get string value const username = await SecureStorage.get('username') console.log(username) // 'john.doe' or null // Get object value const profile = await SecureStorage.get('user-profile') if (profile && typeof profile === 'object') { console.log(profile.name) } // Get Date (auto-converted from ISO string) const lastLogin = await SecureStorage.get('last-login') if (lastLogin instanceof Date) { console.log(lastLogin.toLocaleDateString()) } // Check if key exists const value = await SecureStorage.get('key') if (value !== null) { console.log('Key exists:', value) } else { console.log('Key does not exist') } // Disable date conversion const isoString = await SecureStorage.get('last-login', false) console.log(typeof isoString) // 'string' // Handle corrupted data try { const data = await SecureStorage.get('potentially-corrupted-key') } catch (error) { if (error instanceof StorageError && error.code === StorageErrorType.invalidData) { console.error('Data is corrupted') await SecureStorage.remove('potentially-corrupted-key') } } // Read with iCloud sync override (iOS) const value = await SecureStorage.get('key', true, true) // force read from iCloud ``` -------------------------------- ### keys() Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/SecureStorage.md Lists all keys currently stored. This method is available on all platforms. ```APIDOC ## keys() ### Description Lists all keys currently stored. ### Method Not specified (assumed to be a method call within the SDK) ### Parameters None ### Response #### Success Response - **keys** (array of strings) - A list of all stored keys. #### Response Example (No example provided in the source) ``` -------------------------------- ### setKeyPrefix() Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/SecureStorage.md Sets a prefix to scope storage operations. This method is available on all platforms. ```APIDOC ## setKeyPrefix() ### Description Sets a prefix to scope storage operations. ### Method Not specified (assumed to be a method call within the SDK) ### Parameters - **prefix** (string) - Required - The prefix to set. ### Response #### Success Response (No specific success response details provided in the source) #### Response Example (No example provided in the source) ``` -------------------------------- ### Detecting Native vs. Web Platforms Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Illustrates how to use `Capacitor.isNativePlatform()` to differentiate between native (iOS/Android) and web environments. This is helpful for applying different configurations or features. ```typescript const isNative = Capacitor.isNativePlatform() // true on iOS/Android, false on web const isWeb = Capacitor.getPlatform() === 'web' // true on web, false on native ``` -------------------------------- ### setKeyPrefix() Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/SecureStorage.md Sets a prefix for all keys, allowing for data scoping. This is useful for isolating data for different users or application modules. ```APIDOC ## setKeyPrefix(prefix) ### Description Sets the prefix for all keys used in storage operations. This allows for data scoping, ensuring that operations only affect keys with the specified prefix. ### Method `setKeyPrefix(prefix: string): Promise` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **prefix** (string) - Required - The new prefix to be used for all keys. Can be an empty string. ### Request Example ```typescript await SecureStorage.setKeyPrefix('my-app_') // Now all keys are stored as 'my-app_' ``` ### Response #### Success Response (200) `Promise` #### Response Example None (resolves when operation is complete) ``` -------------------------------- ### Get iCloud Synchronization Status Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/configuration.md Retrieves the current status of iCloud Keychain synchronization. Returns `false` on non-iOS platforms. User must manually enable iCloud Keychain on the device for sync to function. ```typescript const isSyncing = await SecureStorage.getSynchronize() // Returns: boolean ``` -------------------------------- ### Storing and Retrieving Dates Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/SUMMARY.txt Demonstrates how to store and retrieve Date objects. The plugin converts Dates to ISO 8601 strings for storage and back upon retrieval. ```typescript const eventDate = new Date(); // Store the Date object await secureStorage.setItem('eventTimestamp', eventDate); // Retrieve the Date object const retrievedTimestamp = await secureStorage.getItem('eventTimestamp'); if (retrievedTimestamp) { console.log('Retrieved timestamp:', retrievedTimestamp.toISOString()); console.log('Date object:', retrievedTimestamp); } else { console.log('Event timestamp not found.'); } ``` -------------------------------- ### Get All Keys with Current Prefix Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/SecureStorage.md Retrieves an array of all keys that match the current key prefix. Returned keys are stripped of the prefix. On iOS, if sync is true, this may return duplicate keys from both iCloud and local keychains. ```typescript import { SecureStorage } from '@aparajita/capacitor-secure-storage' // Get all keys const keys = await SecureStorage.keys() console.log(keys) // ['username', 'api-token', 'user-profile'] // Iterate over all stored values for (const key of keys) { const value = await SecureStorage.get(key) console.log(`${key}: ${value}`) } // Check if specific key exists const keys = await SecureStorage.keys() if (keys.includes('api-token')) { console.log('Token is stored') } // Get keys from iCloud keychain (iOS, may have duplicates) const syncedKeys = await SecureStorage.keys(true) // List keys for current user async function listUserData(userId: string): Promise { await SecureStorage.setKeyPrefix(`user-${userId}_`) return SecureStorage.keys() } ``` -------------------------------- ### Set Key Prefix Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/SUMMARY.txt Configure a prefix for all keys stored by the plugin using `setKeyPrefix()`. This helps in namespacing and avoiding collisions. ```typescript await secureStorage.setKeyPrefix('myApp_'); // All subsequent keys will be prefixed with 'myApp_' ``` -------------------------------- ### Handling Storage Errors Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/SUMMARY.txt Demonstrates how to catch and handle potential errors during storage operations, such as missing keys or OS errors. ```typescript import { StorageError, StorageErrorType } from '@aparajita/capacitor-secure-storage'; try { const value = await secureStorage.get('nonExistentKey'); if (value === null) { // Handle case where key is genuinely not found (expected behavior) console.log('Key not found, as expected.'); } } catch (error) { const storageError = error as StorageError; if (storageError.code === StorageErrorType.MissingKey) { console.error('Error: The requested key does not exist.'); } else if (storageError.code === StorageErrorType.OsError) { console.error('Error: An operating system error occurred:', storageError.message); } else { console.error('An unexpected storage error occurred:', error); } } ``` -------------------------------- ### Import Statements for Capacitor Secure Storage Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/index.md Import the main plugin instance, necessary types, and Capacitor core for platform detection. ```typescript import { SecureStorage } from '@aparajita/capacitor-secure-storage' import { DataType, KeychainAccess, StorageError, StorageErrorType, SecureStoragePlugin, } from '@aparajita/capacitor-secure-storage' import { Capacitor } from '@capacitor/core' ``` -------------------------------- ### Configure Storage for User Scope Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/configuration.md Sets up Secure Storage to isolate data for different users by dynamically setting a user-specific key prefix. This ensures that operations for one user do not affect another's data. ```typescript async function switchUser(userId: string): Promise { // Set prefix to user-specific scope await SecureStorage.setKeyPrefix(`user_${userId}_`) // Now all operations are isolated to this user // Set auth token for this user await SecureStorage.set('authToken', userToken) } ``` -------------------------------- ### Detecting the Current Platform Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/platform-implementation.md Shows how to use Capacitor's `getPlatform()` method to determine if the application is running on iOS, Android, or the Web. This is useful for implementing platform-specific logic. ```typescript import { Capacitor } from '@capacitor/core' const platform = Capacitor.getPlatform() // Returns: 'ios' | 'android' | 'web' if (platform === 'ios') { // iOS-only code await SecureStorage.setSynchronize(true) } ``` -------------------------------- ### Storing and Retrieving Arrays of Objects Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/api-reference/data-types-usage.md Shows how to store and retrieve an array where each element is an object, and how to access properties of these objects. ```typescript const users = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, ] await SecureStorage.set('users', users) const retrieved = await SecureStorage.get('users') console.log(retrieved[0].name) // 'Alice' ``` -------------------------------- ### Low-Level Interface Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/DOCUMENTATION_INDEX.md Basic methods for storing, retrieving, and removing string values directly. ```APIDOC ## Low-Level Interface ### `setItem(key, value)` #### Description Stores a string value associated with a key. ### `getItem(key)` #### Description Retrieves a string value associated with a key. ### `removeItem(key)` #### Description Removes a string item associated with a key. ``` -------------------------------- ### Type Definitions Summary Source: https://github.com/aparajita/capacitor-secure-storage/blob/main/_autodocs/types.md Summarizes the type relationships for SecureStoragePlugin, including its dependencies on DataType, KeychainAccess, StorageError, and StorageErrorType. ```typescript SecureStoragePlugin (interface) ├── Uses: DataType (parameter/return) ├── Uses: KeychainAccess (parameter) ├── Uses: StorageError (throws) └── Uses: StorageErrorType (error classification) DataType = string | number | boolean | Record | unknown[] | Date KeychainAccess = enum with 5 options (iOS only) StorageError extends Error { code: StorageErrorType } StorageErrorType = enum with 4 error codes ```