diff --git a/Android/MMKV/build.gradle b/Android/MMKV/build.gradle index 56d9be6d..e1fa14bb 100644 --- a/Android/MMKV/build.gradle +++ b/Android/MMKV/build.gradle @@ -1,14 +1,14 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.11' + ext.kotlin_version = '1.3.61' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.6.1' + classpath 'com.android.tools.build:gradle:3.6.2' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.1' classpath 'digital.wup:android-maven-publish:3.6.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" diff --git a/Android/MMKV/gradle.properties b/Android/MMKV/gradle.properties index a7049f1c..2d518bfc 100644 --- a/Android/MMKV/gradle.properties +++ b/Android/MMKV/gradle.properties @@ -14,6 +14,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.1.0 +VERSION_NAME_PREFIX=1.1.1 #VERSION_NAME_SUFFIX=-SNAPSHOT VERSION_NAME_SUFFIX= \ No newline at end of file diff --git a/Android/MMKV/mmkvdemo/build.gradle b/Android/MMKV/mmkvdemo/build.gradle index 6367f972..5916ac36 100644 --- a/Android/MMKV/mmkvdemo/build.gradle +++ b/Android/MMKV/mmkvdemo/build.gradle @@ -16,7 +16,7 @@ android { defaultConfig { applicationId "com.tencent.mmkvdemo" minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 29 versionCode 1 versionName "1.0" @@ -63,8 +63,8 @@ repositories { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') // implementation project(':mmkv') -// implementation 'com.tencent:mmkv:1.1.0' - implementation 'com.tencent:mmkv-static:1.1.0' +// implementation 'com.tencent:mmkv:1.1.1' + implementation 'com.tencent:mmkv-static:1.1.1' implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bab4bd5..400a633b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # MMKV Change Log +## v1.1.1 / 2020-04-13 + +### iOS / macOS + +* Support WatchOS. +* Rename `+[MMKV onExit]` to `+[MMKV onAppTerminate]`, to avoid naming conflict with some other OpenSource projects. +* Make background write protection much more robust, fix a potential crash when writing meta info in background. +* Fix a potential data corruption bug when writing a UTF-8 (non-ASCII) key. + +### Android + +* Fix a crash in the demo project when the App is hot reloaded. +* Improve wiki & readme to recommend users to init & destruct MMKV in the `Application` class instead of on the `MainActivity` class. + +### POSIX +* Fix two compile errors with some compilers. + ## v1.1.0 / 2020-03-24 This is the first **major breaking version** ever since MMKV was made public in September 2018, introducing bunches of improvement. Due to the Covid-19, it has been delayed for about a month. Now it's finally here! diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 331df2a0..eeb138f1 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -71,7 +71,6 @@ add_library(core CodedInputData_OSX.cpp CodedOutputData.h CodedOutputData.cpp - CodedOutputData_OSX.cpp PBUtility.h PBUtility.cpp MiniPBCoder.h diff --git a/Core/CodedInputData.cpp b/Core/CodedInputData.cpp index e585e568..16b15ebd 100644 --- a/Core/CodedInputData.cpp +++ b/Core/CodedInputData.cpp @@ -22,11 +22,11 @@ #include "PBUtility.h" #include -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE # if __has_feature(objc_arc) # error This file must be compiled with MRC. Use -fno-objc-arc flag. # endif -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE using namespace std; @@ -79,7 +79,7 @@ bool CodedInputData::readBool() { return this->readRawVarint32() != 0; } -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE string CodedInputData::readString() { int32_t size = readRawVarint32(); @@ -181,7 +181,7 @@ int8_t CodedInputData::readRawByte() { return bytes[m_position++]; } -#ifdef MMKV_IOS_OR_MAC -#endif // MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE +#endif // MMKV_APPLE } // namespace mmkv diff --git a/Core/CodedInputData.h b/Core/CodedInputData.h index 9811edfe..d7142b76 100644 --- a/Core/CodedInputData.h +++ b/Core/CodedInputData.h @@ -66,7 +66,7 @@ class CodedInputData { MMBuffer readData(); -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE std::string readString(); #else NSString *readString(); diff --git a/Core/CodedInputData_OSX.cpp b/Core/CodedInputData_OSX.cpp index 3935ca1c..cc9f4ca6 100644 --- a/Core/CodedInputData_OSX.cpp +++ b/Core/CodedInputData_OSX.cpp @@ -20,7 +20,7 @@ #include "CodedInputData.h" -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE # include "PBUtility.h" # include @@ -68,4 +68,4 @@ NSData *CodedInputData::readNSData() { } // namespace mmkv -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE diff --git a/Core/CodedOutputData.cpp b/Core/CodedOutputData.cpp index ebc7044b..96d37dee 100644 --- a/Core/CodedOutputData.cpp +++ b/Core/CodedOutputData.cpp @@ -23,11 +23,11 @@ #include #include -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE # if __has_feature(objc_arc) # error This file must be compiled with MRC. Use -fno-objc-arc flag. # endif -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE using namespace std; @@ -78,7 +78,7 @@ void CodedOutputData::writeData(const MMBuffer &value) { this->writeRawData(value); } -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE void CodedOutputData::writeString(const string &value) { size_t numberOfBytes = value.size(); @@ -92,7 +92,7 @@ void CodedOutputData::writeString(const string &value) { m_position += numberOfBytes; } -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE size_t CodedOutputData::spaceLeft() { if (m_size <= m_position) { diff --git a/Core/CodedOutputData.h b/Core/CodedOutputData.h index ac988ee9..c9181c75 100644 --- a/Core/CodedOutputData.h +++ b/Core/CodedOutputData.h @@ -72,10 +72,8 @@ class CodedOutputData { void writeData(const MMBuffer &value); -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE void writeString(const std::string &value); -#else - void writeString(__unsafe_unretained NSString *value); #endif }; diff --git a/Core/CodedOutputData_OSX.cpp b/Core/CodedOutputData_OSX.cpp deleted file mode 100644 index 4981a807..00000000 --- a/Core/CodedOutputData_OSX.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making - * MMKV available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. - * All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use - * this file except in compliance with the License. You may obtain a copy of - * the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "CodedOutputData.h" - -#ifdef MMKV_IOS_OR_MAC - -# include "PBUtility.h" -# include -# include - -# if __has_feature(objc_arc) -# error This file must be compiled with MRC. Use -fno-objc-arc flag. -# endif - -using namespace std; - -namespace mmkv { - -void CodedOutputData::writeString(__unsafe_unretained NSString *value) { - NSUInteger numberOfBytes = [value lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - this->writeRawVarint32((int32_t) numberOfBytes); - if (m_position + numberOfBytes > m_size) { - auto msg = "m_position: " + to_string(m_position) + ", numberOfBytes: " + to_string(numberOfBytes) + - ", m_size: " + to_string(m_size); - throw out_of_range(msg); - } - - [value getBytes:m_ptr + m_position - maxLength:numberOfBytes - usedLength:0 - encoding:NSUTF8StringEncoding - options:0 - range:NSMakeRange(0, value.length) - remainingRange:nullptr]; - m_position += numberOfBytes; -} - -} // namespace mmkv - -#endif // MMKV_IOS_OR_MAC diff --git a/Core/Core.xcodeproj/project.pbxproj b/Core/Core.xcodeproj/project.pbxproj index cbe557f2..262e08b2 100644 --- a/Core/Core.xcodeproj/project.pbxproj +++ b/Core/Core.xcodeproj/project.pbxproj @@ -40,7 +40,39 @@ CBD723F323B5E59800D3CDAF /* MemoryFile_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723F223B5E59800D3CDAF /* MemoryFile_OSX.cpp */; }; CBD723F523B5E76200D3CDAF /* MiniPBCoder_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723F423B5E76200D3CDAF /* MiniPBCoder_OSX.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; CBD723F723B5FD9E00D3CDAF /* CodedInputData_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723F623B5FD9E00D3CDAF /* CodedInputData_OSX.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - CBD723F923B5FDBF00D3CDAF /* CodedOutputData_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723F823B5FDBF00D3CDAF /* CodedOutputData_OSX.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBF19050243D70BA001C82ED /* ThreadLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB9563F723AB2E9100ACCD39 /* ThreadLock.cpp */; }; + CBF19051243D70BA001C82ED /* MemoryFile_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723F223B5E59800D3CDAF /* MemoryFile_OSX.cpp */; }; + CBF19052243D70BA001C82ED /* MMKV.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB9563F223AB2E9100ACCD39 /* MMKV.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBF19053243D70BA001C82ED /* MiniPBCoder_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723F423B5E76200D3CDAF /* MiniPBCoder_OSX.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBF19054243D70BA001C82ED /* AESCrypt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB95640B23AB2E9100ACCD39 /* AESCrypt.cpp */; }; + CBF19055243D70BA001C82ED /* openssl_cfb128.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB95640123AB2E9100ACCD39 /* openssl_cfb128.cpp */; }; + CBF19056243D70BA001C82ED /* CodedOutputData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB9563EF23AB2E9100ACCD39 /* CodedOutputData.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBF19057243D70BA001C82ED /* openssl_md5_dgst.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB95640923AB2E9100ACCD39 /* openssl_md5_dgst.cpp */; }; + CBF19058243D70BA001C82ED /* openssl_aes-armv4.S in Sources */ = {isa = PBXBuildFile; fileRef = CBC7A07E23C7516700CCC492 /* openssl_aes-armv4.S */; }; + CBF19059243D70BA001C82ED /* crc32_armv8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBC7A0C223C8B2C900CCC492 /* crc32_armv8.cpp */; }; + CBF1905A243D70BA001C82ED /* MemoryFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB9563F023AB2E9100ACCD39 /* MemoryFile.cpp */; }; + CBF1905B243D70BA001C82ED /* CodedInputData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB9563F923AB2E9100ACCD39 /* CodedInputData.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBF1905C243D70BA001C82ED /* MMKVLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB95641123AB2E9100ACCD39 /* MMKVLog.cpp */; }; + CBF1905D243D70BA001C82ED /* PBUtility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB95641223AB2E9100ACCD39 /* PBUtility.cpp */; }; + CBF1905E243D70BA001C82ED /* MiniPBCoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB9563F523AB2E9100ACCD39 /* MiniPBCoder.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBF1905F243D70BA001C82ED /* openssl_md5_one.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB95640723AB2E9100ACCD39 /* openssl_md5_one.cpp */; }; + CBF19060243D70BA001C82ED /* openssl_aes_core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB95640323AB2E9100ACCD39 /* openssl_aes_core.cpp */; }; + CBF19061243D70BA001C82ED /* MMBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB9563F823AB2E9100ACCD39 /* MMBuffer.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBF19062243D70BA001C82ED /* CodedInputData_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723F623B5FD9E00D3CDAF /* CodedInputData_OSX.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBF19063243D70BA001C82ED /* openssl_aesv8-armx.S in Sources */ = {isa = PBXBuildFile; fileRef = CBC7A01023C7231600CCC492 /* openssl_aesv8-armx.S */; }; + CBF19064243D70BA001C82ED /* MMKV_OSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBD723BE23B5C22800D3CDAF /* MMKV_OSX.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CBF19065243D70BA001C82ED /* InterProcessLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB95641023AB2E9100ACCD39 /* InterProcessLock.cpp */; }; + CBF19067243D70BA001C82ED /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = CBF3450323B4BABA00168AC7 /* libz.tbd */; }; + CBF19068243D70BA001C82ED /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB58B3FF23AB3035002457F1 /* Foundation.framework */; }; + CBF1906A243D70BA001C82ED /* openssl_opensslconf.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB95640023AB2E9100ACCD39 /* openssl_opensslconf.h */; }; + CBF1906B243D70BA001C82ED /* openssl_md5.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB95640223AB2E9100ACCD39 /* openssl_md5.h */; }; + CBF1906C243D70BA001C82ED /* MMKVLog.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB9563F423AB2E9100ACCD39 /* MMKVLog.h */; }; + CBF1906D243D70BA001C82ED /* ScopedLock.hpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB9563F323AB2E9100ACCD39 /* ScopedLock.hpp */; }; + CBF1906E243D70BA001C82ED /* MMKVPredef.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB9563EE23AB2E9100ACCD39 /* MMKVPredef.h */; }; + CBF1906F243D70BA001C82ED /* PBUtility.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB9563F623AB2E9100ACCD39 /* PBUtility.h */; }; + CBF19070243D70BA001C82ED /* ThreadLock.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB95640D23AB2E9100ACCD39 /* ThreadLock.h */; }; + CBF19071243D70BA001C82ED /* MMBuffer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB9563FA23AB2E9100ACCD39 /* MMBuffer.h */; }; + CBF19072243D70BA001C82ED /* MMKV.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CB9563ED23AB2E9100ACCD39 /* MMKV.h */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -62,10 +94,29 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CBF19069243D70BA001C82ED /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "include/$(PRODUCT_NAME)"; + dstSubfolderSpec = 16; + files = ( + CBF1906A243D70BA001C82ED /* openssl_opensslconf.h in CopyFiles */, + CBF1906B243D70BA001C82ED /* openssl_md5.h in CopyFiles */, + CBF1906C243D70BA001C82ED /* MMKVLog.h in CopyFiles */, + CBF1906D243D70BA001C82ED /* ScopedLock.hpp in CopyFiles */, + CBF1906E243D70BA001C82ED /* MMKVPredef.h in CopyFiles */, + CBF1906F243D70BA001C82ED /* PBUtility.h in CopyFiles */, + CBF19070243D70BA001C82ED /* ThreadLock.h in CopyFiles */, + CBF19071243D70BA001C82ED /* MMBuffer.h in CopyFiles */, + CBF19072243D70BA001C82ED /* MMKV.h in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ CB0DCC70242B57E5009AFE59 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/lib/libc++.tbd"; sourceTree = DEVELOPER_DIR; }; + CB467F862431D3ED00FD7421 /* MMKV_OSX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MMKV_OSX.h; sourceTree = ""; }; CB58B3FF23AB3035002457F1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; CB9563D823AB2D9500ACCD39 /* libMMKVCore.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMMKVCore.a; sourceTree = BUILT_PRODUCTS_DIR; }; CB9563E423AB2E9100ACCD39 /* CodedInputData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodedInputData.h; sourceTree = ""; }; @@ -113,7 +164,7 @@ CBD723F223B5E59800D3CDAF /* MemoryFile_OSX.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp.preprocessed; path = MemoryFile_OSX.cpp; sourceTree = ""; }; CBD723F423B5E76200D3CDAF /* MiniPBCoder_OSX.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp.preprocessed; path = MiniPBCoder_OSX.cpp; sourceTree = ""; }; CBD723F623B5FD9E00D3CDAF /* CodedInputData_OSX.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp.preprocessed; path = CodedInputData_OSX.cpp; sourceTree = ""; }; - CBD723F823B5FDBF00D3CDAF /* CodedOutputData_OSX.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp.preprocessed; path = CodedOutputData_OSX.cpp; sourceTree = ""; }; + CBF19076243D70BA001C82ED /* libMMKVCore.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMMKVCore.a; sourceTree = BUILT_PRODUCTS_DIR; }; CBF3450323B4BABA00168AC7 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; }; /* End PBXFileReference section */ @@ -127,6 +178,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CBF19066243D70BA001C82ED /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CBF19067243D70BA001C82ED /* libz.tbd in Frameworks */, + CBF19068243D70BA001C82ED /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -148,7 +208,6 @@ CBD723F623B5FD9E00D3CDAF /* CodedInputData_OSX.cpp */, CB9563F923AB2E9100ACCD39 /* CodedInputData.cpp */, CB9563E423AB2E9100ACCD39 /* CodedInputData.h */, - CBD723F823B5FDBF00D3CDAF /* CodedOutputData_OSX.cpp */, CB9563EF23AB2E9100ACCD39 /* CodedOutputData.cpp */, CB95640C23AB2E9100ACCD39 /* CodedOutputData.h */, CB95641023AB2E9100ACCD39 /* InterProcessLock.cpp */, @@ -162,6 +221,7 @@ CB9563F823AB2E9100ACCD39 /* MMBuffer.cpp */, CB9563FA23AB2E9100ACCD39 /* MMBuffer.h */, CBD723BE23B5C22800D3CDAF /* MMKV_OSX.cpp */, + CB467F862431D3ED00FD7421 /* MMKV_OSX.h */, CB9563F223AB2E9100ACCD39 /* MMKV.cpp */, CB9563ED23AB2E9100ACCD39 /* MMKV.h */, CB95641123AB2E9100ACCD39 /* MMKVLog.cpp */, @@ -183,6 +243,7 @@ isa = PBXGroup; children = ( CB9563D823AB2D9500ACCD39 /* libMMKVCore.a */, + CBF19076243D70BA001C82ED /* libMMKVCore.a */, ); name = Products; sourceTree = ""; @@ -246,6 +307,23 @@ productReference = CB9563D823AB2D9500ACCD39 /* libMMKVCore.a */; productType = "com.apple.product-type.library.static"; }; + CBF1904E243D70BA001C82ED /* MMKVWatchCore */ = { + isa = PBXNativeTarget; + buildConfigurationList = CBF19073243D70BA001C82ED /* Build configuration list for PBXNativeTarget "MMKVWatchCore" */; + buildPhases = ( + CBF1904F243D70BA001C82ED /* Sources */, + CBF19066243D70BA001C82ED /* Frameworks */, + CBF19069243D70BA001C82ED /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MMKVWatchCore; + productName = Core; + productReference = CBF19076243D70BA001C82ED /* libMMKVCore.a */; + productType = "com.apple.product-type.library.static"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -274,6 +352,7 @@ projectRoot = ""; targets = ( CB9563D723AB2D9500ACCD39 /* MMKVCore */, + CBF1904E243D70BA001C82ED /* MMKVWatchCore */, ); }; /* End PBXProject section */ @@ -295,7 +374,6 @@ CBC7A0C323C8B2C900CCC492 /* crc32_armv8.cpp in Sources */, CB95641523AB2E9100ACCD39 /* MemoryFile.cpp in Sources */, CB95641A23AB2E9100ACCD39 /* CodedInputData.cpp in Sources */, - CBD723F923B5FDBF00D3CDAF /* CodedOutputData_OSX.cpp in Sources */, CB95642223AB2E9100ACCD39 /* MMKVLog.cpp in Sources */, CB95642323AB2E9100ACCD39 /* PBUtility.cpp in Sources */, CB95641723AB2E9100ACCD39 /* MiniPBCoder.cpp in Sources */, @@ -309,6 +387,35 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CBF1904F243D70BA001C82ED /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CBF19050243D70BA001C82ED /* ThreadLock.cpp in Sources */, + CBF19051243D70BA001C82ED /* MemoryFile_OSX.cpp in Sources */, + CBF19052243D70BA001C82ED /* MMKV.cpp in Sources */, + CBF19053243D70BA001C82ED /* MiniPBCoder_OSX.cpp in Sources */, + CBF19054243D70BA001C82ED /* AESCrypt.cpp in Sources */, + CBF19055243D70BA001C82ED /* openssl_cfb128.cpp in Sources */, + CBF19056243D70BA001C82ED /* CodedOutputData.cpp in Sources */, + CBF19057243D70BA001C82ED /* openssl_md5_dgst.cpp in Sources */, + CBF19058243D70BA001C82ED /* openssl_aes-armv4.S in Sources */, + CBF19059243D70BA001C82ED /* crc32_armv8.cpp in Sources */, + CBF1905A243D70BA001C82ED /* MemoryFile.cpp in Sources */, + CBF1905B243D70BA001C82ED /* CodedInputData.cpp in Sources */, + CBF1905C243D70BA001C82ED /* MMKVLog.cpp in Sources */, + CBF1905D243D70BA001C82ED /* PBUtility.cpp in Sources */, + CBF1905E243D70BA001C82ED /* MiniPBCoder.cpp in Sources */, + CBF1905F243D70BA001C82ED /* openssl_md5_one.cpp in Sources */, + CBF19060243D70BA001C82ED /* openssl_aes_core.cpp in Sources */, + CBF19061243D70BA001C82ED /* MMBuffer.cpp in Sources */, + CBF19062243D70BA001C82ED /* CodedInputData_OSX.cpp in Sources */, + CBF19063243D70BA001C82ED /* openssl_aesv8-armx.S in Sources */, + CBF19064243D70BA001C82ED /* MMKV_OSX.cpp in Sources */, + CBF19065243D70BA001C82ED /* InterProcessLock.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ @@ -480,6 +587,61 @@ }; name = Release; }; + CBF19074243D70BA001C82ED /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; + CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES; + CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; + CODE_SIGN_STYLE = Automatic; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNUSED_PARAMETER = NO; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MACOSX_DEPLOYMENT_TARGET = 10.9; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = MMKVCore; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "watchsimulator watchos"; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 2.0; + }; + name = Debug; + }; + CBF19075243D70BA001C82ED /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; + CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES; + CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; + CODE_SIGN_STYLE = Automatic; + GCC_PREPROCESSOR_DEFINITIONS = "NDEBUG=1"; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_UNUSED_PARAMETER = NO; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MACOSX_DEPLOYMENT_TARGET = 10.9; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = MMKVCore; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "watchsimulator watchos"; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 2.0; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -501,6 +663,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + CBF19073243D70BA001C82ED /* Build configuration list for PBXNativeTarget "MMKVWatchCore" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CBF19074243D70BA001C82ED /* Debug */, + CBF19075243D70BA001C82ED /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = CB9563D023AB2D9500ACCD39 /* Project object */; diff --git a/Core/MMBuffer.cpp b/Core/MMBuffer.cpp index c09253cb..7c5e9237 100644 --- a/Core/MMBuffer.cpp +++ b/Core/MMBuffer.cpp @@ -23,7 +23,7 @@ #include #include -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE # if __has_feature(objc_arc) # error This file must be compiled with MRC. Use -fno-objc-arc flag. # endif @@ -44,7 +44,7 @@ MMBuffer::MMBuffer(void *source, size_t length, MMBufferCopyFlag flag) : ptr(sou } } -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE MMBuffer::MMBuffer(NSData *data, MMBufferCopyFlag flag) : ptr((void *) data.bytes), size(data.length), isNoCopy(flag) { if (isNoCopy == MMBufferCopy) { m_data = [data retain]; @@ -59,7 +59,7 @@ MMBuffer::MMBuffer(MMBuffer &&other) noexcept : ptr(other.ptr), size(other.size) other.size = 0; other.isNoCopy = MMBufferCopy; -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE m_data = other.m_data; other.m_data = nil; #endif @@ -70,7 +70,7 @@ MMBuffer &MMBuffer::operator=(MMBuffer &&other) noexcept { std::swap(size, other.size); std::swap(isNoCopy, other.isNoCopy); -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE std::swap(m_data, other.m_data); #endif @@ -78,7 +78,7 @@ MMBuffer &MMBuffer::operator=(MMBuffer &&other) noexcept { } MMBuffer::~MMBuffer() { -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE if (m_data) { if (isNoCopy == MMBufferCopy) { [m_data release]; diff --git a/Core/MMBuffer.h b/Core/MMBuffer.h index e77b2952..47b8021d 100644 --- a/Core/MMBuffer.h +++ b/Core/MMBuffer.h @@ -39,14 +39,14 @@ class MMBuffer { void *ptr; size_t size; MMBufferCopyFlag isNoCopy; -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE NSData *m_data = nil; #endif public: explicit MMBuffer(size_t length = 0); MMBuffer(void *source, size_t length, MMBufferCopyFlag flag = MMBufferCopy); -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE explicit MMBuffer(NSData *data, MMBufferCopyFlag flag = MMBufferCopy); #endif diff --git a/Core/MMKV.cpp b/Core/MMKV.cpp index 3d310f88..0775c190 100644 --- a/Core/MMKV.cpp +++ b/Core/MMKV.cpp @@ -37,11 +37,11 @@ #include #include -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE # if __has_feature(objc_arc) # error This file must be compiled with MRC. Use -fno-objc-arc flag. # endif -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE using namespace std; using namespace mmkv; @@ -116,11 +116,7 @@ MMKV::MMKV(const std::string &mmapID, MMKVMode mode, string *cryptKey, MMKVPath_ MMKV::~MMKV() { clearMemoryCache(); - if (m_crypter) { - delete m_crypter; - m_crypter = nullptr; - } - + delete m_crypter; delete m_file; delete m_metaFile; delete m_metaInfo; @@ -235,7 +231,7 @@ void decryptBuffer(AESCrypt &crypter, MMBuffer &inputBuffer) { } static void clearDictionary(MMKVMap &dic) { -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE for (auto &pair : dic) { [pair.first release]; } @@ -345,7 +341,6 @@ void MMKV::partialLoadFromFile() { void MMKV::checkDataValid(bool &loadFromFile, bool &needFullWriteback) { // try auto recover from last confirmed location - constexpr auto offset = pbFixed32Size(); auto fileSize = m_file->getFileSize(); auto checkLastConfirmedInfo = [&] { if (m_metaInfo->m_version >= MMKVVersionActualSize) { @@ -368,7 +363,7 @@ void MMKV::checkDataValid(bool &loadFromFile, bool &needFullWriteback) { } auto lastActualSize = m_metaInfo->m_lastConfirmedMetaInfo.lastActualSize; - if (lastActualSize < fileSize && (lastActualSize + offset) <= fileSize) { + if (lastActualSize < fileSize && (lastActualSize + Fixed32Size) <= fileSize) { auto lastCRCDigest = m_metaInfo->m_lastConfirmedMetaInfo.lastCRCDigest; if (checkFileCRCValid(lastActualSize, lastCRCDigest)) { loadFromFile = true; @@ -386,7 +381,7 @@ void MMKV::checkDataValid(bool &loadFromFile, bool &needFullWriteback) { m_actualSize = readActualSize(); - if (m_actualSize < fileSize && (m_actualSize + offset) <= fileSize) { + if (m_actualSize < fileSize && (m_actualSize + Fixed32Size) <= fileSize) { if (checkFileCRCValid(m_actualSize, m_metaInfo->m_crcDigest)) { loadFromFile = true; } else { @@ -410,7 +405,7 @@ void MMKV::checkDataValid(bool &loadFromFile, bool &needFullWriteback) { auto strategic = onMMKVFileLengthError(m_mmapID); if (strategic == OnErrorRecover) { // make sure we don't over read the file - m_actualSize = fileSize - offset; + m_actualSize = fileSize - Fixed32Size; loadFromFile = true; needFullWriteback = true; } @@ -585,7 +580,7 @@ void MMKV::trim() { } auto ptr = (uint8_t *) m_file->getMemory(); delete m_output; - m_output = new CodedOutputData(ptr + pbFixed32Size(), fileSize - pbFixed32Size()); + m_output = new CodedOutputData(ptr + pbFixed32Size(), fileSize - Fixed32Size); m_output->seek(m_actualSize); MMKVInfo("finish trim %s from %zu to %zu", m_mmapID.c_str(), oldSize, fileSize); @@ -606,10 +601,9 @@ bool MMKV::ensureMemorySize(size_t newSize) { } if (newSize >= m_output->spaceLeft() || m_dic.empty()) { // try a full rewrite to make space - static const int offset = pbFixed32Size(); auto fileSize = m_file->getFileSize(); MMBuffer data = MiniPBCoder::encodeDataWithObject(m_dic); - size_t lenNeeded = data.length() + offset + newSize; + size_t lenNeeded = data.length() + Fixed32Size + newSize; 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 @@ -660,7 +654,13 @@ void MMKV::oldStyleWriteActualSize(size_t actualSize) { MMKV_ASSERT(m_file->getMemory()); m_actualSize = actualSize; +#ifdef MMKV_IOS + protectFromBackgroundWriting(m_file->getMemory(), Fixed32Size, ^{ + memcpy(m_file->getMemory(), &actualSize, Fixed32Size); + }); +#else memcpy(m_file->getMemory(), &actualSize, Fixed32Size); +#endif } bool MMKV::writeActualSize(size_t size, uint32_t crcDigest, const void *iv, bool increaseSequence) { @@ -696,13 +696,22 @@ bool MMKV::writeActualSize(size_t size, uint32_t crcDigest, const void *iv, bool } needsFullWrite = true; } +#ifdef MMKV_IOS + return protectFromBackgroundWriting(m_metaFile->getMemory(), sizeof(MMKVMetaInfo), ^{ + if (unlikely(needsFullWrite)) { + m_metaInfo->write(m_metaFile->getMemory()); + } else { + m_metaInfo->writeCRCAndActualSizeOnly(m_metaFile->getMemory()); + } + }); +#else if (unlikely(needsFullWrite)) { m_metaInfo->write(m_metaFile->getMemory()); } else { m_metaInfo->writeCRCAndActualSizeOnly(m_metaFile->getMemory()); } - return true; +#endif } const MMBuffer &MMKV::getDataForKey(MMKVKey_t key) { @@ -727,7 +736,7 @@ bool MMKV::setDataForKey(MMBuffer &&data, MMKVKey_t key) { if (ret) { m_dic[key] = std::move(data); m_hasFullWriteback = false; -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE [key retain]; #endif } @@ -741,7 +750,7 @@ bool MMKV::removeDataForKey(MMKVKey_t key) { auto itr = m_dic.find(key); if (itr != m_dic.end()) { -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE [itr->first release]; #endif m_dic.erase(itr); @@ -755,8 +764,9 @@ bool MMKV::removeDataForKey(MMKVKey_t key) { } bool MMKV::appendDataWithKey(const MMBuffer &data, MMKVKey_t key) { -#ifdef MMKV_IOS_OR_MAC - size_t keyLength = key.length; +#ifdef MMKV_APPLE + auto keyData = [key dataUsingEncoding:NSUTF8StringEncoding]; + size_t keyLength = keyData.length; #else size_t keyLength = key.length(); #endif @@ -773,15 +783,19 @@ bool MMKV::appendDataWithKey(const MMBuffer &data, MMKVKey_t key) { } #ifdef MMKV_IOS - auto ret = protectFromBackgroundWriting(size, ^(CodedOutputData *output) { - output->writeString(key); - output->writeData(data); // note: write size of data + auto ret = protectFromBackgroundWriting(m_output->curWritePointer(), size, ^{ + m_output->writeData(MMBuffer(keyData, MMBufferNoCopy)); + m_output->writeData(data); // note: write size of data }); if (!ret) { return false; } +#else +#ifdef MMKV_APPLE + m_output->writeData(MMBuffer(keyData, MMBufferNoCopy)); #else m_output->writeString(key); +#endif m_output->writeData(data); // note: write size of data #endif @@ -842,13 +856,12 @@ bool MMKV::doFullWriteBack(MMBuffer &&allData) { m_crypter->encrypt(ptr, ptr, allData.length()); } - constexpr auto offset = pbFixed32Size(); auto ptr = (uint8_t *) m_file->getMemory(); delete m_output; - m_output = new CodedOutputData(ptr + offset, m_file->getFileSize() - offset); + m_output = new CodedOutputData(ptr + Fixed32Size, m_file->getFileSize() - Fixed32Size); #ifdef MMKV_IOS - auto ret = protectFromBackgroundWriting(allData.length(), ^(CodedOutputData *output) { - output->writeRawData(allData); // note: don't write size of data + auto ret = protectFromBackgroundWriting(m_output->curWritePointer(), allData.length(), ^{ + m_output->writeRawData(allData); // note: don't write size of data }); if (!ret) { // revert everything @@ -856,7 +869,7 @@ bool MMKV::doFullWriteBack(MMBuffer &&allData) { m_crypter->resetIV(oldIV); } delete m_output; - m_output = new CodedOutputData(ptr + offset, m_file->getFileSize() - offset); + m_output = new CodedOutputData(ptr + Fixed32Size, m_file->getFileSize() - Fixed32Size); m_output->seek(m_actualSize); return false; } @@ -960,8 +973,7 @@ bool MMKV::isFileValid() { bool MMKV::checkFileCRCValid(size_t actualSize, uint32_t crcDigest) { auto ptr = (uint8_t *) m_file->getMemory(); if (ptr) { - constexpr auto offset = pbFixed32Size(); - m_crcDigest = (uint32_t) CRC32(0, (const uint8_t *) ptr + offset, (uint32_t) actualSize); + m_crcDigest = (uint32_t) CRC32(0, (const uint8_t *) ptr + Fixed32Size, (uint32_t) actualSize); if (m_crcDigest == crcDigest) { return true; @@ -974,9 +986,8 @@ bool MMKV::checkFileCRCValid(size_t actualSize, uint32_t crcDigest) { void MMKV::recaculateCRCDigestWithIV(const void *iv) { auto ptr = (const uint8_t *) m_file->getMemory(); if (ptr) { - constexpr auto offset = pbFixed32Size(); m_crcDigest = 0; - m_crcDigest = (uint32_t) CRC32(0, ptr + offset, (uint32_t) m_actualSize); + m_crcDigest = (uint32_t) CRC32(0, ptr + Fixed32Size, (uint32_t) m_actualSize); writeActualSize(m_actualSize, m_crcDigest, iv, IncreaseSequence); } } @@ -1076,7 +1087,7 @@ bool MMKV::set(double value, MMKVKey_t key) { return setDataForKey(std::move(data), key); } -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE bool MMKV::set(const char *value, MMKVKey_t key) { if (!value) { @@ -1160,7 +1171,7 @@ bool MMKV::getVector(MMKVKey_t key, vector &result) { return false; } -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE bool MMKV::getBool(MMKVKey_t key, bool defaultValue) { if (isKeyEmpty(key)) { @@ -1373,7 +1384,7 @@ void MMKV::removeValueForKey(MMKVKey_t key) { removeDataForKey(key); } -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE vector MMKV::allKeys() { SCOPED_LOCK(m_lock); @@ -1413,7 +1424,7 @@ void MMKV::removeValuesForKeys(const vector &arrKeys) { } } -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE // file @@ -1462,19 +1473,18 @@ bool MMKV::isFileValid(const string &mmapID, MMKVPath_t *relatePath) { return false; } - constexpr auto offset = pbFixed32Size(); uint32_t crcDigest = 0; MMBuffer *fileData = readWholeFile(kvPath); if (fileData) { - if (fileData->getPtr() && fileData->length() >= Fixed32Size) { + if (fileData->getPtr() && (fileData->length() >= Fixed32Size)) { uint32_t actualSize = 0; memcpy(&actualSize, fileData->getPtr(), Fixed32Size); - if (actualSize > fileData->length() - offset) { + if (actualSize > (fileData->length() - Fixed32Size)) { delete fileData; return false; } - crcDigest = (uint32_t) CRC32(0, (const uint8_t *) fileData->getPtr() + offset, (uint32_t) actualSize); + crcDigest = (uint32_t) CRC32(0, (const uint8_t *) fileData->getPtr() + Fixed32Size, (uint32_t) actualSize); } delete fileData; return crcFile == crcDigest; diff --git a/Core/MMKV.h b/Core/MMKV.h index f8ebc376..c5316aab 100644 --- a/Core/MMKV.h +++ b/Core/MMKV.h @@ -83,7 +83,7 @@ class MMKV { mmkv::InterProcessLock *m_sharedProcessLock; mmkv::InterProcessLock *m_exclusiveProcessLock; -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE using MMKVKey_t = NSString *__unsafe_unretained; static bool isKeyEmpty(MMKVKey_t key) { return key.length <= 0; } #else @@ -133,16 +133,16 @@ class MMKV { void checkReSetCryptKey(int fd, int metaFD, std::string *cryptKey); #endif -#ifdef MMKV_IOS - typedef void (^WriteBlock)(mmkv::CodedOutputData *output); - bool protectFromBackgroundWriting(size_t size, WriteBlock block); +#if defined(MMKV_IOS) + typedef void (^WriteBlock)(void); + bool protectFromBackgroundWriting(void *ptr, size_t size, WriteBlock block); #endif public: // call this before getting any MMKV instance static void initializeMMKV(const MMKVPath_t &rootDir, MMKVLogLevel logLevel = MMKVLogInfo); -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE // protect from some old code that don't call initializeMMKV() static void minimalInit(MMKVPath_t defaultRootDir); #endif @@ -214,11 +214,11 @@ class MMKV { template bool set(T value, MMKVKey_t key) = delete; -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE bool set(NSObject *__unsafe_unretained obj, MMKVKey_t key); NSObject *getObject(MMKVKey_t key, Class cls); -#else // !defined(MMKV_IOS_OR_MAC) +#else // !defined(MMKV_APPLE) bool set(const char *value, MMKVKey_t key); bool set(const std::string &value, MMKVKey_t key); @@ -232,7 +232,7 @@ class MMKV { mmkv::MMBuffer getBytes(MMKVKey_t key); bool getVector(MMKVKey_t key, std::vector &result); -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE bool getBool(MMKVKey_t key, bool defaultValue = false); @@ -264,7 +264,7 @@ class MMKV { size_t actualSize(); -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE NSArray *allKeys(); void removeValuesForKeys(NSArray *arrKeys); @@ -275,11 +275,11 @@ class MMKV { # ifdef MMKV_IOS static void setIsInBackground(bool isInBackground); # endif -#else // !defined(MMKV_IOS_OR_MAC) +#else // !defined(MMKV_APPLE) std::vector allKeys(); void removeValuesForKeys(const std::vector &arrKeys); -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE void removeValueForKey(MMKVKey_t key); diff --git a/Core/MMKVLog.cpp b/Core/MMKVLog.cpp index 0efb2c2c..5747958a 100644 --- a/Core/MMKVLog.cpp +++ b/Core/MMKVLog.cpp @@ -67,7 +67,7 @@ static const char *MMKVLogLevelDesc(MMKVLogLevel level) { } } -# ifdef MMKV_IOS_OR_MAC +# ifdef MMKV_APPLE void _MMKVLogWithLevel(MMKVLogLevel level, const char *file, const char *func, int line, const char *format, ...) { if (level >= g_currentLogLevel) { @@ -121,7 +121,7 @@ void _MMKVLogWithLevel(MMKVLogLevel level, const char *file, const char *func, i } } -# endif // MMKV_IOS_OR_MAC +# endif // MMKV_APPLE # endif // MMKV_ANDROID diff --git a/Core/MMKVPredef.h b/Core/MMKVPredef.h index 24c80061..bfe92ea4 100644 --- a/Core/MMKVPredef.h +++ b/Core/MMKVPredef.h @@ -32,12 +32,11 @@ # ifdef FORCE_POSIX # define MMKV_POSIX # else -# define MMKV_IOS_OR_MAC +# define MMKV_APPLE # ifdef __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ # define MMKV_IOS -# if __has_feature(attribute_availability_app_extension) -# define MMKV_IOS_EXTENSION -# endif +# elif __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ +# define MMKV_WATCH # else # define MMKV_MAC # endif @@ -86,7 +85,7 @@ using MMKVPath_t = std::string; #endif // MMKV_WIN32 -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE # import # define MMKV_NAMESPACE_BEGIN namespace mmkv { # define MMKV_NAMESPACE_END } @@ -97,7 +96,7 @@ using MMKVLog_t = NSString *; # define MMKV_NAMESPACE_END # define MMKV_NAMESPACE_PREFIX using MMKVLog_t = const std::string &; -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE MMKV_NAMESPACE_BEGIN @@ -140,7 +139,7 @@ extern size_t DEFAULT_MMAP_SIZE; class MMBuffer; -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE struct KeyHasher { size_t operator()(NSString *key) const { return key.hash; } }; @@ -157,7 +156,7 @@ struct KeyEqualer { using MMKVMap = std::unordered_map; #else using MMKVMap = std::unordered_map; -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE template void unused(const T &) {} diff --git a/Core/MMKV_OSX.cpp b/Core/MMKV_OSX.cpp index bafac4a3..ace47bdc 100644 --- a/Core/MMKV_OSX.cpp +++ b/Core/MMKV_OSX.cpp @@ -20,7 +20,7 @@ #include "MMKVPredef.h" -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE # include "CodedInputData.h" # include "CodedOutputData.h" @@ -33,10 +33,14 @@ # include # ifdef MMKV_IOS -# include "Checksum.h" +# include "MMKV_OSX.h" # include # endif +# ifdef __aarch64__ +# include "Checksum.h" +# endif + # if __has_feature(objc_arc) # error This file must be compiled with MRC. Use -fno-objc-arc flag. # endif @@ -50,6 +54,29 @@ extern MMKVPath_t g_rootDir; enum { UnKnown = 0, PowerMac = 1, Mac, iPhone, iPod, iPad, AppleTV, AppleWatch }; static void GetAppleMachineInfo(int &device, int &version); +# ifdef MMKV_IOS +MLockPtr::MLockPtr(void *ptr, size_t size) : m_lockDownSize(0), m_lockedPtr(nullptr) { + // calc ptr to be mlock() + auto writePtr = (size_t) ptr; + auto lockPtr = (writePtr / DEFAULT_MMAP_SIZE) * DEFAULT_MMAP_SIZE; + auto lockDownSize = writePtr - lockPtr + size; + if (mlock((void *) lockPtr, lockDownSize) == 0) { + m_lockedPtr = (uint8_t *) lockPtr; + m_lockDownSize = lockDownSize; + } else { + MMKVError("fail to mlock [%p], %s", m_lockedPtr, strerror(errno)); + // just fail on this condition, otherwise app will crash anyway + } +} + +MLockPtr::~MLockPtr() { + if (m_lockedPtr) { + munlock(m_lockedPtr, m_lockDownSize); + } +} + +# endif + MMKV_NAMESPACE_BEGIN extern ThreadOnceToken_t once_control; @@ -85,38 +112,28 @@ void MMKV::setIsInBackground(bool isInBackground) { MMKVInfo("g_isInBackground:%d", g_isInBackground); } -// @finally in C++ stype -template -struct AtExit { - AtExit(F f) : m_func{f} {} - ~AtExit() { m_func(); } - -private: - F m_func; -}; - -bool MMKV::protectFromBackgroundWriting(size_t size, WriteBlock block) { +bool MMKV::protectFromBackgroundWriting(void *ptr, size_t size, WriteBlock block) { if (g_isInBackground) { - // calc ptr to be mlock() - auto writePtr = (size_t) m_output->curWritePointer(); - auto ptr = (writePtr / DEFAULT_MMAP_SIZE) * DEFAULT_MMAP_SIZE; - size_t lockDownSize = writePtr - ptr + size; - if (mlock((void *) ptr, lockDownSize) != 0) { - MMKVError("fail to mlock [%s], %s", m_mmapID.c_str(), strerror(errno)); - // just fail on this condition, otherwise app will crash anyway - //block(m_output); - return false; - } else { - AtExit cleanup([=] { munlock((void *) ptr, lockDownSize); }); + MLockPtr mlockPtr(ptr, size); + if (mlockPtr.isLocked()) { try { - block(m_output); + block(); } catch (std::exception &exception) { MMKVError("%s", exception.what()); return false; } + } else { + // just fail on this condition, otherwise app will crash anyway + //block(m_output); + return false; } } else { - block(m_output); + try { + block(); + } catch (std::exception &exception) { + MMKVError("%s", exception.what()); + return false; + } } return true; @@ -259,4 +276,4 @@ static void GetAppleMachineInfo(int &device, int &version) { } } -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE diff --git a/Core/MMKV_OSX.h b/Core/MMKV_OSX.h new file mode 100644 index 00000000..68974049 --- /dev/null +++ b/Core/MMKV_OSX.h @@ -0,0 +1,44 @@ +/* + * Tencent is pleased to support the open source community by making + * MMKV available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#include "MMKVPredef.h" + +#if defined(MMKV_IOS) && defined(__cplusplus) + +class MLockPtr { + size_t m_lockDownSize; + uint8_t *m_lockedPtr; + +public: + MLockPtr(void *ptr, size_t size); + + ~MLockPtr(); + + bool isLocked() const { + return (m_lockedPtr != nullptr); + } + + // just forbid it for possibly misuse + explicit MLockPtr(const MLockPtr &other) = delete; + MLockPtr &operator=(const MLockPtr &other) = delete; +}; + +#endif diff --git a/Core/MiniPBCoder.cpp b/Core/MiniPBCoder.cpp index 4d133865..933fe447 100644 --- a/Core/MiniPBCoder.cpp +++ b/Core/MiniPBCoder.cpp @@ -27,11 +27,11 @@ #include #include -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE # if __has_feature(objc_arc) # error This file must be compiled with MRC. Use -fno-objc-arc flag. # endif -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE using namespace std; @@ -64,7 +64,7 @@ void MiniPBCoder::writeRootObject() { m_outputData->writeUInt32(encodeItem->valueSize); break; } -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE case PBEncodeItemType_String: { m_outputData->writeString(*(encodeItem->value.strValue)); break; @@ -93,7 +93,7 @@ void MiniPBCoder::writeRootObject() { m_outputData->writeDouble(oDate.timeIntervalSince1970); break; } -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE case PBEncodeItemType_None: { MMKVError("%d", encodeItem->type); break; @@ -127,7 +127,7 @@ size_t MiniPBCoder::prepareObjectForEncode(const MMKVMap &map) { for (const auto &itr : map) { const auto &key = itr.first; const auto &value = itr.second; -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE if (key.length <= 0) { #else if (key.length() <= 0) { @@ -168,7 +168,7 @@ MMBuffer MiniPBCoder::getEncodeData(const MMKVMap &map) { return move(*m_outputBuffer); } -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE size_t MiniPBCoder::prepareObjectForEncode(const string &str) { m_encodeItems->push_back(PBEncodeItem()); @@ -319,7 +319,7 @@ vector MiniPBCoder::decodeSet(const MMBuffer &oData) { return oCoder.decodeOneSet(); } -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE void MiniPBCoder::decodeMap(MMKVMap &dic, const MMBuffer &oData, size_t size) { MiniPBCoder oCoder(&oData); diff --git a/Core/MiniPBCoder.h b/Core/MiniPBCoder.h index d79640cf..3c81b10b 100644 --- a/Core/MiniPBCoder.h +++ b/Core/MiniPBCoder.h @@ -58,7 +58,7 @@ class MiniPBCoder { void decodeOneMap(MMKVMap &dic, size_t size, bool greedy); -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE size_t prepareObjectForEncode(const std::string &str); size_t prepareObjectForEncode(const std::vector &vector); @@ -93,7 +93,7 @@ class MiniPBCoder { // decode as much data as possible before any error happens static void greedyDecodeMap(MMKVMap &dic, const MMBuffer &oData, size_t size = 0); -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE static std::string decodeString(const MMBuffer &oData); static MMBuffer decodeBytes(const MMBuffer &oData); diff --git a/Core/MiniPBCoder_OSX.cpp b/Core/MiniPBCoder_OSX.cpp index 23e942fe..dda97018 100644 --- a/Core/MiniPBCoder_OSX.cpp +++ b/Core/MiniPBCoder_OSX.cpp @@ -20,7 +20,7 @@ #include "MiniPBCoder.h" -#ifdef MMKV_IOS_OR_MAC +#ifdef MMKV_APPLE # include "CodedInputData.h" # include "CodedOutputData.h" @@ -189,4 +189,4 @@ bool MiniPBCoder::isCompatibleClass(Class cls) { } // namespace mmkv -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE diff --git a/Core/PBEncodeItem.hpp b/Core/PBEncodeItem.hpp index 7cd232c6..712223b4 100644 --- a/Core/PBEncodeItem.hpp +++ b/Core/PBEncodeItem.hpp @@ -35,7 +35,7 @@ enum PBEncodeItemType { PBEncodeItemType_None, PBEncodeItemType_Data, PBEncodeItemType_Container, -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE PBEncodeItemType_String, #else PBEncodeItemType_NSString, @@ -50,7 +50,7 @@ struct PBEncodeItem { uint32_t valueSize; union { const MMBuffer *bufferValue; -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE const std::string *strValue; #else void *objectValue; @@ -60,7 +60,7 @@ struct PBEncodeItem { PBEncodeItem() : type(PBEncodeItemType_None), compiledSize(0), valueSize(0) { memset(&value, 0, sizeof(value)); } -#ifndef MMKV_IOS_OR_MAC +#ifndef MMKV_APPLE // opt std::vector.push_back() on slow_path PBEncodeItem(PBEncodeItem &&other) = default; @@ -110,7 +110,7 @@ struct PBEncodeItem { } } -#endif // MMKV_IOS_OR_MAC +#endif // MMKV_APPLE }; } // namespace mmkv diff --git a/MMKV.podspec b/MMKV.podspec index b9264d30..a0274a16 100644 --- a/MMKV.podspec +++ b/MMKV.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "MMKV" - s.version = "1.1.0" + s.version = "1.1.1" s.summary = "MMKV is a cross-platform key-value storage framework developed by WeChat." s.description = <<-DESC @@ -22,7 +22,6 @@ Pod::Spec.new do |s| s.public_header_files = "iOS/MMKV/MMKV/MMKV.h", "iOS/MMKV/MMKV/MMKVHandler.h" s.framework = "CoreFoundation" - s.ios.frameworks = "UIKit" s.libraries = "z", "c++" s.requires_arc = true s.pod_target_xcconfig = { @@ -31,7 +30,7 @@ Pod::Spec.new do |s| "CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF" => "NO", } - s.dependency 'MMKVCore', '~> 1.1.0' + s.dependency 'MMKVCore', '~> 1.1.1' end diff --git a/MMKVAppExtension.podspec b/MMKVAppExtension.podspec new file mode 100644 index 00000000..ac2f9e99 --- /dev/null +++ b/MMKVAppExtension.podspec @@ -0,0 +1,37 @@ +Pod::Spec.new do |s| + + s.name = "MMKVAppExtension" + s.version = "1.1.1" + s.summary = "MMKV is a cross-platform key-value storage framework developed by WeChat." + s.module_name = "MMKVAppExtension" + + s.description = <<-DESC + The MMKV for iOS App Extensions. + MMKV is an efficient, complete, easy-to-use mobile key-value storage framework used in the WeChat application. + It can be a replacement for NSUserDefaults & SQLite. + DESC + + s.homepage = "https://github.com/Tencent/MMKV" + s.license = { :type => "BSD 3-Clause", :file => "LICENSE.TXT"} + s.author = { "guoling" => "guoling@tencent.com" } + + s.ios.deployment_target = "8.0" + + s.source = { :git => "https://github.com/Tencent/MMKV.git", :tag => "v#{s.version}" } + s.source_files = "iOS/MMKV/MMKV", "iOS/MMKV/MMKV/*.{h,mm,hpp}" + s.public_header_files = "iOS/MMKV/MMKV/MMKV.h", "iOS/MMKV/MMKV/MMKVHandler.h" + + s.framework = "CoreFoundation" + s.libraries = "z", "c++" + s.requires_arc = true + s.pod_target_xcconfig = { + "CLANG_CXX_LANGUAGE_STANDARD" => "gnu++17", + "CLANG_CXX_LIBRARY" => "libc++", + "CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF" => "NO", + "GCC_PREPROCESSOR_DEFINITIONS" => "MMKV_IOS_EXTENSION", + } + + s.dependency 'MMKVCore', '~> 1.1.1' + +end + diff --git a/MMKVCore.podspec b/MMKVCore.podspec index 3654b93f..492e207e 100644 --- a/MMKVCore.podspec +++ b/MMKVCore.podspec @@ -16,6 +16,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = "8.0" s.osx.deployment_target = "10.9" + s.watchos.deployment_target = "2.0" s.source = { :git => "https://github.com/Tencent/MMKV.git", :tag => "v#{s.version}" } s.source_files = "Core", "Core/*.{h,cpp,hpp}", "Core/aes/*", "Core/aes/openssl/*", "Core/crc32/*" diff --git a/MMKVWatchExtension.podspec b/MMKVWatchExtension.podspec new file mode 100644 index 00000000..6408629c --- /dev/null +++ b/MMKVWatchExtension.podspec @@ -0,0 +1,37 @@ +Pod::Spec.new do |s| + + s.name = "MMKVWatchExtension" + s.version = "1.1.1" + s.summary = "MMKV is a cross-platform key-value storage framework developed by WeChat." + s.module_name = "MMKVWatchExtension" + + s.description = <<-DESC + The MMKV for WatchOS App Extensions. + MMKV is an efficient, complete, easy-to-use mobile key-value storage framework used in the WeChat application. + It can be a replacement for NSUserDefaults & SQLite. + DESC + + s.homepage = "https://github.com/Tencent/MMKV" + s.license = { :type => "BSD 3-Clause", :file => "LICENSE.TXT"} + s.author = { "guoling" => "guoling@tencent.com" } + + s.watchos.deployment_target = "2.0" + + s.source = { :git => "https://github.com/Tencent/MMKV.git", :tag => "v#{s.version}" } + s.source_files = "iOS/MMKV/MMKV", "iOS/MMKV/MMKV/*.{h,mm,hpp}" + s.public_header_files = "iOS/MMKV/MMKV/MMKV.h", "iOS/MMKV/MMKV/MMKVHandler.h" + + s.framework = "CoreFoundation" + s.libraries = "z", "c++" + s.requires_arc = true + s.pod_target_xcconfig = { + "CLANG_CXX_LANGUAGE_STANDARD" => "gnu++17", + "CLANG_CXX_LIBRARY" => "libc++", + "CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF" => "NO", + "GCC_PREPROCESSOR_DEFINITIONS" => "MMKV_IOS_EXTENSION", + } + + s.dependency 'MMKVCore', '~> 1.1.1' + +end + diff --git a/POSIX/demo/UnitTest.cpp b/POSIX/demo/UnitTest.cpp index 8e2dfe23..b4733c27 100644 --- a/POSIX/demo/UnitTest.cpp +++ b/POSIX/demo/UnitTest.cpp @@ -20,7 +20,9 @@ #include "MMKV.h" #include +#include #include +#include #include #include #include @@ -125,7 +127,7 @@ void testUInt64(MMKV *mmkv) { template bool EqualWithAccuracy(T value1, T value2, T accuracy) { - return abs(value1 - value2) <= accuracy; + return fabs(value1 - value2) <= accuracy; } void testFloat(MMKV *mmkv) { diff --git a/README.md b/README.md index 00f10198..8864a570 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) [![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.1.0-brightgreen.svg)](https://github.com/Tencent/MMKV/releases) +[![Release Version](https://img.shields.io/badge/release-1.1.1-brightgreen.svg)](https://github.com/Tencent/MMKV/releases) [![Platform](https://img.shields.io/badge/Platform-%20Android%20%7C%20iOS%2FmacOS%20%7C%20Win32%20%7C%20POSIX-brightgreen.svg)](https://github.com/Tencent/MMKV/wiki/home) 中文版本请参看[这里](./readme_cn.md) @@ -28,8 +28,8 @@ Add the following lines to `build.gradle` on your app module: ```gradle dependencies { - implementation 'com.tencent:mmkv-static:1.1.0' - // replace "1.1.0" with any available version + implementation 'com.tencent:mmkv-static:1.1.1' + // replace "1.1.1" with any available version } ``` diff --git a/iOS/MMKV/MMKV.xcodeproj/project.pbxproj b/iOS/MMKV/MMKV.xcodeproj/project.pbxproj index 839e4769..22108d31 100644 --- a/iOS/MMKV/MMKV.xcodeproj/project.pbxproj +++ b/iOS/MMKV/MMKV.xcodeproj/project.pbxproj @@ -24,6 +24,12 @@ CBC1A90C20DA97DF00AD5087 /* MMKV.h in Headers */ = {isa = PBXBuildFile; fileRef = CB1FD4942046984F00931B5F /* MMKV.h */; settings = {ATTRIBUTES = (Public, ); }; }; CBDF32902192C0000028DB4D /* MMKVHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = CBDF328F2192C0000028DB4D /* MMKVHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; CBDF32912192C0340028DB4D /* MMKVHandler.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CBDF328F2192C0000028DB4D /* MMKVHandler.h */; }; + CBF19040243D706D001C82ED /* libMMKV.mm in Sources */ = {isa = PBXBuildFile; fileRef = CB1FD4952046984F00931B5F /* libMMKV.mm */; }; + CBF19042243D706D001C82ED /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = CBC1A90320DA94A000AD5087 /* libz.tbd */; }; + CBF19044243D706D001C82ED /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB1FD4CC2046ACBC00931B5F /* Foundation.framework */; }; + CBF19046243D706D001C82ED /* MMKVHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = CBDF328F2192C0000028DB4D /* MMKVHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CBF19047243D706D001C82ED /* MMKV.h in Headers */ = {isa = PBXBuildFile; fileRef = CB1FD4942046984F00931B5F /* MMKV.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CBF1907F243D7627001C82ED /* libMMKVCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CBF19079243D70FD001C82ED /* libMMKVCore.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -55,6 +61,13 @@ remoteGlobalIDString = CB9563D723AB2D9500ACCD39; remoteInfo = Core; }; + CBF19078243D70FD001C82ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CB6F6BFC23ACCF47000351EA /* Core.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = CBF19076243D70BA001C82ED; + remoteInfo = MMKVWatchCore; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -72,9 +85,9 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - CB1E0651242B84D800F2FD42 /* MMKVAppExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MMKVAppExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + CB1E0651242B84D800F2FD42 /* MMKV.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MMKV.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CB1E0652242B84D800F2FD42 /* MMKV copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "MMKV copy-Info.plist"; path = "/Users/lingol/Developer/mmkv/iOS/MMKV/MMKV copy-Info.plist"; sourceTree = ""; }; - CB1FD4912046984F00931B5F /* libMMKV Static.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libMMKV Static.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + CB1FD4912046984F00931B5F /* libMMKV.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMMKV.a; sourceTree = BUILT_PRODUCTS_DIR; }; CB1FD4942046984F00931B5F /* MMKV.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MMKV.h; sourceTree = ""; }; CB1FD4952046984F00931B5F /* libMMKV.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = libMMKV.mm; sourceTree = ""; }; CB1FD4CC2046ACBC00931B5F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -84,6 +97,8 @@ CBC1A90320DA94A000AD5087 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; CBC1A90A20DA95E100AD5087 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; CBDF328F2192C0000028DB4D /* MMKVHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MMKVHandler.h; sourceTree = ""; }; + CBF1904C243D706D001C82ED /* MMKV.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MMKV.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + CBF1904D243D706D001C82ED /* MMKVAppExtension copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "MMKVAppExtension copy-Info.plist"; path = "/Users/lingol/Developer/mmkv/iOS/MMKV/MMKVAppExtension copy-Info.plist"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -116,6 +131,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CBF19041243D706D001C82ED /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CBF1907F243D7627001C82ED /* libMMKVCore.a in Frameworks */, + CBF19042243D706D001C82ED /* libz.tbd in Frameworks */, + CBF19044243D706D001C82ED /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -127,15 +152,17 @@ CB1FD4922046984F00931B5F /* Products */, CB1FD4C92046ACB200931B5F /* Frameworks */, CB1E0652242B84D800F2FD42 /* MMKV copy-Info.plist */, + CBF1904D243D706D001C82ED /* MMKVAppExtension copy-Info.plist */, ); sourceTree = ""; }; CB1FD4922046984F00931B5F /* Products */ = { isa = PBXGroup; children = ( - CB1FD4912046984F00931B5F /* libMMKV Static.a */, + CB1FD4912046984F00931B5F /* libMMKV.a */, CBC1A8F620DA946200AD5087 /* MMKV.framework */, - CB1E0651242B84D800F2FD42 /* MMKVAppExtension.framework */, + CB1E0651242B84D800F2FD42 /* MMKV.framework */, + CBF1904C243D706D001C82ED /* MMKV.framework */, ); name = Products; sourceTree = ""; @@ -165,6 +192,7 @@ isa = PBXGroup; children = ( CB6F6C0123ACCF47000351EA /* libMMKVCore.a */, + CBF19079243D70FD001C82ED /* libMMKVCore.a */, ); name = Products; sourceTree = ""; @@ -198,6 +226,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CBF19045243D706D001C82ED /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + CBF19046243D706D001C82ED /* MMKVHandler.h in Headers */, + CBF19047243D706D001C82ED /* MMKV.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ @@ -217,7 +254,7 @@ ); name = MMKVAppExtension; productName = MMKV; - productReference = CB1E0651242B84D800F2FD42 /* MMKVAppExtension.framework */; + productReference = CB1E0651242B84D800F2FD42 /* MMKV.framework */; productType = "com.apple.product-type.framework"; }; CB1FD4902046984F00931B5F /* MMKV Static */ = { @@ -235,7 +272,7 @@ ); name = "MMKV Static"; productName = MMKV; - productReference = CB1FD4912046984F00931B5F /* libMMKV Static.a */; + productReference = CB1FD4912046984F00931B5F /* libMMKV.a */; productType = "com.apple.product-type.library.static"; }; CBC1A8F520DA946200AD5087 /* MMKV */ = { @@ -257,6 +294,24 @@ productReference = CBC1A8F620DA946200AD5087 /* MMKV.framework */; productType = "com.apple.product-type.framework"; }; + CBF1903C243D706D001C82ED /* MMKVWatchExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = CBF19049243D706D001C82ED /* Build configuration list for PBXNativeTarget "MMKVWatchExtension" */; + buildPhases = ( + CBF1903F243D706D001C82ED /* Sources */, + CBF19041243D706D001C82ED /* Frameworks */, + CBF19045243D706D001C82ED /* Headers */, + CBF19048243D706D001C82ED /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MMKVWatchExtension; + productName = MMKV; + productReference = CBF1904C243D706D001C82ED /* MMKV.framework */; + productType = "com.apple.product-type.framework"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -277,6 +332,9 @@ CreatedOnToolsVersion = 9.4.1; ProvisioningStyle = Automatic; }; + CBF1903C243D706D001C82ED = { + ProvisioningStyle = Automatic; + }; }; }; buildConfigurationList = CB1FD48C2046984F00931B5F /* Build configuration list for PBXProject "MMKV" */; @@ -301,6 +359,7 @@ CB1FD4902046984F00931B5F /* MMKV Static */, CBC1A8F520DA946200AD5087 /* MMKV */, CB1E0641242B84D800F2FD42 /* MMKVAppExtension */, + CBF1903C243D706D001C82ED /* MMKVWatchExtension */, ); }; /* End PBXProject section */ @@ -313,6 +372,13 @@ remoteRef = CB6F6C0023ACCF47000351EA /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + CBF19079243D70FD001C82ED /* libMMKVCore.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libMMKVCore.a; + remoteRef = CBF19078243D70FD001C82ED /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ @@ -330,6 +396,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CBF19048243D706D001C82ED /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -357,6 +430,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CBF1903F243D706D001C82ED /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CBF19040243D706D001C82ED /* libMMKV.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -393,13 +474,18 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + MMKV_IOS_EXTENSION, + ); GENERATE_MASTER_OBJECT_FILE = NO; INFOPLIST_FILE = "MMKV copy-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.9; - MARKETING_VERSION = 1.1.0; + MARKETING_VERSION = 1.1.1; "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "-framework", UIKit, @@ -409,8 +495,7 @@ UIKit, ); PRODUCT_BUNDLE_IDENTIFIER = com.tencent.MMKVAppExtension; - PRODUCT_MODULE_NAME = MMKV; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = MMKV; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VALID_ARCHS = "arm64 armv7 arm64e"; @@ -435,13 +520,17 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NDEBUG=1", + MMKV_IOS_EXTENSION, + ); GENERATE_MASTER_OBJECT_FILE = NO; INFOPLIST_FILE = "MMKV copy-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.9; - MARKETING_VERSION = 1.1.0; + MARKETING_VERSION = 1.1.1; "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "-framework", UIKit, @@ -451,8 +540,7 @@ UIKit, ); PRODUCT_BUNDLE_IDENTIFIER = com.tencent.MMKVAppExtension; - PRODUCT_MODULE_NAME = MMKV; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = MMKV; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VALID_ARCHS = "arm64 armv7 arm64e"; @@ -595,7 +683,7 @@ "-framework", UIKit, ); - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = MMKV; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VALID_ARCHS = "arm64 armv7"; @@ -620,7 +708,7 @@ "-framework", UIKit, ); - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = MMKV; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VALID_ARCHS = "arm64 armv7"; @@ -648,7 +736,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.9; - MARKETING_VERSION = 1.1.0; + MARKETING_VERSION = 1.1.1; "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "-framework", UIKit, @@ -688,7 +776,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.9; - MARKETING_VERSION = 1.1.0; + MARKETING_VERSION = 1.1.1; "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "-framework", UIKit, @@ -708,6 +796,101 @@ }; name = Release; }; + CBF1904A243D706D001C82ED /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + MMKV_IOS_EXTENSION, + ); + GENERATE_MASTER_OBJECT_FILE = NO; + INFOPLIST_FILE = "MMKVAppExtension copy-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MARKETING_VERSION = 1.1.1; + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "-framework", + UIKit, + ); + "OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( + "-framework", + UIKit, + ); + PRODUCT_BUNDLE_IDENTIFIER = com.tencent.MMKVWatchExtension; + PRODUCT_NAME = MMKV; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "watchsimulator watchos"; + TARGETED_DEVICE_FAMILY = 4; + VALID_ARCHS = "armv7k arm64_32"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + WATCHOS_DEPLOYMENT_TARGET = 2.0; + }; + name = Debug; + }; + CBF1904B243D706D001C82ED /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NDEBUG=1", + MMKV_IOS_EXTENSION, + ); + GENERATE_MASTER_OBJECT_FILE = NO; + INFOPLIST_FILE = "MMKVAppExtension copy-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MARKETING_VERSION = 1.1.1; + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "-framework", + UIKit, + ); + "OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( + "-framework", + UIKit, + ); + PRODUCT_BUNDLE_IDENTIFIER = com.tencent.MMKVWatchExtension; + PRODUCT_NAME = MMKV; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "watchsimulator watchos"; + TARGETED_DEVICE_FAMILY = 4; + VALID_ARCHS = "armv7k arm64_32"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + WATCHOS_DEPLOYMENT_TARGET = 2.0; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -747,6 +930,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + CBF19049243D706D001C82ED /* Build configuration list for PBXNativeTarget "MMKVWatchExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CBF1904A243D706D001C82ED /* Debug */, + CBF1904B243D706D001C82ED /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = CB1FD4892046984F00931B5F /* Project object */; diff --git a/iOS/MMKV/MMKV.xcodeproj/xcshareddata/xcschemes/MMKV Static.xcscheme b/iOS/MMKV/MMKV.xcodeproj/xcshareddata/xcschemes/MMKV Static.xcscheme index 6a822e2a..8dadde0b 100644 --- a/iOS/MMKV/MMKV.xcodeproj/xcshareddata/xcschemes/MMKV Static.xcscheme +++ b/iOS/MMKV/MMKV.xcodeproj/xcshareddata/xcschemes/MMKV Static.xcscheme @@ -15,7 +15,7 @@ @@ -44,7 +44,7 @@ @@ -60,7 +60,7 @@ diff --git a/iOS/MMKV/MMKV/MMKV.h b/iOS/MMKV/MMKV/MMKV.h index 0d0cc3a8..973c23ac 100644 --- a/iOS/MMKV/MMKV/MMKV.h +++ b/iOS/MMKV/MMKV/MMKV.h @@ -76,7 +76,7 @@ NS_ASSUME_NONNULL_BEGIN + (nullable instancetype)mmkvWithID:(NSString *)mmapID cryptKey:(nullable NSData *)cryptKey relativePath:(nullable NSString *)relativePath NS_SWIFT_NAME(init(mmapID:cryptKey:relativePath:)); // you can call this on applicationWillTerminate, it's totally fine if you don't call -+ (void)onExit; ++ (void)onAppTerminate; + (NSString *)mmkvBasePath; diff --git a/iOS/MMKV/MMKV/libMMKV.mm b/iOS/MMKV/MMKV/libMMKV.mm index 67908d2e..e72d40e2 100644 --- a/iOS/MMKV/MMKV/libMMKV.mm +++ b/iOS/MMKV/MMKV/libMMKV.mm @@ -38,6 +38,10 @@ static NSString *g_basePath = nil; static NSString *g_groupPath = nil; +#if defined(MMKV_IOS) && !defined(MMKV_IOS_EXTENSION) +static BOOL g_isRunningInAppExtension = NO; +#endif + static void LogHandler(mmkv::MMKVLogLevel level, const char *file, int line, const char *function, NSString *message); static mmkv::MMKVRecoverStrategic ErrorHandler(const string &mmapID, mmkv::MMKVErrorType errorType); static void ContentChangeHandler(const string &mmapID); @@ -60,13 +64,19 @@ + (void)initialize { mmkv::MMKV::minimalInit([self mmkvBasePath].UTF8String); #if defined(MMKV_IOS) && !defined(MMKV_IOS_EXTENSION) - auto appState = [UIApplication sharedApplication].applicationState; - auto isInBackground = (appState == UIApplicationStateBackground); - mmkv::MMKV::setIsInBackground(isInBackground); - MMKVInfo("appState:%ld", (long) appState); - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil]; + // just in case someone forget to set the MMKV_IOS_EXTENSION macro + if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) { + g_isRunningInAppExtension = YES; + } + if (!g_isRunningInAppExtension) { + auto appState = [UIApplication sharedApplication].applicationState; + auto isInBackground = (appState == UIApplicationStateBackground); + mmkv::MMKV::setIsInBackground(isInBackground); + MMKVInfo("appState:%ld", (long) appState); + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil]; + } #endif } } @@ -183,10 +193,12 @@ - (instancetype)initWithMMapID:(NSString *)mmapID cryptKey:(NSData *)cryptKey re m_mmapID = [NSString stringWithUTF8String:m_mmkv->mmapID().c_str()]; #if defined(MMKV_IOS) && !defined(MMKV_IOS_EXTENSION) - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(onMemoryWarning) - name:UIApplicationDidReceiveMemoryWarningNotification - object:nil]; + if (!g_isRunningInAppExtension) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(onMemoryWarning) + name:UIApplicationDidReceiveMemoryWarningNotification + object:nil]; + } #endif } return self; @@ -466,7 +478,7 @@ - (void)checkContentChanged { m_mmkv->checkContentChanged(); } -+ (void)onExit { ++ (void)onAppTerminate { SCOPED_LOCK(g_lock); [g_instanceDic removeAllObjects]; diff --git a/iOS/MMKV/MMKVAppExtension copy-Info.plist b/iOS/MMKV/MMKVAppExtension copy-Info.plist new file mode 100644 index 00000000..fcd36391 --- /dev/null +++ b/iOS/MMKV/MMKVAppExtension copy-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/iOS/MMKVDemo/MMKVDemo.xcodeproj/project.pbxproj b/iOS/MMKVDemo/MMKVDemo.xcodeproj/project.pbxproj index 8161d51e..b4fa3e40 100644 --- a/iOS/MMKVDemo/MMKVDemo.xcodeproj/project.pbxproj +++ b/iOS/MMKVDemo/MMKVDemo.xcodeproj/project.pbxproj @@ -10,7 +10,6 @@ CB0DCC72242B57FC009AFE59 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = CBD5359823B4718200D3A404 /* libc++.tbd */; }; CB1E0659242B8E3F00F2FD42 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = CB1FD4D12046AF2300931B5F /* libz.tbd */; }; CB1E065F242B8E4A00F2FD42 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = CB1E065E242B8E4A00F2FD42 /* libz.tbd */; }; - CB1E0660242B8E5F00F2FD42 /* MMKVAppExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB1E065D242B8E3F00F2FD42 /* MMKVAppExtension.framework */; }; CB1FD42520455E2D00931B5F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CB1FD42420455E2D00931B5F /* AppDelegate.m */; }; CB1FD42820455E2D00931B5F /* ViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CB1FD42720455E2D00931B5F /* ViewController.mm */; }; CB1FD42B20455E2D00931B5F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CB1FD42920455E2D00931B5F /* Main.storyboard */; }; @@ -19,35 +18,34 @@ CB1FD43320455E2D00931B5F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CB1FD43220455E2D00931B5F /* main.m */; }; CB36F24C20F8A20C009AF46F /* MMKVDemoTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CB36F24B20F8A20C009AF46F /* MMKVDemoTests.mm */; }; CB36F25A20F8D728009AF46F /* MMKVPerformanceTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = CB36F25920F8D728009AF46F /* MMKVPerformanceTest.mm */; }; + CB467FBC2431EE3000FD7421 /* MMKVAppExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB467FBB2431EE2D00FD7421 /* MMKVAppExtension.framework */; }; CB6D44CC23B3A44400F369AA /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB6D44CB23B3A44400F369AA /* NotificationCenter.framework */; }; CB6D44D023B3A44400F369AA /* TodayViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CB6D44CF23B3A44400F369AA /* TodayViewController.m */; }; CB6D44D323B3A44400F369AA /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CB6D44D123B3A44400F369AA /* MainInterface.storyboard */; }; CB6D44D723B3A44400F369AA /* MMKVTodayExtensionDemo.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = CB6D44CA23B3A44400F369AA /* MMKVTodayExtensionDemo.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; CB9C2731215E5DF000448B6C /* libMMKV Static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CB1FD4B52046994D00931B5F /* libMMKV Static.a */; }; CB9F963920FCA7C500A1C14C /* DemoSwiftUsage.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB9F963820FCA7C500A1C14C /* DemoSwiftUsage.swift */; }; + CBB306612435E8F200CB593E /* ViewController+TestCaseBad.mm in Sources */ = {isa = PBXBuildFile; fileRef = CBB306602435E8F200CB593E /* ViewController+TestCaseBad.mm */; }; CBB6C823215CDB9500487192 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CBB6C822215CDB9500487192 /* AppDelegate.m */; }; CBB6C826215CDB9500487192 /* ViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CBB6C825215CDB9500487192 /* ViewController.mm */; }; CBB6C828215CDB9600487192 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CBB6C827215CDB9600487192 /* Assets.xcassets */; }; CBB6C82B215CDB9600487192 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CBB6C829215CDB9600487192 /* Main.storyboard */; }; CBB6C82E215CDB9600487192 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CBB6C82D215CDB9600487192 /* main.m */; }; CBD5359023B46E8500D3A404 /* libMMKV Static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CB1FD4B52046994D00931B5F /* libMMKV Static.a */; }; + CBF19016243D6F59001C82ED /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CBF19014243D6F59001C82ED /* Interface.storyboard */; }; + CBF19018243D6F5A001C82ED /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CBF19017243D6F5A001C82ED /* Assets.xcassets */; }; + CBF1901F243D6F5A001C82ED /* WatchApp Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = CBF1901E243D6F5A001C82ED /* WatchApp Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + CBF19025243D6F5A001C82ED /* InterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = CBF19024243D6F5A001C82ED /* InterfaceController.m */; }; + CBF19028243D6F5A001C82ED /* ExtensionDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = CBF19027243D6F5A001C82ED /* ExtensionDelegate.mm */; }; + CBF1902B243D6F5A001C82ED /* NotificationController.m in Sources */ = {isa = PBXBuildFile; fileRef = CBF1902A243D6F5A001C82ED /* NotificationController.m */; }; + CBF1902D243D6F5A001C82ED /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CBF1902C243D6F5A001C82ED /* Assets.xcassets */; }; + CBF19032243D6F5A001C82ED /* WatchApp.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = CBF19012243D6F59001C82ED /* WatchApp.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + CBF1907E243D71E8001C82ED /* MMKVWatchExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBF1907C243D7116001C82ED /* MMKVWatchExtension.framework */; }; + CBF190AD243D7869001C82ED /* MMKVAppExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB467FBB2431EE2D00FD7421 /* MMKVAppExtension.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + CBF190AF243D78F3001C82ED /* MMKVWatchExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBF1907C243D7116001C82ED /* MMKVWatchExtension.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - CB0DCC65242B52E4009AFE59 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = CB1FD4B02046994C00931B5F /* MMKV.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = CB1FD4902046984F00931B5F; - remoteInfo = "MMKV Static"; - }; - CB1E065C242B8E3F00F2FD42 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = CB1FD4B02046994C00931B5F /* MMKV.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = CB1E0651242B84D800F2FD42; - remoteInfo = MMKVAppExtension; - }; CB1FD4B42046994D00931B5F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = CB1FD4B02046994C00931B5F /* MMKV.xcodeproj */; @@ -69,6 +67,13 @@ remoteGlobalIDString = CBC1A8F620DA946200AD5087; remoteInfo = MMKV; }; + CB467FBA2431EE2D00FD7421 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CB1FD4B02046994C00931B5F /* MMKV.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = CB1E0651242B84D800F2FD42; + remoteInfo = MMKVAppExtension; + }; CB6D44D523B3A44400F369AA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = CB1FD41820455E2D00931B5F /* Project object */; @@ -83,6 +88,13 @@ remoteGlobalIDString = CB1FD4902046984F00931B5F; remoteInfo = "MMKV Static"; }; + CBB306642435EC6000CB593E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CB1FD4B02046994C00931B5F /* MMKV.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = CB1E0641242B84D800F2FD42; + remoteInfo = MMKVAppExtension; + }; CBD5358E23B46E7C00D3A404 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = CB1FD4B02046994C00931B5F /* MMKV.xcodeproj */; @@ -90,6 +102,27 @@ remoteGlobalIDString = CB1FD4902046984F00931B5F; remoteInfo = "MMKV Static"; }; + CBF19020243D6F5A001C82ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CB1FD41820455E2D00931B5F /* Project object */; + proxyType = 1; + remoteGlobalIDString = CBF1901D243D6F5A001C82ED; + remoteInfo = "WatchApp Extension"; + }; + CBF19030243D6F5A001C82ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CB1FD41820455E2D00931B5F /* Project object */; + proxyType = 1; + remoteGlobalIDString = CBF19011243D6F59001C82ED; + remoteInfo = WatchApp; + }; + CBF1907B243D7116001C82ED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CB1FD4B02046994C00931B5F /* MMKV.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = CBF1904C243D706D001C82ED; + remoteInfo = MMKVWatchExtension; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -104,6 +137,50 @@ name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; }; + CBF19033243D6F5A001C82ED /* Embed Watch Content */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; + dstSubfolderSpec = 16; + files = ( + CBF19032243D6F5A001C82ED /* WatchApp.app in Embed Watch Content */, + ); + name = "Embed Watch Content"; + runOnlyForDeploymentPostprocessing = 0; + }; + CBF19036243D6F5A001C82ED /* Embed App Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + CBF1901F243D6F5A001C82ED /* WatchApp Extension.appex in Embed App Extensions */, + ); + name = "Embed App Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; + CBF190AC243D7853001C82ED /* Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + CBF190AD243D7869001C82ED /* MMKVAppExtension.framework in Frameworks */, + ); + name = Frameworks; + runOnlyForDeploymentPostprocessing = 0; + }; + CBF190AE243D78D4001C82ED /* Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + CBF190AF243D78F3001C82ED /* MMKVWatchExtension.framework in Frameworks */, + ); + name = Frameworks; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -135,6 +212,8 @@ CB9C2732215E5ECC00448B6C /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; }; CB9F963720FCA7C400A1C14C /* MMKVDemo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MMKVDemo-Bridging-Header.h"; sourceTree = ""; }; CB9F963820FCA7C500A1C14C /* DemoSwiftUsage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoSwiftUsage.swift; sourceTree = ""; }; + CBB3065F2435E8F200CB593E /* ViewController+TestCaseBad.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ViewController+TestCaseBad.h"; sourceTree = ""; }; + CBB306602435E8F200CB593E /* ViewController+TestCaseBad.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "ViewController+TestCaseBad.mm"; sourceTree = ""; }; CBB6C81F215CDB9500487192 /* MMKVMacDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MMKVMacDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; CBB6C821215CDB9500487192 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; CBB6C822215CDB9500487192 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -146,6 +225,20 @@ CBB6C82D215CDB9600487192 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; CBB6C82F215CDB9600487192 /* MMKVMacDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MMKVMacDemo.entitlements; sourceTree = ""; }; CBD5359823B4718200D3A404 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; + CBF19012243D6F59001C82ED /* WatchApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WatchApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + CBF19015243D6F59001C82ED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; + CBF19017243D6F5A001C82ED /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + CBF19019243D6F5A001C82ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + CBF1901E243D6F5A001C82ED /* WatchApp Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "WatchApp Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; + CBF19023243D6F5A001C82ED /* InterfaceController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InterfaceController.h; sourceTree = ""; }; + CBF19024243D6F5A001C82ED /* InterfaceController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InterfaceController.m; sourceTree = ""; }; + CBF19026243D6F5A001C82ED /* ExtensionDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExtensionDelegate.h; sourceTree = ""; }; + CBF19027243D6F5A001C82ED /* ExtensionDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ExtensionDelegate.mm; sourceTree = ""; }; + CBF19029243D6F5A001C82ED /* NotificationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationController.h; sourceTree = ""; }; + CBF1902A243D6F5A001C82ED /* NotificationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationController.m; sourceTree = ""; }; + CBF1902C243D6F5A001C82ED /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + CBF1902E243D6F5A001C82ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + CBF1902F243D6F5A001C82ED /* PushNotificationPayload.apns */ = {isa = PBXFileReference; lastKnownFileType = text; path = PushNotificationPayload.apns; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -169,7 +262,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - CB1E0660242B8E5F00F2FD42 /* MMKVAppExtension.framework in Frameworks */, + CB467FBC2431EE3000FD7421 /* MMKVAppExtension.framework in Frameworks */, CB0DCC72242B57FC009AFE59 /* libc++.tbd in Frameworks */, CB6D44CC23B3A44400F369AA /* NotificationCenter.framework in Frameworks */, ); @@ -184,6 +277,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CBF1901B243D6F5A001C82ED /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CBF1907E243D71E8001C82ED /* MMKVWatchExtension.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -195,6 +296,8 @@ CB36F24A20F8A20C009AF46F /* MMKVDemoTests */, CBB6C820215CDB9500487192 /* MMKVMacDemo */, CB6D44CD23B3A44400F369AA /* MMKVTodayExtensionDemo */, + CBF19013243D6F59001C82ED /* WatchApp */, + CBF19022243D6F5A001C82ED /* WatchApp Extension */, CB1FD42120455E2D00931B5F /* Products */, CB1FD45720455F3500931B5F /* Frameworks */, ); @@ -207,6 +310,8 @@ CB36F24920F8A20C009AF46F /* MMKVDemoTests.xctest */, CBB6C81F215CDB9500487192 /* MMKVMacDemo.app */, CB6D44CA23B3A44400F369AA /* MMKVTodayExtensionDemo.appex */, + CBF19012243D6F59001C82ED /* WatchApp.app */, + CBF1901E243D6F5A001C82ED /* WatchApp Extension.appex */, ); name = Products; sourceTree = ""; @@ -226,6 +331,8 @@ CB9F963720FCA7C400A1C14C /* MMKVDemo-Bridging-Header.h */, CB1FD42620455E2D00931B5F /* ViewController.h */, CB1FD42720455E2D00931B5F /* ViewController.mm */, + CBB3065F2435E8F200CB593E /* ViewController+TestCaseBad.h */, + CBB306602435E8F200CB593E /* ViewController+TestCaseBad.mm */, ); path = MMKVDemo; sourceTree = ""; @@ -247,7 +354,8 @@ children = ( CB1FD4B52046994D00931B5F /* libMMKV Static.a */, CB36F25420F8A20C009AF46F /* MMKV.framework */, - CB1E065D242B8E3F00F2FD42 /* MMKVAppExtension.framework */, + CB467FBB2431EE2D00FD7421 /* MMKVAppExtension.framework */, + CBF1907C243D7116001C82ED /* MMKVWatchExtension.framework */, ); name = Products; sourceTree = ""; @@ -290,6 +398,32 @@ path = MMKVMacDemo; sourceTree = ""; }; + CBF19013243D6F59001C82ED /* WatchApp */ = { + isa = PBXGroup; + children = ( + CBF19014243D6F59001C82ED /* Interface.storyboard */, + CBF19017243D6F5A001C82ED /* Assets.xcassets */, + CBF19019243D6F5A001C82ED /* Info.plist */, + ); + path = WatchApp; + sourceTree = ""; + }; + CBF19022243D6F5A001C82ED /* WatchApp Extension */ = { + isa = PBXGroup; + children = ( + CBF19023243D6F5A001C82ED /* InterfaceController.h */, + CBF19024243D6F5A001C82ED /* InterfaceController.m */, + CBF19026243D6F5A001C82ED /* ExtensionDelegate.h */, + CBF19027243D6F5A001C82ED /* ExtensionDelegate.mm */, + CBF19029243D6F5A001C82ED /* NotificationController.h */, + CBF1902A243D6F5A001C82ED /* NotificationController.m */, + CBF1902C243D6F5A001C82ED /* Assets.xcassets */, + CBF1902E243D6F5A001C82ED /* Info.plist */, + CBF1902F243D6F5A001C82ED /* PushNotificationPayload.apns */, + ); + path = "WatchApp Extension"; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -301,12 +435,14 @@ CB1FD41D20455E2D00931B5F /* Frameworks */, CB1FD41E20455E2D00931B5F /* Resources */, CB6D44DB23B3A44400F369AA /* Embed App Extensions */, + CBF19033243D6F5A001C82ED /* Embed Watch Content */, ); buildRules = ( ); dependencies = ( CBD5358F23B46E7C00D3A404 /* PBXTargetDependency */, CB6D44D623B3A44400F369AA /* PBXTargetDependency */, + CBF19031243D6F5A001C82ED /* PBXTargetDependency */, ); name = MMKVDemo; productName = MMKVDemo; @@ -338,11 +474,12 @@ CB6D44C623B3A44400F369AA /* Sources */, CB6D44C723B3A44400F369AA /* Frameworks */, CB6D44C823B3A44400F369AA /* Resources */, + CBF190AC243D7853001C82ED /* Frameworks */, ); buildRules = ( ); dependencies = ( - CB0DCC66242B52E4009AFE59 /* PBXTargetDependency */, + CBB306652435EC6000CB593E /* PBXTargetDependency */, ); name = MMKVTodayExtensionDemo; productName = MMKVTodayExtensionDemo; @@ -367,6 +504,41 @@ productReference = CBB6C81F215CDB9500487192 /* MMKVMacDemo.app */; productType = "com.apple.product-type.application"; }; + CBF19011243D6F59001C82ED /* WatchApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = CBF1903B243D6F5A001C82ED /* Build configuration list for PBXNativeTarget "WatchApp" */; + buildPhases = ( + CBF19010243D6F59001C82ED /* Resources */, + CBF19036243D6F5A001C82ED /* Embed App Extensions */, + ); + buildRules = ( + ); + dependencies = ( + CBF19021243D6F5A001C82ED /* PBXTargetDependency */, + ); + name = WatchApp; + productName = WatchApp; + productReference = CBF19012243D6F59001C82ED /* WatchApp.app */; + productType = "com.apple.product-type.application.watchapp2"; + }; + CBF1901D243D6F5A001C82ED /* WatchApp Extension */ = { + isa = PBXNativeTarget; + buildConfigurationList = CBF1903A243D6F5A001C82ED /* Build configuration list for PBXNativeTarget "WatchApp Extension" */; + buildPhases = ( + CBF1901A243D6F5A001C82ED /* Sources */, + CBF1901B243D6F5A001C82ED /* Frameworks */, + CBF1901C243D6F5A001C82ED /* Resources */, + CBF190AE243D78D4001C82ED /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "WatchApp Extension"; + productName = "WatchApp Extension"; + productReference = CBF1901E243D6F5A001C82ED /* WatchApp Extension.appex */; + productType = "com.apple.product-type.watchkit2-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -399,6 +571,14 @@ CreatedOnToolsVersion = 10.0; ProvisioningStyle = Automatic; }; + CBF19011243D6F59001C82ED = { + CreatedOnToolsVersion = 11.4; + ProvisioningStyle = Automatic; + }; + CBF1901D243D6F5A001C82ED = { + CreatedOnToolsVersion = 11.4; + ProvisioningStyle = Automatic; + }; }; }; buildConfigurationList = CB1FD41B20455E2D00931B5F /* Build configuration list for PBXProject "MMKVDemo" */; @@ -424,18 +604,13 @@ CB36F24820F8A20C009AF46F /* MMKVDemoTests */, CBB6C81E215CDB9500487192 /* MMKVMacDemo */, CB6D44C923B3A44400F369AA /* MMKVTodayExtensionDemo */, + CBF19011243D6F59001C82ED /* WatchApp */, + CBF1901D243D6F5A001C82ED /* WatchApp Extension */, ); }; /* End PBXProject section */ /* Begin PBXReferenceProxy section */ - CB1E065D242B8E3F00F2FD42 /* MMKVAppExtension.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = MMKVAppExtension.framework; - remoteRef = CB1E065C242B8E3F00F2FD42 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; CB1FD4B52046994D00931B5F /* libMMKV Static.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -450,6 +625,20 @@ remoteRef = CB36F25320F8A20C009AF46F /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + CB467FBB2431EE2D00FD7421 /* MMKVAppExtension.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = MMKVAppExtension.framework; + remoteRef = CB467FBA2431EE2D00FD7421 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CBF1907C243D7116001C82ED /* MMKVWatchExtension.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = MMKVWatchExtension.framework; + remoteRef = CBF1907B243D7116001C82ED /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ @@ -487,6 +676,23 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CBF19010243D6F59001C82ED /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CBF19018243D6F5A001C82ED /* Assets.xcassets in Resources */, + CBF19016243D6F59001C82ED /* Interface.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CBF1901C243D6F5A001C82ED /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CBF1902D243D6F5A001C82ED /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -495,6 +701,7 @@ buildActionMask = 2147483647; files = ( CB1FD42820455E2D00931B5F /* ViewController.mm in Sources */, + CBB306612435E8F200CB593E /* ViewController+TestCaseBad.mm in Sources */, CB1FD43320455E2D00931B5F /* main.m in Sources */, CB9F963920FCA7C500A1C14C /* DemoSwiftUsage.swift in Sources */, CB1FD42520455E2D00931B5F /* AppDelegate.m in Sources */, @@ -528,14 +735,19 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + CBF1901A243D6F5A001C82ED /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CBF19028243D6F5A001C82ED /* ExtensionDelegate.mm in Sources */, + CBF19025243D6F5A001C82ED /* InterfaceController.m in Sources */, + CBF1902B243D6F5A001C82ED /* NotificationController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - CB0DCC66242B52E4009AFE59 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "MMKV Static"; - targetProxy = CB0DCC65242B52E4009AFE59 /* PBXContainerItemProxy */; - }; CB36F24F20F8A20C009AF46F /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = CB1FD41F20455E2D00931B5F /* MMKVDemo */; @@ -551,11 +763,26 @@ name = "MMKV Static"; targetProxy = CB9C272F215E5D2400448B6C /* PBXContainerItemProxy */; }; + CBB306652435EC6000CB593E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = MMKVAppExtension; + targetProxy = CBB306642435EC6000CB593E /* PBXContainerItemProxy */; + }; CBD5358F23B46E7C00D3A404 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "MMKV Static"; targetProxy = CBD5358E23B46E7C00D3A404 /* PBXContainerItemProxy */; }; + CBF19021243D6F5A001C82ED /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = CBF1901D243D6F5A001C82ED /* WatchApp Extension */; + targetProxy = CBF19020243D6F5A001C82ED /* PBXContainerItemProxy */; + }; + CBF19031243D6F5A001C82ED /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = CBF19011243D6F59001C82ED /* WatchApp */; + targetProxy = CBF19030243D6F5A001C82ED /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -591,6 +818,14 @@ name = Main.storyboard; sourceTree = ""; }; + CBF19014243D6F59001C82ED /* Interface.storyboard */ = { + isa = PBXVariantGroup; + children = ( + CBF19015243D6F59001C82ED /* Base */, + ); + name = Interface.storyboard; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -877,6 +1112,84 @@ }; name = Release; }; + CBF19034243D6F5A001C82ED /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LP4KGRS5XZ; + IBSC_MODULE = WatchApp_Extension; + INFOPLIST_FILE = WatchApp/Info.plist; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.lingol.MMKVDemo1.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 5.0; + }; + name = Debug; + }; + CBF19035243D6F5A001C82ED /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LP4KGRS5XZ; + IBSC_MODULE = WatchApp_Extension; + INFOPLIST_FILE = WatchApp/Info.plist; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.lingol.MMKVDemo1.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 5.0; + }; + name = Release; + }; + CBF19037243D6F5A001C82ED /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LP4KGRS5XZ; + INFOPLIST_FILE = "WatchApp Extension/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.lingol.MMKVDemo1.watchkitapp.watchkitextension; + PRODUCT_NAME = "${TARGET_NAME}"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 5.0; + }; + name = Debug; + }; + CBF19038243D6F5A001C82ED /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LP4KGRS5XZ; + INFOPLIST_FILE = "WatchApp Extension/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.lingol.MMKVDemo1.watchkitapp.watchkitextension; + PRODUCT_NAME = "${TARGET_NAME}"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 5.0; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -925,6 +1238,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + CBF1903A243D6F5A001C82ED /* Build configuration list for PBXNativeTarget "WatchApp Extension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CBF19037243D6F5A001C82ED /* Debug */, + CBF19038243D6F5A001C82ED /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + CBF1903B243D6F5A001C82ED /* Build configuration list for PBXNativeTarget "WatchApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CBF19034243D6F5A001C82ED /* Debug */, + CBF19035243D6F5A001C82ED /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = CB1FD41820455E2D00931B5F /* Project object */; diff --git a/iOS/MMKVDemo/MMKVDemo/ViewController+TestCaseBad.h b/iOS/MMKVDemo/MMKVDemo/ViewController+TestCaseBad.h new file mode 100644 index 00000000..47e43ac8 --- /dev/null +++ b/iOS/MMKVDemo/MMKVDemo/ViewController+TestCaseBad.h @@ -0,0 +1,29 @@ +/* +* Tencent is pleased to support the open source community by making +* MMKV available. +* +* Copyright (C) 2020 THL A29 Limited, a Tencent company. +* All rights reserved. +* +* Licensed under the BSD 3-Clause License (the "License"); you may not use +* this file except in compliance with the License. You may obtain a copy of +* the License at +* +* https://opensource.org/licenses/BSD-3-Clause +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#import "ViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ViewController (TestCaseBad) + +@end + +NS_ASSUME_NONNULL_END diff --git a/iOS/MMKVDemo/MMKVDemo/ViewController+TestCaseBad.mm b/iOS/MMKVDemo/MMKVDemo/ViewController+TestCaseBad.mm new file mode 100644 index 00000000..8d6aeccb --- /dev/null +++ b/iOS/MMKVDemo/MMKVDemo/ViewController+TestCaseBad.mm @@ -0,0 +1,129 @@ +/* +* Tencent is pleased to support the open source community by making +* MMKV available. +* +* Copyright (C) 2020 THL A29 Limited, a Tencent company. +* All rights reserved. +* +* Licensed under the BSD 3-Clause License (the "License"); you may not use +* this file except in compliance with the License. You may obtain a copy of +* the License at +* +* https://opensource.org/licenses/BSD-3-Clause +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#import "ViewController+TestCaseBad.h" +#import +#import +#import + +@implementation ViewController (TestCaseBad) + +- (void)testCornerSize { + auto mmkv = [MMKV mmkvWithID:@"test/cornerSize" cryptKey:[@"crypt" dataUsingEncoding:NSUTF8StringEncoding]]; + [mmkv clearAll]; + auto size = getpagesize() - 2; + size -= 4; + NSString *key = @"key"; + auto keySize = 3 + 1; + size -= keySize; + auto valueSize = 3; + size -= valueSize; + NSData *value = [NSMutableData dataWithLength:size]; + [mmkv setObject:value forKey:key]; +} + +- (void)testFastRemoveCornerSize { + auto mmkv = [MMKV mmkvWithID:@"test/FastRemoveCornerSize" cryptKey:[@"crypt" dataUsingEncoding:NSUTF8StringEncoding]]; + [mmkv clearAll]; + auto size = getpagesize() - 4; + size -= 4; + NSString *key = @"key"; + auto keySize = 3 + 1; + size -= keySize; + auto valueSize = 3; + size -= valueSize; + size -= (keySize + 1); // total size of fast remove + size /= 16; + NSMutableData *value = [NSMutableData dataWithLength:size]; + auto ptr = (char *) value.mutableBytes; + for (int i = 0; i < value.length; i++) { + ptr[i] = 'A'; + } + for (int i = 0; i < 16; i++) { + [mmkv setObject:value forKey:key]; // when a full write back is occur, here's corruption happens + [mmkv removeValueForKey:key]; + } +} + +- (void)testChineseCharKey { + std::vector> fakeKeyValues = { + {"UUID", 36, 37}, + {"webViewShake", 1, 2}, + {"install_now", 1, 1}, + {"HomeContainerViewControllerGuide", 32, 33}, + {"AdvertisingKey", 397, 397}, + {"PrivacyPolicy", 1, 1}, + {"appVersion", 6, 7}, + {"IS_RECEIVE_PUSH", 1, 1}, + {"invite_url", 0, 1}, + {"kHaveOneDayOrLongTime", 8, 8}, + {"kHaveOneHourOrLongTime", 8, 8}, + {"PO_TYPE", 139, 139}, + {"invite_url", 41, 42}, + {"watermark", 95, 96}, + {"BrowserWhitelist", 253, 253}, + {"open_log", 0, 1}, + {"xz_district_key", 1390, 1390}, + {"open_position", 1, 1}, + {"xz_auth_wechat", 1, 1}, + {"xz_auth_weibo", 0, 1}, + {"xz_auth_qq", 0, 1}, + {"cache_expire", 0, 8}, + {"PopupWindowNotice", 461, 461}, + {"推送通知提示间隔", 1, 1}, + {"版本更新提示间隔", 0, 1}, + {"定位提醒显示间隔", 0, 8}, + {"QFH5_JAVASCRIPT", 2157, 2159}, + {"上次定位_city", 9, 10}, + {"PopupWindowNotice", 0, 0}, + }; + + auto mmkv = [MMKV mmkvWithID:@"testChineseCharKey"]; + for (auto &kv : fakeKeyValues) { + auto key = [NSString stringWithUTF8String:std::get<0>(kv).c_str()]; + auto size = std::get<1>(kv); + const auto orgSize = std::get<2>(kv); + if (orgSize == 8) { + [mmkv setDouble:0.0 forKey:key]; + } else if (size < orgSize) { + auto buf = [NSMutableData dataWithLength:size]; + [mmkv setObject:buf forKey:key]; + } else if (size == 1) { + [mmkv setBool:YES forKey:key]; + } else if (size == 0) { + [mmkv removeValueForKey:key]; + } else if (size > 8) { + if (orgSize <= 127) { + size -= 1; + } else { + size -= 2; + } + auto buf = [NSMutableData dataWithLength:size]; + [mmkv setObject:buf forKey:key]; + } else { + assert(0); + } + auto resultSize = [mmkv getValueSizeForKey:key]; + assert(resultSize == orgSize); + NSLog(@"%@, %zu", key, [mmkv actualSize]); + } +} + +@end diff --git a/iOS/MMKVDemo/MMKVDemo/ViewController.mm b/iOS/MMKVDemo/MMKVDemo/ViewController.mm index 1dd469a0..9282c61a 100644 --- a/iOS/MMKVDemo/MMKVDemo/ViewController.mm +++ b/iOS/MMKVDemo/MMKVDemo/ViewController.mm @@ -18,8 +18,8 @@ * limitations under the License. */ -#import "ViewController.h" #import "MMKVDemo-Swift.h" +#import "ViewController+TestCaseBad.h" #import @interface TestNSArchive : NSObject @@ -69,6 +69,7 @@ - (void)viewDidLoad { [self testImportFromUserDefault]; //[self testCornerSize]; //[self testFastRemoveCornerSize]; + //[self testChineseCharKey]; DemoSwiftUsage *swiftUsageDemo = [[DemoSwiftUsage alloc] init]; [swiftUsageDemo testSwiftFunctionality]; @@ -162,43 +163,6 @@ - (void)funcionalTest { [mmkv close]; } -- (void)testCornerSize { - auto mmkv = [MMKV mmkvWithID:@"test/cornerSize" cryptKey:[@"crypt" dataUsingEncoding:NSUTF8StringEncoding]]; - [mmkv clearAll]; - auto size = getpagesize() - 2; - size -= 4; - NSString *key = @"key"; - auto keySize = 3 + 1; - size -= keySize; - auto valueSize = 3; - size -= valueSize; - NSData *value = [NSMutableData dataWithLength:size]; - [mmkv setObject:value forKey:key]; -} - -- (void)testFastRemoveCornerSize { - auto mmkv = [MMKV mmkvWithID:@"test/FastRemoveCornerSize" cryptKey:[@"crypt" dataUsingEncoding:NSUTF8StringEncoding]]; - [mmkv clearAll]; - auto size = getpagesize() - 4; - size -= 4; - NSString *key = @"key"; - auto keySize = 3 + 1; - size -= keySize; - auto valueSize = 3; - size -= valueSize; - size -= (keySize + 1); // total size of fast remove - size /= 16; - NSMutableData *value = [NSMutableData dataWithLength:size]; - auto ptr = (char *) value.mutableBytes; - for (int i = 0; i < value.length; i++) { - ptr[i] = 'A'; - } - for (int i = 0; i < 16; i++) { - [mmkv setObject:value forKey:key]; // when a full write back is occur, here's corruption happens - [mmkv removeValueForKey:key]; - } -} - - (void)testMMKV:(NSString *)mmapID withCryptKey:(NSData *)cryptKey decodeOnly:(BOOL)decodeOnly { MMKV *mmkv = [MMKV mmkvWithID:mmapID cryptKey:cryptKey]; diff --git a/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json new file mode 100644 index 00000000..ed7de25e --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Contents.json b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Contents.json new file mode 100644 index 00000000..df73a6bb --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Contents.json @@ -0,0 +1,48 @@ +{ + "assets" : [ + { + "filename" : "Circular.imageset", + "idiom" : "watch", + "role" : "circular" + }, + { + "filename" : "Extra Large.imageset", + "idiom" : "watch", + "role" : "extra-large" + }, + { + "filename" : "Graphic Bezel.imageset", + "idiom" : "watch", + "role" : "graphic-bezel" + }, + { + "filename" : "Graphic Circular.imageset", + "idiom" : "watch", + "role" : "graphic-circular" + }, + { + "filename" : "Graphic Corner.imageset", + "idiom" : "watch", + "role" : "graphic-corner" + }, + { + "filename" : "Graphic Large Rectangular.imageset", + "idiom" : "watch", + "role" : "graphic-large-rectangular" + }, + { + "filename" : "Modular.imageset", + "idiom" : "watch", + "role" : "modular" + }, + { + "filename" : "Utilitarian.imageset", + "idiom" : "watch", + "role" : "utilitarian" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json new file mode 100644 index 00000000..ed7de25e --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json new file mode 100644 index 00000000..ed7de25e --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json new file mode 100644 index 00000000..ed7de25e --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json new file mode 100644 index 00000000..ed7de25e --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json new file mode 100644 index 00000000..ed7de25e --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json new file mode 100644 index 00000000..ed7de25e --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json new file mode 100644 index 00000000..ed7de25e --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Contents.json b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/MMKVDemo/WatchApp Extension/ExtensionDelegate.h b/iOS/MMKVDemo/WatchApp Extension/ExtensionDelegate.h new file mode 100644 index 00000000..ff6f3f88 --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/ExtensionDelegate.h @@ -0,0 +1,13 @@ +// +// ExtensionDelegate.h +// WatchApp Extension +// +// Created by lingol on 2020/4/8. +// Copyright © 2020 Lingol. All rights reserved. +// + +#import + +@interface ExtensionDelegate : NSObject + +@end diff --git a/iOS/MMKVDemo/WatchApp Extension/ExtensionDelegate.mm b/iOS/MMKVDemo/WatchApp Extension/ExtensionDelegate.mm new file mode 100644 index 00000000..e7d1f86d --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/ExtensionDelegate.mm @@ -0,0 +1,123 @@ +// +// ExtensionDelegate.m +// WatchApp Extension +// +// Created by lingol on 2020/4/8. +// Copyright © 2020 Lingol. All rights reserved. +// + +#import "ExtensionDelegate.h" +#import + +@implementation ExtensionDelegate + +- (void)applicationDidFinishLaunching { + // Perform any final initialization of your application. + [MMKV initializeMMKV:nil]; + + [self funcionalTest]; +} + +- (void)funcionalTest { + auto path = [MMKV mmkvBasePath]; + path = [path stringByDeletingLastPathComponent]; + path = [path stringByAppendingPathComponent:@"mmkv_2"]; + auto mmkv = [MMKV mmkvWithID:@"test/case1" relativePath:path]; + + [mmkv setBool:YES forKey:@"bool"]; + NSLog(@"bool:%d", [mmkv getBoolForKey:@"bool"]); + + [mmkv setInt32:-1024 forKey:@"int32"]; + NSLog(@"int32:%d", [mmkv getInt32ForKey:@"int32"]); + + [mmkv setUInt32:std::numeric_limits::max() forKey:@"uint32"]; + NSLog(@"uint32:%u", [mmkv getUInt32ForKey:@"uint32"]); + + [mmkv setInt64:std::numeric_limits::min() forKey:@"int64"]; + NSLog(@"int64:%lld", [mmkv getInt64ForKey:@"int64"]); + + [mmkv setUInt64:std::numeric_limits::max() forKey:@"uint64"]; + NSLog(@"uint64:%llu", [mmkv getInt64ForKey:@"uint64"]); + + [mmkv setFloat:-3.1415926 forKey:@"float"]; + NSLog(@"float:%f", [mmkv getFloatForKey:@"float"]); + + [mmkv setDouble:std::numeric_limits::max() forKey:@"double"]; + NSLog(@"double:%f", [mmkv getDoubleForKey:@"double"]); + + [mmkv setString:@"hello, mmkv" forKey:@"string"]; + NSLog(@"string:%@", [mmkv getStringForKey:@"string"]); + + [mmkv setObject:nil forKey:@"string"]; + NSLog(@"string after set nil:%@, containsKey:%d", + [mmkv getObjectOfClass:NSString.class + forKey:@"string"], + [mmkv containsKey:@"string"]); + + [mmkv setDate:[NSDate date] forKey:@"date"]; + NSLog(@"date:%@", [mmkv getDateForKey:@"date"]); + + [mmkv setData:[@"hello, mmkv again and again" dataUsingEncoding:NSUTF8StringEncoding] forKey:@"data"]; + NSData *data = [mmkv getDataForKey:@"data"]; + NSLog(@"data:%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); + NSLog(@"data length:%zu, value size consumption:%zu", data.length, [mmkv getValueSizeForKey:@"data"]); + + [mmkv setObject:[NSData data] forKey:@"data"]; + NSLog(@"data after set empty data:%@, containsKey:%d", + [mmkv getObjectOfClass:NSData.class + forKey:@"data"], + [mmkv containsKey:@"data"]); + + [mmkv removeValueForKey:@"bool"]; + NSLog(@"bool:%d", [mmkv getBoolForKey:@"bool"]); + [mmkv removeValuesForKeys:@[ @"int32", @"uint64" ]]; + NSLog(@"allKeys %@", [mmkv allKeys]); + + [mmkv close]; +} + +- (void)applicationDidBecomeActive { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillResignActive { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, etc. +} + +- (void)handleBackgroundTasks:(NSSet *)backgroundTasks { + // Sent when the system needs to launch the application in the background to process tasks. Tasks arrive in a set, so loop through and process each one. + for (WKRefreshBackgroundTask * task in backgroundTasks) { + // Check the Class of each task to decide how to process it + if ([task isKindOfClass:[WKApplicationRefreshBackgroundTask class]]) { + // Be sure to complete the background task once you’re done. + WKApplicationRefreshBackgroundTask *backgroundTask = (WKApplicationRefreshBackgroundTask*)task; + [backgroundTask setTaskCompletedWithSnapshot:NO]; + } else if ([task isKindOfClass:[WKSnapshotRefreshBackgroundTask class]]) { + // Snapshot tasks have a unique completion call, make sure to set your expiration date + WKSnapshotRefreshBackgroundTask *snapshotTask = (WKSnapshotRefreshBackgroundTask*)task; + [snapshotTask setTaskCompletedWithDefaultStateRestored:YES estimatedSnapshotExpiration:[NSDate distantFuture] userInfo:nil]; + } else if ([task isKindOfClass:[WKWatchConnectivityRefreshBackgroundTask class]]) { + // Be sure to complete the background task once you’re done. + WKWatchConnectivityRefreshBackgroundTask *backgroundTask = (WKWatchConnectivityRefreshBackgroundTask*)task; + [backgroundTask setTaskCompletedWithSnapshot:NO]; + } else if ([task isKindOfClass:[WKURLSessionRefreshBackgroundTask class]]) { + // Be sure to complete the background task once you’re done. + WKURLSessionRefreshBackgroundTask *backgroundTask = (WKURLSessionRefreshBackgroundTask*)task; + [backgroundTask setTaskCompletedWithSnapshot:NO]; + } else if ([task isKindOfClass:[WKRelevantShortcutRefreshBackgroundTask class]]) { + // Be sure to complete the relevant-shortcut task once you’re done. + WKRelevantShortcutRefreshBackgroundTask *relevantShortcutTask = (WKRelevantShortcutRefreshBackgroundTask*)task; + [relevantShortcutTask setTaskCompletedWithSnapshot:NO]; + } else if ([task isKindOfClass:[WKIntentDidRunRefreshBackgroundTask class]]) { + // Be sure to complete the intent-did-run task once you’re done. + WKIntentDidRunRefreshBackgroundTask *intentDidRunTask = (WKIntentDidRunRefreshBackgroundTask*)task; + [intentDidRunTask setTaskCompletedWithSnapshot:NO]; + } else { + // make sure to complete unhandled task types + [task setTaskCompletedWithSnapshot:NO]; + } + } +} + +@end diff --git a/iOS/MMKVDemo/WatchApp Extension/Info.plist b/iOS/MMKVDemo/WatchApp Extension/Info.plist new file mode 100644 index 00000000..0dc6badd --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/Info.plist @@ -0,0 +1,36 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + WatchApp Extension + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + NSExtension + + NSExtensionAttributes + + WKAppBundleIdentifier + com.lingol.MMKVDemo1.watchkitapp + + NSExtensionPointIdentifier + com.apple.watchkit + + WKExtensionDelegateClassName + ExtensionDelegate + + diff --git a/iOS/MMKVDemo/WatchApp Extension/InterfaceController.h b/iOS/MMKVDemo/WatchApp Extension/InterfaceController.h new file mode 100644 index 00000000..9d4eeaed --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/InterfaceController.h @@ -0,0 +1,14 @@ +// +// InterfaceController.h +// WatchApp Extension +// +// Created by lingol on 2020/4/8. +// Copyright © 2020 Lingol. All rights reserved. +// + +#import +#import + +@interface InterfaceController : WKInterfaceController + +@end diff --git a/iOS/MMKVDemo/WatchApp Extension/InterfaceController.m b/iOS/MMKVDemo/WatchApp Extension/InterfaceController.m new file mode 100644 index 00000000..468862e0 --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/InterfaceController.m @@ -0,0 +1,38 @@ +// +// InterfaceController.m +// WatchApp Extension +// +// Created by lingol on 2020/4/8. +// Copyright © 2020 Lingol. All rights reserved. +// + +#import "InterfaceController.h" + + +@interface InterfaceController () + +@end + + +@implementation InterfaceController + +- (void)awakeWithContext:(id)context { + [super awakeWithContext:context]; + + // Configure interface objects here. +} + +- (void)willActivate { + // This method is called when watch view controller is about to be visible to user + [super willActivate]; +} + +- (void)didDeactivate { + // This method is called when watch view controller is no longer visible + [super didDeactivate]; +} + +@end + + + diff --git a/iOS/MMKVDemo/WatchApp Extension/NotificationController.h b/iOS/MMKVDemo/WatchApp Extension/NotificationController.h new file mode 100644 index 00000000..85ecd544 --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/NotificationController.h @@ -0,0 +1,14 @@ +// +// NotificationController.h +// WatchApp Extension +// +// Created by lingol on 2020/4/8. +// Copyright © 2020 Lingol. All rights reserved. +// + +#import +#import + +@interface NotificationController : WKUserNotificationInterfaceController + +@end diff --git a/iOS/MMKVDemo/WatchApp Extension/NotificationController.m b/iOS/MMKVDemo/WatchApp Extension/NotificationController.m new file mode 100644 index 00000000..41a3f651 --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/NotificationController.m @@ -0,0 +1,48 @@ +// +// NotificationController.m +// WatchApp Extension +// +// Created by lingol on 2020/4/8. +// Copyright © 2020 Lingol. All rights reserved. +// + +#import "NotificationController.h" + + +@interface NotificationController () + +@end + + +@implementation NotificationController + +- (instancetype)init { + self = [super init]; + if (self){ + // Initialize variables here. + // Configure interface objects here. + + } + return self; +} + +- (void)willActivate { + // This method is called when watch view controller is about to be visible to user + [super willActivate]; +} + +- (void)didDeactivate { + // This method is called when watch view controller is no longer visible + [super didDeactivate]; +} + +- (void)didReceiveNotification:(UNNotification *)notification { + // This method is called when a notification needs to be presented. + // Implement it if you use a dynamic notification interface. + // Populate your dynamic notification interface as quickly as possible. +} + +@end + + + diff --git a/iOS/MMKVDemo/WatchApp Extension/PushNotificationPayload.apns b/iOS/MMKVDemo/WatchApp Extension/PushNotificationPayload.apns new file mode 100644 index 00000000..c18b00ad --- /dev/null +++ b/iOS/MMKVDemo/WatchApp Extension/PushNotificationPayload.apns @@ -0,0 +1,20 @@ +{ + "aps": { + "alert": { + "body": "Test message", + "title": "Optional title", + "subtitle": "Optional subtitle" + }, + "category": "myCategory", + "thread-id": "5280" + }, + + "WatchKit Simulator Actions": [ + { + "title": "First Button", + "identifier": "firstButtonAction" + } + ], + + "customKey": "Use this file to define a testing payload for your notifications. The aps dictionary specifies the category, alert text and title. The WatchKit Simulator Actions array can provide info for one or more action buttons in addition to the standard Dismiss button. Any other top level keys are custom payload. If you have multiple such JSON files in your project, you'll be able to select them when choosing to debug the notification interface of your Watch App." +} diff --git a/iOS/MMKVDemo/WatchApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/iOS/MMKVDemo/WatchApp/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d06b66af --- /dev/null +++ b/iOS/MMKVDemo/WatchApp/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,81 @@ +{ + "images" : [ + { + "idiom" : "watch", + "role" : "notificationCenter", + "scale" : "2x", + "size" : "24x24", + "subtype" : "38mm" + }, + { + "idiom" : "watch", + "role" : "notificationCenter", + "scale" : "2x", + "size" : "27.5x27.5", + "subtype" : "42mm" + }, + { + "idiom" : "watch", + "role" : "companionSettings", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "watch", + "role" : "companionSettings", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "watch", + "role" : "appLauncher", + "scale" : "2x", + "size" : "40x40", + "subtype" : "38mm" + }, + { + "idiom" : "watch", + "role" : "appLauncher", + "scale" : "2x", + "size" : "44x44", + "subtype" : "40mm" + }, + { + "idiom" : "watch", + "role" : "appLauncher", + "scale" : "2x", + "size" : "50x50", + "subtype" : "44mm" + }, + { + "idiom" : "watch", + "role" : "quickLook", + "scale" : "2x", + "size" : "86x86", + "subtype" : "38mm" + }, + { + "idiom" : "watch", + "role" : "quickLook", + "scale" : "2x", + "size" : "98x98", + "subtype" : "42mm" + }, + { + "idiom" : "watch", + "role" : "quickLook", + "scale" : "2x", + "size" : "108x108", + "subtype" : "44mm" + }, + { + "idiom" : "watch-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/MMKVDemo/WatchApp/Assets.xcassets/Contents.json b/iOS/MMKVDemo/WatchApp/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/iOS/MMKVDemo/WatchApp/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/MMKVDemo/WatchApp/Base.lproj/Interface.storyboard b/iOS/MMKVDemo/WatchApp/Base.lproj/Interface.storyboard new file mode 100644 index 00000000..0d181e5b --- /dev/null +++ b/iOS/MMKVDemo/WatchApp/Base.lproj/Interface.storyboard @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/MMKVDemo/WatchApp/Info.plist b/iOS/MMKVDemo/WatchApp/Info.plist new file mode 100644 index 00000000..0c247240 --- /dev/null +++ b/iOS/MMKVDemo/WatchApp/Info.plist @@ -0,0 +1,33 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + MMKVDemo + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + + WKCompanionAppBundleIdentifier + com.lingol.MMKVDemo1 + WKWatchKitApp + + + diff --git a/readme_cn.md b/readme_cn.md index 0c44ed5c..3c6d03a9 100644 --- a/readme_cn.md +++ b/readme_cn.md @@ -22,8 +22,8 @@ MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列 ```gradle dependencies { - implementation 'com.tencent:mmkv-static:1.1.0' - // replace "1.1.0" with any available version + implementation 'com.tencent:mmkv-static:1.1.1' + // replace "1.1.1" with any available version } ```