react-native-mmkv 2.10.1 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MMKV/LICENSE.TXT +193 -0
- package/MMKV/README.md +290 -0
- package/README.md +9 -1
- package/android/build.gradle +7 -0
- package/android/src/main/AndroidManifest.xml +1 -1
- package/android/src/main/cpp/MmkvHostObject.cpp +191 -204
- package/android/src/main/cpp/MmkvHostObject.h +2 -2
- package/android/src/main/cpp/cpp-adapter.cpp +56 -49
- package/cpp/TypedArray.cpp +69 -76
- package/cpp/TypedArray.h +66 -91
- package/img/banner-dark.png +0 -0
- package/img/banner-light.png +0 -0
- package/ios/JSIUtils.h +27 -39
- package/ios/JSIUtils.mm +110 -138
- package/ios/MmkvHostObject.h +2 -2
- package/ios/MmkvHostObject.mm +188 -205
- package/ios/MmkvModule.mm +62 -52
- package/lib/commonjs/hooks.js +1 -3
- package/lib/commonjs/hooks.js.map +1 -1
- package/lib/module/hooks.js +1 -3
- package/lib/module/hooks.js.map +1 -1
- package/lib/typescript/hooks.d.ts.map +1 -1
- package/package.json +13 -3
- package/src/hooks.ts +1 -3
package/ios/MmkvHostObject.mm
CHANGED
|
@@ -6,25 +6,24 @@
|
|
|
6
6
|
// Copyright © 2021 Facebook. All rights reserved.
|
|
7
7
|
//
|
|
8
8
|
|
|
9
|
-
#import <Foundation/Foundation.h>
|
|
10
9
|
#import "MmkvHostObject.h"
|
|
11
|
-
#import "JSIUtils.h"
|
|
12
10
|
#import "../cpp/TypedArray.h"
|
|
11
|
+
#import "JSIUtils.h"
|
|
12
|
+
#import <Foundation/Foundation.h>
|
|
13
13
|
#import <vector>
|
|
14
14
|
|
|
15
|
-
MmkvHostObject::MmkvHostObject(NSString* instanceId, NSString* path, NSString* cryptKey)
|
|
16
|
-
{
|
|
15
|
+
MmkvHostObject::MmkvHostObject(NSString* instanceId, NSString* path, NSString* cryptKey) {
|
|
17
16
|
NSData* cryptData = cryptKey == nil ? nil : [cryptKey dataUsingEncoding:NSUTF8StringEncoding];
|
|
18
|
-
|
|
17
|
+
|
|
19
18
|
// Get appGroup value from info.plist using key "AppGroup"
|
|
20
|
-
NSString
|
|
19
|
+
NSString* appGroup = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppGroup"];
|
|
21
20
|
if (appGroup == nil) {
|
|
22
|
-
|
|
21
|
+
instance = [MMKV mmkvWithID:instanceId cryptKey:cryptData rootPath:path];
|
|
23
22
|
} else {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
if (path != nil) {
|
|
24
|
+
NSLog(@"Warning: `path` is ignored when `appGroup` is set!");
|
|
25
|
+
}
|
|
26
|
+
instance = [MMKV mmkvWithID:instanceId cryptKey:cryptData mode:MMKVMultiProcess];
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
if (instance == nil) {
|
|
@@ -35,7 +34,8 @@ MmkvHostObject::MmkvHostObject(NSString* instanceId, NSString* path, NSString* c
|
|
|
35
34
|
|
|
36
35
|
// Check if encryptionKey is invalid
|
|
37
36
|
if (cryptData != nil && [cryptData length] > 16) {
|
|
38
|
-
throw std::runtime_error(
|
|
37
|
+
throw std::runtime_error(
|
|
38
|
+
"Failed to create MMKV instance! `encryptionKey` cannot be longer than 16 bytes!");
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
if (appGroup == nil) {
|
|
@@ -43,7 +43,8 @@ MmkvHostObject::MmkvHostObject(NSString* instanceId, NSString* path, NSString* c
|
|
|
43
43
|
NSFileManager* fileManager = [[NSFileManager alloc] init];
|
|
44
44
|
bool pathExists = [fileManager fileExistsAtPath:path isDirectory:nil];
|
|
45
45
|
if (!pathExists) {
|
|
46
|
-
throw std::runtime_error(
|
|
46
|
+
throw std::runtime_error(
|
|
47
|
+
"Failed to create MMKV instance! The given Storage Path does not exist!");
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -51,8 +52,7 @@ MmkvHostObject::MmkvHostObject(NSString* instanceId, NSString* path, NSString* c
|
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
std::vector<jsi::PropNameID> MmkvHostObject::getPropertyNames(jsi::Runtime& rt)
|
|
55
|
-
{
|
|
55
|
+
std::vector<jsi::PropNameID> MmkvHostObject::getPropertyNames(jsi::Runtime& rt) {
|
|
56
56
|
std::vector<jsi::PropNameID> result;
|
|
57
57
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("set")));
|
|
58
58
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("getBoolean")));
|
|
@@ -67,245 +67,228 @@ std::vector<jsi::PropNameID> MmkvHostObject::getPropertyNames(jsi::Runtime& rt)
|
|
|
67
67
|
return result;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& propNameId)
|
|
71
|
-
{
|
|
70
|
+
jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& propNameId) {
|
|
72
71
|
auto propName = propNameId.utf8(runtime);
|
|
73
72
|
auto funcName = "MMKV." + propName;
|
|
74
73
|
|
|
75
74
|
if (propName == "set") {
|
|
76
75
|
// MMKV.set(key: string, value: string | number | bool)
|
|
77
|
-
return jsi::Function::createFromHostFunction(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
76
|
+
return jsi::Function::createFromHostFunction(
|
|
77
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
78
|
+
2, // key, value
|
|
79
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
80
|
+
size_t count) -> jsi::Value {
|
|
81
|
+
if (!arguments[0].isString()) {
|
|
82
|
+
throw jsi::JSError(runtime,
|
|
83
|
+
"MMKV::set: First argument ('key') has to be of type string!");
|
|
84
|
+
}
|
|
87
85
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
86
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
87
|
+
if (arguments[1].isBool()) {
|
|
88
|
+
// Set as boolean
|
|
89
|
+
[instance setBool:arguments[1].getBool() forKey:keyName];
|
|
90
|
+
} else if (arguments[1].isNumber()) {
|
|
91
|
+
// Set as number (double in JS)
|
|
92
|
+
[instance setDouble:arguments[1].getNumber() forKey:keyName];
|
|
93
|
+
} else if (arguments[1].isString()) {
|
|
94
|
+
// Set as UTF-8 string
|
|
95
|
+
auto stringValue = convertJSIStringToNSString(runtime, arguments[1].getString(runtime));
|
|
96
|
+
[instance setString:stringValue forKey:keyName];
|
|
97
|
+
} else if (arguments[1].isObject()) {
|
|
98
|
+
// object
|
|
99
|
+
auto object = arguments[1].asObject(runtime);
|
|
100
|
+
if (isTypedArray(runtime, object)) {
|
|
101
|
+
// Uint8Array
|
|
102
|
+
auto typedArray = getTypedArray(runtime, object);
|
|
103
|
+
auto bufferValue = typedArray.getBuffer(runtime);
|
|
104
|
+
auto data = [[NSData alloc] initWithBytes:bufferValue.data(runtime)
|
|
105
|
+
length:bufferValue.length(runtime)];
|
|
106
|
+
[instance setData:data forKey:keyName];
|
|
107
|
+
} else {
|
|
108
|
+
// unknown object
|
|
109
|
+
throw jsi::JSError(
|
|
110
|
+
runtime, "MMKV::set: 'value' argument is an object, but not of type Uint8Array!");
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
// Invalid type
|
|
114
|
+
throw jsi::JSError(
|
|
115
|
+
runtime, "Second argument ('value') has to be of type bool, number or string!");
|
|
116
|
+
}
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
return jsi::Value::undefined();
|
|
119
|
+
});
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
if (propName == "getBoolean") {
|
|
123
123
|
// MMKV.getBoolean(key: string)
|
|
124
|
-
return jsi::Function::createFromHostFunction(
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
133
|
-
}
|
|
124
|
+
return jsi::Function::createFromHostFunction(
|
|
125
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
126
|
+
1, // key
|
|
127
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
128
|
+
size_t count) -> jsi::Value {
|
|
129
|
+
if (!arguments[0].isString()) {
|
|
130
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
131
|
+
}
|
|
134
132
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
133
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
134
|
+
BOOL hasValue;
|
|
135
|
+
auto value = [instance getBoolForKey:keyName defaultValue:false hasValue:&hasValue];
|
|
136
|
+
if (hasValue) {
|
|
137
|
+
return jsi::Value(value == true);
|
|
138
|
+
} else {
|
|
139
|
+
return jsi::Value::undefined();
|
|
140
|
+
}
|
|
141
|
+
});
|
|
144
142
|
}
|
|
145
143
|
|
|
146
144
|
if (propName == "getString") {
|
|
147
145
|
// MMKV.getString(key: string)
|
|
148
|
-
return jsi::Function::createFromHostFunction(
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
157
|
-
}
|
|
146
|
+
return jsi::Function::createFromHostFunction(
|
|
147
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
148
|
+
1, // key
|
|
149
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
150
|
+
size_t count) -> jsi::Value {
|
|
151
|
+
if (!arguments[0].isString()) {
|
|
152
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
153
|
+
}
|
|
158
154
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
155
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
156
|
+
auto value = [instance getStringForKey:keyName];
|
|
157
|
+
if (value != nil) {
|
|
158
|
+
return convertNSStringToJSIString(runtime, value);
|
|
159
|
+
} else {
|
|
160
|
+
return jsi::Value::undefined();
|
|
161
|
+
}
|
|
162
|
+
});
|
|
167
163
|
}
|
|
168
164
|
|
|
169
165
|
if (propName == "getNumber") {
|
|
170
166
|
// MMKV.getNumber(key: string)
|
|
171
|
-
return jsi::Function::createFromHostFunction(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
180
|
-
}
|
|
167
|
+
return jsi::Function::createFromHostFunction(
|
|
168
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
169
|
+
1, // key
|
|
170
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
171
|
+
size_t count) -> jsi::Value {
|
|
172
|
+
if (!arguments[0].isString()) {
|
|
173
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
174
|
+
}
|
|
181
175
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
176
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
177
|
+
BOOL hasValue;
|
|
178
|
+
auto value = [instance getDoubleForKey:keyName defaultValue:0.0 hasValue:&hasValue];
|
|
179
|
+
if (hasValue) {
|
|
180
|
+
return jsi::Value(value);
|
|
181
|
+
} else {
|
|
182
|
+
return jsi::Value::undefined();
|
|
183
|
+
}
|
|
184
|
+
});
|
|
191
185
|
}
|
|
192
186
|
|
|
193
187
|
if (propName == "getBuffer") {
|
|
194
188
|
// MMKV.getBuffer(key: string)
|
|
195
|
-
return jsi::Function::createFromHostFunction(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
204
|
-
}
|
|
189
|
+
return jsi::Function::createFromHostFunction(
|
|
190
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
191
|
+
1, // key
|
|
192
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
193
|
+
size_t count) -> jsi::Value {
|
|
194
|
+
if (!arguments[0].isString()) {
|
|
195
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
196
|
+
}
|
|
205
197
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
198
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
199
|
+
auto data = [instance getDataForKey:keyName];
|
|
200
|
+
if (data != nil) {
|
|
201
|
+
TypedArray<TypedArrayKind::Uint8Array> array(runtime, data.length);
|
|
202
|
+
auto charArray = static_cast<const unsigned char*>([data bytes]);
|
|
203
|
+
std::vector<unsigned char> vector(data.length);
|
|
204
|
+
vector.assign(charArray, charArray + data.length);
|
|
205
|
+
array.update(runtime, vector);
|
|
206
|
+
return array;
|
|
207
|
+
} else {
|
|
208
|
+
return jsi::Value::undefined();
|
|
209
|
+
}
|
|
210
|
+
});
|
|
219
211
|
}
|
|
220
212
|
|
|
221
213
|
if (propName == "contains") {
|
|
222
214
|
// MMKV.contains(key: string)
|
|
223
|
-
return jsi::Function::createFromHostFunction(
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
232
|
-
}
|
|
215
|
+
return jsi::Function::createFromHostFunction(
|
|
216
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
217
|
+
1, // key
|
|
218
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
219
|
+
size_t count) -> jsi::Value {
|
|
220
|
+
if (!arguments[0].isString()) {
|
|
221
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
222
|
+
}
|
|
233
223
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
224
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
225
|
+
bool containsKey = [instance containsKey:keyName];
|
|
226
|
+
return jsi::Value(containsKey);
|
|
227
|
+
});
|
|
238
228
|
}
|
|
239
229
|
|
|
240
230
|
if (propName == "delete") {
|
|
241
231
|
// MMKV.delete(key: string)
|
|
242
|
-
return jsi::Function::createFromHostFunction(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
251
|
-
}
|
|
232
|
+
return jsi::Function::createFromHostFunction(
|
|
233
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
234
|
+
1, // key
|
|
235
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
236
|
+
size_t count) -> jsi::Value {
|
|
237
|
+
if (!arguments[0].isString()) {
|
|
238
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
239
|
+
}
|
|
252
240
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
241
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
242
|
+
[instance removeValueForKey:keyName];
|
|
243
|
+
return jsi::Value::undefined();
|
|
244
|
+
});
|
|
257
245
|
}
|
|
258
246
|
|
|
259
247
|
if (propName == "getAllKeys") {
|
|
260
248
|
// MMKV.getAllKeys()
|
|
261
|
-
return jsi::Function::createFromHostFunction(
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
auto keys = [instance allKeys];
|
|
269
|
-
return convertNSArrayToJSIArray(runtime, keys);
|
|
270
|
-
});
|
|
249
|
+
return jsi::Function::createFromHostFunction(
|
|
250
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName), 0,
|
|
251
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
252
|
+
size_t count) -> jsi::Value {
|
|
253
|
+
auto keys = [instance allKeys];
|
|
254
|
+
return convertNSArrayToJSIArray(runtime, keys);
|
|
255
|
+
});
|
|
271
256
|
}
|
|
272
257
|
|
|
273
258
|
if (propName == "clearAll") {
|
|
274
259
|
// MMKV.clearAll()
|
|
275
|
-
return jsi::Function::createFromHostFunction(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
[instance clearAll];
|
|
283
|
-
return jsi::Value::undefined();
|
|
284
|
-
});
|
|
260
|
+
return jsi::Function::createFromHostFunction(
|
|
261
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName), 0,
|
|
262
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
263
|
+
size_t count) -> jsi::Value {
|
|
264
|
+
[instance clearAll];
|
|
265
|
+
return jsi::Value::undefined();
|
|
266
|
+
});
|
|
285
267
|
}
|
|
286
268
|
|
|
287
269
|
if (propName == "recrypt") {
|
|
288
270
|
// MMKV.recrypt(encryptionKey)
|
|
289
|
-
return jsi::Function::createFromHostFunction(
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
271
|
+
return jsi::Function::createFromHostFunction(
|
|
272
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
273
|
+
1, // encryptionKey
|
|
274
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
275
|
+
size_t count) -> jsi::Value {
|
|
276
|
+
if (arguments[0].isUndefined()) {
|
|
277
|
+
// reset encryption key to "no encryption"
|
|
278
|
+
[instance reKey:nil];
|
|
279
|
+
} else if (arguments[0].isString()) {
|
|
280
|
+
// reKey(..) with new encryption-key
|
|
281
|
+
NSString* encryptionKey =
|
|
282
|
+
convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
283
|
+
NSData* encryptionKeyBytes = [encryptionKey dataUsingEncoding:NSUTF8StringEncoding];
|
|
284
|
+
[instance reKey:encryptionKeyBytes];
|
|
285
|
+
} else {
|
|
286
|
+
throw jsi::JSError(
|
|
287
|
+
runtime,
|
|
288
|
+
"First argument ('encryptionKey') has to be of type string (or undefined)!");
|
|
289
|
+
}
|
|
290
|
+
return jsi::Value::undefined();
|
|
291
|
+
});
|
|
309
292
|
}
|
|
310
293
|
|
|
311
294
|
return jsi::Value::undefined();
|
package/ios/MmkvModule.mm
CHANGED
|
@@ -5,81 +5,91 @@
|
|
|
5
5
|
#import <React/RCTUtils.h>
|
|
6
6
|
#import <jsi/jsi.h>
|
|
7
7
|
|
|
8
|
-
#import <MMKV/MMKV.h>
|
|
9
|
-
#import "MmkvHostObject.h"
|
|
10
8
|
#import "../cpp/TypedArray.h"
|
|
9
|
+
#import "MmkvHostObject.h"
|
|
10
|
+
#import <MMKV/MMKV.h>
|
|
11
11
|
|
|
12
12
|
using namespace facebook;
|
|
13
13
|
|
|
14
14
|
@implementation MmkvModule
|
|
15
15
|
|
|
16
|
+
@synthesize bridge=_bridge;
|
|
17
|
+
|
|
16
18
|
RCT_EXPORT_MODULE(MMKV)
|
|
17
19
|
|
|
20
|
+
- (void)setBridge:(RCTBridge *)bridge {
|
|
21
|
+
_bridge = bridge;
|
|
22
|
+
}
|
|
23
|
+
|
|
18
24
|
+ (NSString*)getPropertyAsStringOrNilFromObject:(jsi::Object&)object
|
|
19
25
|
propertyName:(std::string)propertyName
|
|
20
|
-
runtime:(jsi::Runtime&)runtime
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return string.length() > 0 ? [NSString stringWithUTF8String:string.c_str()] : nil;
|
|
26
|
+
runtime:(jsi::Runtime&)runtime {
|
|
27
|
+
jsi::Value value = object.getProperty(runtime, propertyName.c_str());
|
|
28
|
+
std::string string = value.isString() ? value.asString(runtime).utf8(runtime) : "";
|
|
29
|
+
return string.length() > 0 ? [NSString stringWithUTF8String:string.c_str()] : nil;
|
|
25
30
|
}
|
|
26
31
|
|
|
27
|
-
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install:(nullable NSString*)storageDirectory)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install : (nullable NSString*)storageDirectory) {
|
|
33
|
+
NSLog(@"Installing global.mmkvCreateNewInstance...");
|
|
34
|
+
RCTCxxBridge* cxxBridge = (RCTCxxBridge*)_bridge;
|
|
35
|
+
if (cxxBridge == nil) {
|
|
36
|
+
return @false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
using namespace facebook;
|
|
40
|
+
|
|
41
|
+
auto jsiRuntime = (jsi::Runtime*)cxxBridge.runtime;
|
|
42
|
+
if (jsiRuntime == nil) {
|
|
43
|
+
return @false;
|
|
44
|
+
}
|
|
45
|
+
auto& runtime = *jsiRuntime;
|
|
46
|
+
|
|
47
|
+
RCTUnsafeExecuteOnMainQueueSync(^{
|
|
48
|
+
// Get appGroup value from info.plist using key "AppGroup"
|
|
49
|
+
NSString* appGroup = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppGroup"];
|
|
50
|
+
if (appGroup == nil) {
|
|
51
|
+
[MMKV initializeMMKV:storageDirectory];
|
|
52
|
+
} else {
|
|
53
|
+
NSString* groupDir = [[NSFileManager defaultManager]
|
|
54
|
+
containerURLForSecurityApplicationGroupIdentifier:appGroup]
|
|
55
|
+
.path;
|
|
56
|
+
[MMKV initializeMMKV:nil groupDir:groupDir logLevel:MMKVLogNone];
|
|
34
57
|
}
|
|
58
|
+
});
|
|
35
59
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
auto& runtime = *jsiRuntime;
|
|
43
|
-
|
|
44
|
-
RCTUnsafeExecuteOnMainQueueSync(^{
|
|
45
|
-
// Get appGroup value from info.plist using key "AppGroup"
|
|
46
|
-
NSString *appGroup = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppGroup"];
|
|
47
|
-
if (appGroup == nil) {
|
|
48
|
-
[MMKV initializeMMKV:storageDirectory];
|
|
49
|
-
} else {
|
|
50
|
-
NSString *groupDir = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:appGroup].path;
|
|
51
|
-
[MMKV initializeMMKV:nil groupDir:groupDir logLevel:MMKVLogNone];
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
// MMKV.createNewInstance()
|
|
56
|
-
auto mmkvCreateNewInstance = jsi::Function::createFromHostFunction(runtime,
|
|
57
|
-
jsi::PropNameID::forAscii(runtime, "mmkvCreateNewInstance"),
|
|
58
|
-
1,
|
|
59
|
-
[](jsi::Runtime& runtime,
|
|
60
|
-
const jsi::Value& thisValue,
|
|
61
|
-
const jsi::Value* arguments,
|
|
62
|
-
size_t count) -> jsi::Value {
|
|
60
|
+
// MMKV.createNewInstance()
|
|
61
|
+
auto mmkvCreateNewInstance = jsi::Function::createFromHostFunction(
|
|
62
|
+
runtime, jsi::PropNameID::forAscii(runtime, "mmkvCreateNewInstance"), 1,
|
|
63
|
+
[](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
64
|
+
size_t count) -> jsi::Value {
|
|
63
65
|
if (count != 1) {
|
|
64
|
-
|
|
66
|
+
throw jsi::JSError(runtime, "MMKV.createNewInstance(..) expects one argument (object)!");
|
|
65
67
|
}
|
|
66
68
|
jsi::Object config = arguments[0].asObject(runtime);
|
|
67
69
|
|
|
68
|
-
NSString* instanceId = [MmkvModule getPropertyAsStringOrNilFromObject:config
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
NSString* instanceId = [MmkvModule getPropertyAsStringOrNilFromObject:config
|
|
71
|
+
propertyName:"id"
|
|
72
|
+
runtime:runtime];
|
|
73
|
+
NSString* path = [MmkvModule getPropertyAsStringOrNilFromObject:config
|
|
74
|
+
propertyName:"path"
|
|
75
|
+
runtime:runtime];
|
|
76
|
+
NSString* encryptionKey = [MmkvModule getPropertyAsStringOrNilFromObject:config
|
|
77
|
+
propertyName:"encryptionKey"
|
|
78
|
+
runtime:runtime];
|
|
71
79
|
|
|
72
80
|
auto instance = std::make_shared<MmkvHostObject>(instanceId, path, encryptionKey);
|
|
73
81
|
return jsi::Object::createFromHostObject(runtime, instance);
|
|
74
|
-
|
|
75
|
-
|
|
82
|
+
});
|
|
83
|
+
runtime.global().setProperty(runtime, "mmkvCreateNewInstance", std::move(mmkvCreateNewInstance));
|
|
76
84
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
85
|
+
// Adds the PropNameIDCache object to the Runtime. If the Runtime gets destroyed, the Object gets
|
|
86
|
+
// destroyed and the cache gets invalidated.
|
|
87
|
+
auto propNameIdCache = std::make_shared<InvalidateCacheOnDestroy>(runtime);
|
|
88
|
+
runtime.global().setProperty(runtime, "mmkvArrayBufferPropNameIdCache",
|
|
89
|
+
jsi::Object::createFromHostObject(runtime, propNameIdCache));
|
|
80
90
|
|
|
81
|
-
|
|
82
|
-
|
|
91
|
+
NSLog(@"Installed global.mmkvCreateNewInstance!");
|
|
92
|
+
return @true;
|
|
83
93
|
}
|
|
84
94
|
|
|
85
95
|
@end
|