diff --git a/README.md b/README.md index f2d7a966..f4d03add 100644 --- a/README.md +++ b/README.md @@ -108,12 +108,13 @@ See [Configuring App Groups](https://developer.apple.com/documentation/xcode/con #### Customize ```js -import { MMKV } from 'react-native-mmkv' +import { MMKV, MMKVMode } from 'react-native-mmkv' export const storage = new MMKV({ id: `user-${userId}-storage`, path: `${USER_DIRECTORY}/storage`, - encryptionKey: 'hunter2' + encryptionKey: 'hunter2', + mode: 'single-process' }) ``` @@ -124,6 +125,8 @@ The following values can be configured: * `id`: The MMKV instance's ID. If you want to use multiple instances, use different IDs. For example, you can separate the global app's storage and a logged-in user's storage. (required if `path` or `encryptionKey` fields are specified, otherwise defaults to: `'mmkv.default'`) * `path`: The MMKV instance's root path. By default, MMKV stores file inside `$(Documents)/mmkv/`. You can customize MMKV's root directory on MMKV initialization (documentation: [iOS](https://github.com/Tencent/MMKV/wiki/iOS_advance#customize-location) / [Android](https://github.com/Tencent/MMKV/wiki/android_advance#customize-location)) * `encryptionKey`: The MMKV instance's encryption/decryption key. By default, MMKV stores all key-values in plain text on file, relying on iOS's/Android's sandbox to make sure the file is encrypted. Should you worry about information leaking, you can choose to encrypt MMKV. (documentation: [iOS](https://github.com/Tencent/MMKV/wiki/iOS_advance#encryption) / [Android](https://github.com/Tencent/MMKV/wiki/android_advance#encryption)) +* `mode`: *Android Only*: The MMKV mode. It is set to `single-process` by default. You can set its value to `multi-process` to support simultaneous read-write access between processus at the cost of performance. This is useful when you want to share data between your react-native app and native extensions such as widgets. _Notice_: On iOS, this will automatically be set to `multi-process` if you set an AppGroup in the plist configuration (more information on AppGroups [here](https://github.com/mrousavy/react-native-mmkv/tree/master#app-groups)) + ### Set diff --git a/android/src/main/cpp/MmkvHostObject.cpp b/android/src/main/cpp/MmkvHostObject.cpp index 1ffbdc2d..613c64c3 100644 --- a/android/src/main/cpp/MmkvHostObject.cpp +++ b/android/src/main/cpp/MmkvHostObject.cpp @@ -14,14 +14,14 @@ #include MmkvHostObject::MmkvHostObject(const std::string& instanceId, std::string path, - std::string cryptKey) { + std::string cryptKey, MMKVMode mmkvMode) { bool hasEncryptionKey = cryptKey.size() > 0; __android_log_print(ANDROID_LOG_INFO, "RNMMKV", "Creating MMKV instance \"%s\"... (Path: %s, Encrypted: %b)", instanceId.c_str(), path.c_str(), hasEncryptionKey); std::string* pathPtr = path.size() > 0 ? &path : nullptr; std::string* cryptKeyPtr = cryptKey.size() > 0 ? &cryptKey : nullptr; - instance = MMKV::mmkvWithID(instanceId, mmkv::DEFAULT_MMAP_SIZE, MMKV_SINGLE_PROCESS, cryptKeyPtr, + instance = MMKV::mmkvWithID(instanceId, mmkv::DEFAULT_MMAP_SIZE, mmkvMode, cryptKeyPtr, pathPtr); if (instance == nullptr) { diff --git a/android/src/main/cpp/MmkvHostObject.h b/android/src/main/cpp/MmkvHostObject.h index b2c5573a..ff3b55d7 100644 --- a/android/src/main/cpp/MmkvHostObject.h +++ b/android/src/main/cpp/MmkvHostObject.h @@ -15,7 +15,7 @@ using namespace facebook; class JSI_EXPORT MmkvHostObject : public jsi::HostObject { public: - MmkvHostObject(const std::string& instanceId, std::string path, std::string cryptKey); + MmkvHostObject(const std::string& instanceId, std::string path, std::string cryptKey, MMKVMode mmkvMode); public: jsi::Value get(jsi::Runtime&, const jsi::PropNameID& name) override; diff --git a/android/src/main/cpp/cpp-adapter.cpp b/android/src/main/cpp/cpp-adapter.cpp index cf167c9d..63d3f9cf 100644 --- a/android/src/main/cpp/cpp-adapter.cpp +++ b/android/src/main/cpp/cpp-adapter.cpp @@ -13,6 +13,19 @@ std::string getPropertyAsStringOrEmptyFromObject(jsi::Object& object, return value.isString() ? value.asString(runtime).utf8(runtime) : ""; } +const std::string MMKV_MULTI_PROCESS_MODE = "multi-process"; +MMKVMode getPropertyAsMMKVModeFromObject(jsi::Object& object, + const std::string& propertyName, + jsi::Runtime& runtime) { + std::string value = getPropertyAsStringOrEmptyFromObject(object, propertyName, runtime); + if (value == MMKV_MULTI_PROCESS_MODE) { + return MMKV_MULTI_PROCESS; + } + + // Use Single Process as default value + return MMKV_SINGLE_PROCESS; +} + void install(jsi::Runtime& jsiRuntime) { // MMKV.createNewInstance() auto mmkvCreateNewInstance = jsi::Function::createFromHostFunction( @@ -28,8 +41,9 @@ void install(jsi::Runtime& jsiRuntime) { std::string path = getPropertyAsStringOrEmptyFromObject(config, "path", runtime); std::string encryptionKey = getPropertyAsStringOrEmptyFromObject(config, "encryptionKey", runtime); + MMKVMode mode = getPropertyAsMMKVModeFromObject(config, "mode", runtime); - auto instance = std::make_shared(instanceId, path, encryptionKey); + auto instance = std::make_shared(instanceId, path, encryptionKey, mode); return jsi::Object::createFromHostObject(runtime, instance); }); jsiRuntime.global().setProperty(jsiRuntime, "mmkvCreateNewInstance", diff --git a/src/MMKV.ts b/src/MMKV.ts index 973a5e74..1b768d93 100644 --- a/src/MMKV.ts +++ b/src/MMKV.ts @@ -46,6 +46,20 @@ export interface MMKVConfiguration { * ``` */ encryptionKey?: string; + /** + * *Android Only*: The MMKV mode. It is set to `single-process` by default. You can set its value to `multi-process` to support simultaneous read-write access between processus at the cost of performance. + * + * This is useful when you want to share data between your react-native app and native extensions such as widgets. + * + * @example + * ```ts + * const extensionStorage = new MMKV({ id: 'mmkv.default', mode: 'multi-process' }) + * ``` + * + * _Notice_: On iOS, this will automatically be set to `multi-process` if you set an AppGroup in the plist configuration. + * More information on AppGroups [here](https://github.com/mrousavy/react-native-mmkv/tree/master#app-groups) + */ + mode?: 'single-process' | 'multi-process'; } /**