diff --git a/Android/MMKV/gradle.properties b/Android/MMKV/gradle.properties index 17ceb0d4..489d64f9 100644 --- a/Android/MMKV/gradle.properties +++ b/Android/MMKV/gradle.properties @@ -12,6 +12,6 @@ org.gradle.jvmargs=-Xmx1536m # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -VERSION_NAME_PREFIX=1.0.14 +VERSION_NAME_PREFIX=1.0.15 #VERSION_NAME_SUFFIX=-SNAPSHOT VERSION_NAME_SUFFIX= \ No newline at end of file diff --git a/Android/MMKV/mmkv/src/main/cpp/MMKV.cpp b/Android/MMKV/mmkv/src/main/cpp/MMKV.cpp index b0219e44..f1af2904 100644 --- a/Android/MMKV/mmkv/src/main/cpp/MMKV.cpp +++ b/Android/MMKV/mmkv/src/main/cpp/MMKV.cpp @@ -660,7 +660,7 @@ bool MMKV::ensureMemorySize(size_t newSize) { return false; } } else { - size_t avgItemSize = lenNeeded / m_dic.size(); + size_t avgItemSize = lenNeeded / std::max(1, m_dic.size()); size_t futureUsage = avgItemSize * std::max(8, (m_dic.size() + 1) / 2); // 1. no space for a full rewrite, double it // 2. or space is not large enough for future usage, double it to avoid frequently full rewrite diff --git a/Android/MMKV/mmkv/src/main/cpp/native-bridge.cpp b/Android/MMKV/mmkv/src/main/cpp/native-bridge.cpp index aedc3709..2964f47a 100644 --- a/Android/MMKV/mmkv/src/main/cpp/native-bridge.cpp +++ b/Android/MMKV/mmkv/src/main/cpp/native-bridge.cpp @@ -32,9 +32,10 @@ static jclass g_cls = nullptr; static jfieldID g_fileID = nullptr; static jmethodID g_callbackOnCRCFailID = nullptr; static jmethodID g_callbackOnFileLengthErrorID = nullptr; -static JNIEnv *g_currentEnv = nullptr; +static JavaVM *g_currentJVM = nullptr; extern "C" JNIEXPORT JNICALL jint JNI_OnLoad(JavaVM *vm, void *reserved) { + g_currentJVM = vm; JNIEnv *env; if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { return -1; @@ -138,20 +139,34 @@ static jobjectArray vector2jarray(JNIEnv *env, const vector &arr) { return nullptr; } +static JNIEnv *getCurrentEnv() { + if (g_currentJVM) { + JNIEnv *currentEnv = nullptr; + auto ret = g_currentJVM->GetEnv(reinterpret_cast(¤tEnv), JNI_VERSION_1_6); + if (ret == JNI_OK) { + return currentEnv; + } else { + MMKVError("fail to get current JNIEnv: %d", ret); + } + } + return nullptr; +} + MMKVRecoverStrategic onMMKVCRCCheckFail(const std::string &mmapID) { - if (g_currentEnv && g_callbackOnCRCFailID) { - jstring str = string2jstring(g_currentEnv, mmapID); - auto strategic = g_currentEnv->CallStaticIntMethod(g_cls, g_callbackOnCRCFailID, str); + auto currentEnv = getCurrentEnv(); + if (g_currentJVM && g_callbackOnCRCFailID) { + jstring str = string2jstring(currentEnv, mmapID); + auto strategic = currentEnv->CallStaticIntMethod(g_cls, g_callbackOnCRCFailID, str); return static_cast(strategic); } return OnErrorDiscard; } MMKVRecoverStrategic onMMKVFileLengthError(const std::string &mmapID) { - if (g_currentEnv && g_callbackOnFileLengthErrorID) { - jstring str = string2jstring(g_currentEnv, mmapID); - auto strategic = - g_currentEnv->CallStaticIntMethod(g_cls, g_callbackOnFileLengthErrorID, str); + auto currentEnv = getCurrentEnv(); + if (currentEnv && g_callbackOnFileLengthErrorID) { + jstring str = string2jstring(currentEnv, mmapID); + auto strategic = currentEnv->CallStaticIntMethod(g_cls, g_callbackOnFileLengthErrorID, str); return static_cast(strategic); } return OnErrorDiscard; @@ -159,7 +174,6 @@ MMKVRecoverStrategic onMMKVFileLengthError(const std::string &mmapID) { extern "C" JNIEXPORT JNICALL jlong Java_com_tencent_mmkv_MMKV_getMMKVWithID( JNIEnv *env, jobject obj, jstring mmapID, jint mode, jstring cryptKey) { - g_currentEnv = env; MMKV *kv = nullptr; if (!mmapID) { return (jlong) kv; @@ -181,7 +195,6 @@ extern "C" JNIEXPORT JNICALL jlong Java_com_tencent_mmkv_MMKV_getMMKVWithID( extern "C" JNIEXPORT JNICALL jlong Java_com_tencent_mmkv_MMKV_getMMKVWithIDAndSize( JNIEnv *env, jobject obj, jstring mmapID, jint size, jint mode, jstring cryptKey) { - g_currentEnv = env; MMKV *kv = nullptr; if (!mmapID || size < 0) { return (jlong) kv; @@ -204,7 +217,6 @@ extern "C" JNIEXPORT JNICALL jlong Java_com_tencent_mmkv_MMKV_getDefaultMMKV(JNI jobject obj, jint mode, jstring cryptKey) { - g_currentEnv = env; MMKV *kv = nullptr; if (cryptKey != nullptr) { @@ -222,7 +234,6 @@ extern "C" JNIEXPORT JNICALL jlong Java_com_tencent_mmkv_MMKV_getDefaultMMKV(JNI extern "C" JNIEXPORT JNICALL jlong Java_com_tencent_mmkv_MMKV_getMMKVWithAshmemFD( JNIEnv *env, jobject obj, jstring mmapID, jint fd, jint metaFD, jstring cryptKey) { - g_currentEnv = env; MMKV *kv = nullptr; if (!mmapID || fd < 0 || metaFD < 0) { return (jlong) kv; diff --git a/Android/MMKV/mmkv/src/main/java/com/tencent/mmkv/MMKV.java b/Android/MMKV/mmkv/src/main/java/com/tencent/mmkv/MMKV.java index 460b431a..94decd0e 100644 --- a/Android/MMKV/mmkv/src/main/java/com/tencent/mmkv/MMKV.java +++ b/Android/MMKV/mmkv/src/main/java/com/tencent/mmkv/MMKV.java @@ -304,8 +304,7 @@ public T decodeParcelable(String key, Class tClass) { } @SuppressWarnings("unchecked") - public - T decodeParcelable(String key, Class tClass, T defaultValue) { + public T decodeParcelable(String key, Class tClass, T defaultValue) { if (tClass == null) { return defaultValue; } diff --git a/Android/MMKV/mmkvdemo/build.gradle b/Android/MMKV/mmkvdemo/build.gradle index 371d22ce..9bfb29cd 100644 --- a/Android/MMKV/mmkvdemo/build.gradle +++ b/Android/MMKV/mmkvdemo/build.gradle @@ -63,8 +63,8 @@ repositories { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') // implementation project(':mmkv') - implementation 'com.tencent:mmkv:1.0.14' -// implementation 'com.tencent:mmkv-static:1.0.14' + implementation 'com.tencent:mmkv:1.0.15' +// implementation 'com.tencent:mmkv-static:1.0.15' implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' diff --git a/Android/MMKV/mmkvdemo/src/main/java/com/tencent/mmkvdemo/MainActivity.java b/Android/MMKV/mmkvdemo/src/main/java/com/tencent/mmkvdemo/MainActivity.java index 658ac643..8ec6f5a9 100644 --- a/Android/MMKV/mmkvdemo/src/main/java/com/tencent/mmkvdemo/MainActivity.java +++ b/Android/MMKV/mmkvdemo/src/main/java/com/tencent/mmkvdemo/MainActivity.java @@ -69,6 +69,8 @@ public void onClick(View v) { } }); + //testHolderForMultiThread(); + //prepareInterProcessAshmem(); //prepareInterProcessAshmemByContentProvider(KEY_1); @@ -330,6 +332,29 @@ private void testInterProcessReKey() { prepareInterProcessAshmemByContentProvider(KEY_2); } + private void testHolderForMultiThread() { + final int COUNT = 1; + final int THREAD_COUNT = 1; + final String ID = "Hotel"; + final String KEY = "California"; + final String VALUE = "You can checkout any time you like, but you can never leave."; + + final MMKV mmkv = MMKV.mmkvWithID(ID); + Runnable task = new Runnable() { + public void run() { + for (int i = 0; i < COUNT; ++i) { + mmkv.putString(KEY, VALUE); + mmkv.getString(KEY, null); + mmkv.remove(KEY); + } + } + }; + + for (int i = 0; i < THREAD_COUNT; ++i) { + new Thread(task, "MMKV-" + i).start(); + } + } + @Override public MMKVRecoverStrategic onMMKVCRCCheckFail(String mmapID) { return MMKVRecoverStrategic.OnErrorRecover; diff --git a/CHANGELOG.md b/CHANGELOG.md index 23ec9075..5d24c000 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # MMKV Change Log +## v1.0.15 / 2018-12-13 +### iOS / macOS +What's new + +* Storing **NSString/NSData/NSDate** directly by calling `setString`/`getSring`, `setData`/`getData`, `setDate`/getDate`. +* Fix a potencial crash due to divided by zero. + + +### Android +What's new + +* Fix a stack overflow crash due to the **callback** feature introduced by v1.0.13. +* Fix a potencial crash due to divided by zero. + +### Win32 +MMKV for Win32 in under construction. Hopefully will come out in next release. For those who are interested, check out branch `dev_win32` for the latest development. + ## v1.0.14 / 2018-11-30 ### iOS / macOS What's new diff --git a/README.md b/README.md index 44f5d5a3..d7ab1627 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -[![license](https://img.shields.io/badge/license-BSD_3-brightgreen.svg?style=flat)](https://github.com/Tencent/MMKV/blob/master/LICENSE.txt) +[![license](https://img.shields.io/badge/license-BSD_3-brightgreen.svg?style=flat)](https://github.com/Tencent/MMKV/blob/master/LICENSE.TXT) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/MMKV/pulls) -[![Release Version](https://img.shields.io/badge/release-1.0.14-brightgreen.svg)](https://github.com/Tencent/MMKV/releases) +[![Release Version](https://img.shields.io/badge/release-1.0.15-brightgreen.svg)](https://github.com/Tencent/MMKV/releases) [![Platform](https://img.shields.io/badge/Platform-%20iOS%20%7C%20Android-brightgreen.svg)](https://github.com/Tencent/MMKV/wiki/home) 中文版本请参看[这里](./readme_cn.md) @@ -75,8 +75,8 @@ Add the following lines to `build.gradle` on your app module: ```gradle dependencies { - implementation 'com.tencent:mmkv:1.0.14' - // replace "1.0.14" with any available version + implementation 'com.tencent:mmkv:1.0.15' + // replace "1.0.15" with any available version } ``` diff --git a/iOS/MMKV/MMKV/MMKV.h b/iOS/MMKV/MMKV/MMKV.h index 6b07c6fb..5460b11a 100644 --- a/iOS/MMKV/MMKV/MMKV.h +++ b/iOS/MMKV/MMKV/MMKV.h @@ -39,8 +39,7 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)reKey:(nullable NSData *)newKey NS_SWIFT_NAME(reset(cryptKey:)); - (nullable NSData *)cryptKey; -// object: NSString/NSData/NSDate/id -- (BOOL)setObject:(nullable id)object forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:)); +- (BOOL)setObject:(nullable NSObject *)object forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:)); - (BOOL)setBool:(BOOL)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:)); @@ -56,6 +55,12 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)setDouble:(double)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:)); +- (BOOL)setString:(NSString *)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:)); + +- (BOOL)setDate:(NSDate *)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:)); + +- (BOOL)setData:(NSData *)value forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:)); + - (nullable id)getObjectOfClass:(Class)cls forKey:(NSString *)key NS_SWIFT_NAME(object(of:forKey:)); - (BOOL)getBoolForKey:(NSString *)key __attribute__((swift_name("bool(forKey:)"))); @@ -79,6 +84,15 @@ NS_ASSUME_NONNULL_BEGIN - (double)getDoubleForKey:(NSString *)key NS_SWIFT_NAME(double(forKey:)); - (double)getDoubleForKey:(NSString *)key defaultValue:(double)defaultValue NS_SWIFT_NAME(double(forKey:defaultValue:)); +- (nullable NSString *)getStringForKey:(NSString *)key NS_SWIFT_NAME(string(forKey:)); +- (nullable NSString *)getStringForKey:(NSString *)key defaultValue:(nullable NSString *)defaultValue NS_SWIFT_NAME(string(forKey:defaultValue:)); + +- (nullable NSDate *)getDateForKey:(NSString *)key NS_SWIFT_NAME(date(forKey:)); +- (nullable NSDate *)getDateForKey:(NSString *)key defaultValue:(nullable NSDate *)defaultValue NS_SWIFT_NAME(date(forKey:defaultValue:)); + +- (nullable NSData *)getDataForKey:(NSString *)key NS_SWIFT_NAME(data(forKey:)); +- (nullable NSData *)getDataForKey:(NSString *)key defaultValue:(nullable NSData *)defaultValue NS_SWIFT_NAME(data(forKey:defaultValue:)); + - (BOOL)containsKey:(NSString *)key NS_SWIFT_NAME(contains(key:)); - (size_t)count; diff --git a/iOS/MMKV/MMKV/MMKV.mm b/iOS/MMKV/MMKV/MMKV.mm index 06fb16d5..512e5c58 100644 --- a/iOS/MMKV/MMKV/MMKV.mm +++ b/iOS/MMKV/MMKV/MMKV.mm @@ -524,7 +524,7 @@ - (BOOL)ensureMemorySize:(size_t)newSize { static const int offset = pbFixed32Size(0); NSData *data = [MiniPBCoder encodeDataWithObject:m_dic]; size_t lenNeeded = data.length + offset + newSize; - size_t avgItemSize = lenNeeded / m_dic.count; + size_t avgItemSize = lenNeeded / std::max(1, m_dic.count); size_t futureUsage = avgItemSize * std::max(8, m_dic.count / 2); // 1. no space for a full rewrite, double it // 2. or space is not large enough for future usage, double it to avoid frequently full rewrite @@ -619,7 +619,7 @@ - (BOOL)writeAcutalSize:(size_t)actualSize { return YES; } -- (BOOL)setData:(NSData *)data forKey:(NSString *)key { +- (BOOL)setRawData:(NSData *)data forKey:(NSString *)key { if (data.length <= 0 || key.length <= 0) { return NO; } @@ -682,7 +682,7 @@ - (BOOL)appendData:(NSData *)data forKey:(NSString *)key { } } -- (NSData *)getDataForKey:(NSString *)key { +- (NSData *)getRawDataForKey:(NSString *)key { CScopedLock lock(m_lock); [self checkLoadData]; return [m_dic objectForKey:key]; @@ -900,7 +900,7 @@ - (BOOL)reKey:(NSData *)newKey { #pragma mark - set & get -- (BOOL)setObject:(nullable id)object forKey:(NSString *)key { +- (BOOL)setObject:(nullable NSObject *)object forKey:(NSString *)key { if (key.length <= 0) { return NO; } @@ -913,12 +913,12 @@ - (BOOL)setObject:(nullable id)object forKey:(NSString *)key { if ([MiniPBCoder isMiniPBCoderCompatibleObject:object]) { data = [MiniPBCoder encodeDataWithObject:object]; } else { - if ([[object class] conformsToProtocol:@protocol(NSCoding)]) { + /*if ([object conformsToProtocol:@protocol(NSCoding)])*/ { data = [NSKeyedArchiver archivedDataWithRootObject:object]; } } - return [self setData:data forKey:key]; + return [self setRawData:data forKey:key]; } - (BOOL)setBool:(BOOL)value forKey:(NSString *)key { @@ -930,7 +930,7 @@ - (BOOL)setBool:(BOOL)value forKey:(NSString *)key { MiniCodedOutputData output(data); output.writeBool(value); - return [self setData:data forKey:key]; + return [self setRawData:data forKey:key]; } - (BOOL)setInt32:(int32_t)value forKey:(NSString *)key { @@ -942,7 +942,7 @@ - (BOOL)setInt32:(int32_t)value forKey:(NSString *)key { MiniCodedOutputData output(data); output.writeInt32(value); - return [self setData:data forKey:key]; + return [self setRawData:data forKey:key]; } - (BOOL)setUInt32:(uint32_t)value forKey:(NSString *)key { @@ -954,7 +954,7 @@ - (BOOL)setUInt32:(uint32_t)value forKey:(NSString *)key { MiniCodedOutputData output(data); output.writeUInt32(value); - return [self setData:data forKey:key]; + return [self setRawData:data forKey:key]; } - (BOOL)setInt64:(int64_t)value forKey:(NSString *)key { @@ -966,7 +966,7 @@ - (BOOL)setInt64:(int64_t)value forKey:(NSString *)key { MiniCodedOutputData output(data); output.writeInt64(value); - return [self setData:data forKey:key]; + return [self setRawData:data forKey:key]; } - (BOOL)setUInt64:(uint64_t)value forKey:(NSString *)key { @@ -978,7 +978,7 @@ - (BOOL)setUInt64:(uint64_t)value forKey:(NSString *)key { MiniCodedOutputData output(data); output.writeUInt64(value); - return [self setData:data forKey:key]; + return [self setRawData:data forKey:key]; } - (BOOL)setFloat:(float)value forKey:(NSString *)key { @@ -990,7 +990,7 @@ - (BOOL)setFloat:(float)value forKey:(NSString *)key { MiniCodedOutputData output(data); output.writeFloat(value); - return [self setData:data forKey:key]; + return [self setRawData:data forKey:key]; } - (BOOL)setDouble:(double)value forKey:(NSString *)key { @@ -1002,14 +1002,26 @@ - (BOOL)setDouble:(double)value forKey:(NSString *)key { MiniCodedOutputData output(data); output.writeDouble(value); - return [self setData:data forKey:key]; + return [self setRawData:data forKey:key]; +} + +- (BOOL)setString:(NSString *)value forKey:(NSString *)key { + return [self setObject:value forKey:key]; +} + +- (BOOL)setDate:(NSDate *)value forKey:(NSString *)key { + return [self setObject:value forKey:key]; +} + +- (BOOL)setData:(NSData *)value forKey:(NSString *)key { + return [self setObject:value forKey:key]; } - (id)getObjectOfClass:(Class)cls forKey:(NSString *)key { if (key.length <= 0) { return nil; } - NSData *data = [self getDataForKey:key]; + NSData *data = [self getRawDataForKey:key]; if (data.length > 0) { if ([MiniPBCoder isMiniPBCoderCompatibleType:cls]) { @@ -1030,7 +1042,7 @@ - (BOOL)getBoolForKey:(NSString *)key defaultValue:(BOOL)defaultValue { if (key.length <= 0) { return defaultValue; } - NSData *data = [self getDataForKey:key]; + NSData *data = [self getRawDataForKey:key]; if (data.length > 0) { @try { MiniCodedInputData input(data); @@ -1049,7 +1061,7 @@ - (int32_t)getInt32ForKey:(NSString *)key defaultValue:(int32_t)defaultValue { if (key.length <= 0) { return defaultValue; } - NSData *data = [self getDataForKey:key]; + NSData *data = [self getRawDataForKey:key]; if (data.length > 0) { @try { MiniCodedInputData input(data); @@ -1068,7 +1080,7 @@ - (uint32_t)getUInt32ForKey:(NSString *)key defaultValue:(uint32_t)defaultValue if (key.length <= 0) { return defaultValue; } - NSData *data = [self getDataForKey:key]; + NSData *data = [self getRawDataForKey:key]; if (data.length > 0) { @try { MiniCodedInputData input(data); @@ -1087,7 +1099,7 @@ - (int64_t)getInt64ForKey:(NSString *)key defaultValue:(int64_t)defaultValue { if (key.length <= 0) { return defaultValue; } - NSData *data = [self getDataForKey:key]; + NSData *data = [self getRawDataForKey:key]; if (data.length > 0) { @try { MiniCodedInputData input(data); @@ -1106,7 +1118,7 @@ - (uint64_t)getUInt64ForKey:(NSString *)key defaultValue:(uint64_t)defaultValue if (key.length <= 0) { return defaultValue; } - NSData *data = [self getDataForKey:key]; + NSData *data = [self getRawDataForKey:key]; if (data.length > 0) { @try { MiniCodedInputData input(data); @@ -1125,7 +1137,7 @@ - (float)getFloatForKey:(NSString *)key defaultValue:(float)defaultValue { if (key.length <= 0) { return defaultValue; } - NSData *data = [self getDataForKey:key]; + NSData *data = [self getRawDataForKey:key]; if (data.length > 0) { @try { MiniCodedInputData input(data); @@ -1144,7 +1156,7 @@ - (double)getDoubleForKey:(NSString *)key defaultValue:(double)defaultValue { if (key.length <= 0) { return defaultValue; } - NSData *data = [self getDataForKey:key]; + NSData *data = [self getRawDataForKey:key]; if (data.length > 0) { @try { MiniCodedInputData input(data); @@ -1156,6 +1168,36 @@ - (double)getDoubleForKey:(NSString *)key defaultValue:(double)defaultValue { return defaultValue; } +- (nullable NSString *)getStringForKey:(NSString *)key { + return [self getStringForKey:key defaultValue:nil]; +} +- (nullable NSString *)getStringForKey:(NSString *)key defaultValue:(nullable NSString *)defaultValue { + if (key.length <= 0) { + return defaultValue; + } + return [self getObjectOfClass:NSString.class forKey:key]; +} + +- (nullable NSDate *)getDateForKey:(NSString *)key { + return [self getDateForKey:key defaultValue:nil]; +} +- (nullable NSDate *)getDateForKey:(NSString *)key defaultValue:(nullable NSDate *)defaultValue { + if (key.length <= 0) { + return defaultValue; + } + return [self getObjectOfClass:NSDate.class forKey:key]; +} + +- (nullable NSData *)getDataForKey:(NSString *)key { + return [self getDataForKey:key defaultValue:nil]; +} +- (nullable NSData *)getDataForKey:(NSString *)key defaultValue:(nullable NSData *)defaultValue { + if (key.length <= 0) { + return defaultValue; + } + return [self getObjectOfClass:NSData.class forKey:key]; +} + #pragma mark - enumerate - (BOOL)containsKey:(NSString *)key { diff --git a/iOS/MMKV/MMKV/Resources/Info.plist b/iOS/MMKV/MMKV/Resources/Info.plist index b84a849d..910e8276 100644 --- a/iOS/MMKV/MMKV/Resources/Info.plist +++ b/iOS/MMKV/MMKV/Resources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0.14 + 1.0.15 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/iOS/MMKVDemo/MMKVDemo/DemoSwiftUsage.swift b/iOS/MMKVDemo/MMKVDemo/DemoSwiftUsage.swift index 94355474..1eae2b55 100644 --- a/iOS/MMKVDemo/MMKVDemo/DemoSwiftUsage.swift +++ b/iOS/MMKVDemo/MMKVDemo/DemoSwiftUsage.swift @@ -48,16 +48,16 @@ class DemoSwiftUsage : NSObject { mmkv.set(Double.infinity, forKey: "double") print("Swift: double = \(mmkv.double(forKey: "double"))") - + mmkv.set("Hello from Swift", forKey: "string") - print("Swift: string = \(mmkv.object(of: NSString.self, forKey: "string") ?? "")") - + print("Swift: string = \(mmkv.string(forKey: "string") ?? "")") + mmkv.set(NSDate(), forKey: "date") - let date = mmkv.object(of: NSDate.self, forKey: "date") as? Date + let date = mmkv.date(forKey: "date") print("Swift: date = \(date?.description(with: .current) ?? "null")") - + mmkv.set("Hello from Swift".data(using: .utf8) ?? Data(), forKey: "data") - let data = mmkv.object(of: NSData.self, forKey: "data") as? Data + let data = mmkv.data(forKey: "data") let str = String(data: data ?? Data(), encoding: .utf8) ?? "" print("Swift: data = \(str)") diff --git a/iOS/MMKVDemo/MMKVDemo/ViewController.mm b/iOS/MMKVDemo/MMKVDemo/ViewController.mm index 34ad6703..07d5bdc4 100644 --- a/iOS/MMKVDemo/MMKVDemo/ViewController.mm +++ b/iOS/MMKVDemo/MMKVDemo/ViewController.mm @@ -84,8 +84,8 @@ - (void)funcionalTest { [mmkv setDouble:std::numeric_limits::max() forKey:@"double"]; NSLog(@"double:%f", [mmkv getDoubleForKey:@"double"]); - [mmkv setObject:@"hello, mmkv" forKey:@"string"]; - NSLog(@"string:%@", [mmkv getObjectOfClass:NSString.class forKey:@"string"]); + [mmkv setString:@"hello, mmkv" forKey:@"string"]; + NSLog(@"string:%@", [mmkv getStringForKey:@"string"]); [mmkv setObject:nil forKey:@"string"]; NSLog(@"string after set nil:%@, containsKey:%d", @@ -93,11 +93,11 @@ - (void)funcionalTest { forKey:@"string"], [mmkv containsKey:@"string"]); - [mmkv setObject:[NSDate date] forKey:@"date"]; - NSLog(@"date:%@", [mmkv getObjectOfClass:NSDate.class forKey:@"date"]); + [mmkv setDate:[NSDate date] forKey:@"date"]; + NSLog(@"date:%@", [mmkv getDateForKey:@"date"]); - [mmkv setObject:[@"hello, mmkv again and again" dataUsingEncoding:NSUTF8StringEncoding] forKey:@"data"]; - NSData *data = [mmkv getObjectOfClass:NSData.class forKey:@"data"]; + [mmkv setData:[@"hello, mmkv again and again" dataUsingEncoding:NSUTF8StringEncoding] forKey:@"data"]; + NSData *data = [mmkv getDataForKey:@"data"]; NSLog(@"data:%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); [mmkv removeValueForKey:@"bool"]; diff --git a/iOS/MMKVDemo/MMKVDemoTests/MMKVDemoTests.mm b/iOS/MMKVDemo/MMKVDemoTests/MMKVDemoTests.mm index 88951178..a8de46fe 100644 --- a/iOS/MMKVDemo/MMKVDemoTests/MMKVDemoTests.mm +++ b/iOS/MMKVDemo/MMKVDemoTests/MMKVDemoTests.mm @@ -213,6 +213,18 @@ - (void)testNSString { XCTAssertEqualObjects(value, nil); } +- (void)testNSStringForNewGetSet { + NSString *str = @"Hello 2018 world cup 世界杯"; + BOOL ret = [mmkv setString:str forKey:@"string"]; + XCTAssertEqual(ret, YES); + + NSString *value = [mmkv getStringForKey:@"string"]; + XCTAssertEqualObjects(value, str); + + value = [mmkv getStringForKey:KeyNotExist]; + XCTAssertEqualObjects(value, nil); +} + - (void)testNSData { NSString *str = @"Hello 2018 world cup 世界杯"; NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding]; @@ -226,6 +238,19 @@ - (void)testNSData { XCTAssertEqualObjects(value, nil); } +- (void)testNSDataForNewGetSet { + NSString *str = @"Hello 2018 world cup 世界杯"; + NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding]; + BOOL ret = [mmkv setData:data forKey:@"data"]; + XCTAssertEqual(ret, YES); + + NSData *value = [mmkv getDataForKey:@"data"]; + XCTAssertEqualObjects(value, data); + + value = [mmkv getDataForKey:KeyNotExist]; + XCTAssertEqualObjects(value, nil); +} + - (void)testNSDate { NSDate *date = [NSDate date]; BOOL ret = [mmkv setObject:date forKey:@"date"]; @@ -238,6 +263,18 @@ - (void)testNSDate { XCTAssertEqualObjects(value, nil); } +- (void)testNSDateForNewGetSet { + NSDate *date = [NSDate date]; + BOOL ret = [mmkv setDate:date forKey:@"date"]; + XCTAssertEqual(ret, YES); + + NSDate *value = [mmkv getDateForKey:@"date"]; + XCTAssertEqualWithAccuracy(date.timeIntervalSince1970, value.timeIntervalSince1970, 0.001); + + value = [mmkv getObjectOfClass:NSDate.class forKey:KeyNotExist]; + XCTAssertEqualObjects(value, nil); +} + - (void)testNSDictionary { NSDictionary *dic = @{@"key1" : @"value1", @"key2" : @(2)}; diff --git a/iOS/MMKVDemo/MMKVMacDemo/ViewController.mm b/iOS/MMKVDemo/MMKVMacDemo/ViewController.mm index b0e9cd13..edbc013e 100644 --- a/iOS/MMKVDemo/MMKVMacDemo/ViewController.mm +++ b/iOS/MMKVDemo/MMKVMacDemo/ViewController.mm @@ -62,11 +62,17 @@ - (void)funcionalTest { [mmkv setDouble:std::numeric_limits::max() forKey:@"double"]; NSLog(@"double:%f", [mmkv getDoubleForKey:@"double"]); - [mmkv setObject:@"hello, mmkv" forKey:@"string"]; - NSLog(@"string:%@", [mmkv getObjectOfClass:NSString.class forKey:@"string"]); + [mmkv setString:@"hello, mmkv" forKey:@"string"]; + NSLog(@"string:%@", [mmkv getStringForKey:@"string"]); - [mmkv setObject:[NSDate date] forKey:@"date"]; - NSLog(@"date:%@", [mmkv getObjectOfClass:NSDate.class forKey:@"date"]); + // [mmkv setObject:@"hello, mmkv" forKey:@"string"]; + // NSLog(@"string:%@", [mmkv getObjectOfClass:NSString.class forKey:@"string"]); + + [mmkv setDate:[NSDate date] forKey:@"date"]; + NSLog(@"date:%@", [mmkv getDateForKey:@"date"]); + + // [mmkv setObject:[NSDate date] forKey:@"date"]; + // NSLog(@"date:%@", [mmkv getObjectOfClass:NSDate.class forKey:@"date"]); [mmkv setObject:[@"hello, mmkv again and again" dataUsingEncoding:NSUTF8StringEncoding] forKey:@"data"]; NSData *data = [mmkv getObjectOfClass:NSData.class forKey:@"data"]; diff --git a/readme_cn.md b/readme_cn.md index 9512227a..ce77bf1a 100644 --- a/readme_cn.md +++ b/readme_cn.md @@ -59,8 +59,8 @@ NSString *str = [mmkv getObjectOfClass:NSString.class forKey:@"string"]; ```gradle dependencies { - implementation 'com.tencent:mmkv:1.0.14' - // replace "1.0.14" with any available version + implementation 'com.tencent:mmkv:1.0.15' + // replace "1.0.15" with any available version } ```