From 89b56922e809c050e55e1dc87a6893f041a802bc Mon Sep 17 00:00:00 2001 From: guoling Date: Thu, 28 Nov 2024 17:22:00 +0800 Subject: [PATCH] 1. NameSpace almost work on iOS 2. Upgrade to iOS 13, watchOS 6 3. Dont mkPath() on ReadOnly mode --- Core/Core.xcodeproj/project.pbxproj | 12 +- Core/MMKV.cpp | 117 +++++++++++++----- Core/MMKV.h | 80 +++++++++++- Core/MMKV_IO.cpp | 4 +- Core/MMKV_IO.h | 3 +- Core/MemoryFile.cpp | 9 ++ Core/MemoryFile.h | 1 + iOS/MMKV/MMKV.xcodeproj/project.pbxproj | 8 +- .../MMKVDemo.xcodeproj/project.pbxproj | 8 +- 9 files changed, 189 insertions(+), 53 deletions(-) diff --git a/Core/Core.xcodeproj/project.pbxproj b/Core/Core.xcodeproj/project.pbxproj index 1272a52d..862d4618 100644 --- a/Core/Core.xcodeproj/project.pbxproj +++ b/Core/Core.xcodeproj/project.pbxproj @@ -498,14 +498,14 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TVOS_DEPLOYMENT_TARGET = 13.0; - WATCHOS_DEPLOYMENT_TARGET = 4.0; + WATCHOS_DEPLOYMENT_TARGET = 6.0; XROS_DEPLOYMENT_TARGET = 1.0; }; name = Debug; @@ -557,14 +557,14 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; TVOS_DEPLOYMENT_TARGET = 13.0; VALIDATE_PRODUCT = YES; - WATCHOS_DEPLOYMENT_TARGET = 4.0; + WATCHOS_DEPLOYMENT_TARGET = 6.0; XROS_DEPLOYMENT_TARGET = 1.0; }; name = Release; @@ -590,8 +590,8 @@ SDKROOT = ""; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx appletvsimulator appletvos xrsimulator xros"; + SUPPORTS_MACCATALYST = YES; TARGETED_DEVICE_FAMILY = "1,2,3"; - SUPPORTS_MACCATALYST = YES; }; name = Debug; }; @@ -617,8 +617,8 @@ SDKROOT = ""; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx appletvsimulator appletvos xrsimulator xros"; + SUPPORTS_MACCATALYST = YES; TARGETED_DEVICE_FAMILY = "1,2,3"; - SUPPORTS_MACCATALYST = YES; }; name = Release; }; diff --git a/Core/MMKV.cpp b/Core/MMKV.cpp index 62e0b525..959281b6 100644 --- a/Core/MMKV.cpp +++ b/Core/MMKV.cpp @@ -60,6 +60,9 @@ using namespace mmkv; unordered_map *g_instanceDic; ThreadLock *g_instanceLock; MMKVPath_t g_rootDir; +MMKVPath_t g_realRootDir; +static ThreadLock *g_namespaceLock; +static unordered_map g_realRootMap; static mmkv::ErrorHandler g_errorHandler; size_t mmkv::DEFAULT_MMAP_SIZE; @@ -78,11 +81,11 @@ bool endsWith(const MMKVPath_t &str, const MMKVPath_t &suffix); MMKVPath_t filename(const MMKVPath_t &path); #ifndef MMKV_ANDROID -MMKV::MMKV(const string &mmapID, MMKVMode mode, string *cryptKey, MMKVPath_t *rootPath, size_t expectedCapacity) +MMKV::MMKV(const string &mmapID, MMKVMode mode, const string *cryptKey, const MMKVPath_t *rootPath, size_t expectedCapacity) : m_mmapID(mmapID) , m_mode(mode) , m_path(mappedKVPathWithID(m_mmapID, mode, rootPath)) - , m_crcPath(crcPathWithID(m_mmapID, mode, rootPath)) + , m_crcPath(crcPathWithPath(m_path)) , m_dic(nullptr) , m_dicCrypt(nullptr) , m_expectedCapacity(std::max(DEFAULT_MMAP_SIZE, roundUp(expectedCapacity, DEFAULT_MMAP_SIZE))) @@ -150,7 +153,7 @@ MMKV::~MMKV() { MMKVInfo("destruct [%s]", m_mmapID.c_str()); } -MMKV *MMKV::defaultMMKV(MMKVMode mode, string *cryptKey) { +MMKV *MMKV::defaultMMKV(MMKVMode mode, const string *cryptKey) { #ifndef MMKV_ANDROID return mmkvWithID(DEFAULT_MMAP_ID, mode, cryptKey); #else @@ -158,7 +161,7 @@ MMKV *MMKV::defaultMMKV(MMKVMode mode, string *cryptKey) { #endif } -void initialize() { +static void initialize() { g_instanceDic = new unordered_map; g_instanceLock = new ThreadLock(); g_instanceLock->initialize(); @@ -196,13 +199,16 @@ void initialize() { #endif } -static ThreadOnceToken_t once_control = ThreadOnceUninitialized; +static void ensureMinimalInitialize() { + static ThreadOnceToken_t once_control = ThreadOnceUninitialized; + ThreadLock::ThreadOnce(&once_control, initialize); +} void MMKV::initializeMMKV(const MMKVPath_t &rootDir, MMKVLogLevel logLevel, mmkv::LogHandler handler) { g_currentLogLevel = logLevel; g_logHandler = handler; - ThreadLock::ThreadOnce(&once_control, initialize); + ensureMinimalInitialize(); #ifdef MMKV_APPLE // crc32 instruction requires A10 chip, aka iPhone 7 or iPad 6th generation @@ -222,18 +228,21 @@ void MMKV::initializeMMKV(const MMKVPath_t &rootDir, MMKVLogLevel logLevel, mmkv if (g_rootDir.empty()) { g_rootDir = rootDir; - mkPath(g_rootDir); + // avoid operating g_realRootMap directly + g_realRootDir = nameSpace(rootDir).getRootDir(); + mkPath(g_realRootDir); } - MMKVInfo("root dir: " MMKV_PATH_FORMAT, g_rootDir.c_str()); + MMKVInfo("root dir: " MMKV_PATH_FORMAT, g_realRootDir.c_str()); } const MMKVPath_t &MMKV::getRootDir() { + // for backword consistency we can't return g_realRootDir return g_rootDir; } #ifndef MMKV_ANDROID -MMKV *MMKV::mmkvWithID(const string &mmapID, MMKVMode mode, string *cryptKey, MMKVPath_t *rootPath, size_t expectedCapacity) { +MMKV *MMKV::mmkvWithID(const string &mmapID, MMKVMode mode, const string *cryptKey, const MMKVPath_t *rootPath, size_t expectedCapacity) { if (mmapID.empty() || !g_instanceLock) { return nullptr; @@ -247,13 +256,14 @@ MMKV *MMKV::mmkvWithID(const string &mmapID, MMKVMode mode, string *cryptKey, MM return kv; } - if (rootPath) { + if (rootPath && !(mode & MMKV_READ_ONLY)) { MMKVPath_t specialPath = (*rootPath) + MMKV_PATH_SLASH + SPECIAL_CHARACTER_DIRECTORY_NAME; if (!isFileExist(specialPath)) { mkPath(specialPath); } - MMKVInfo("prepare to load %s (id %s) from rootPath %s", mmapID.c_str(), mmapKey.c_str(), rootPath->c_str()); } + auto theRootDir = rootPath ? rootPath : &g_realRootDir; + MMKVInfo("prepare to load %s (id %s) from rootPath %s", mmapID.c_str(), mmapKey.c_str(), theRootDir->c_str()); auto kv = new MMKV(mmapID, mode, cryptKey, rootPath, expectedCapacity); kv->m_mmapKey = mmapKey; @@ -1295,7 +1305,7 @@ bool MMKV::backupOneToDirectory(const string &mmapKey, const MMKVPath_t &dstPath } bool MMKV::backupOneToDirectory(const string &mmapID, const MMKVPath_t &dstDir, const MMKVPath_t *srcDir) { - auto rootPath = srcDir ? srcDir : &g_rootDir; + auto rootPath = srcDir ? srcDir : &g_realRootDir; if (*rootPath == dstDir) { return true; } @@ -1372,7 +1382,7 @@ size_t MMKV::backupAllToDirectory(const MMKVPath_t &dstDir, const MMKVPath_t &sr } size_t MMKV::backupAllToDirectory(const MMKVPath_t &dstDir, const MMKVPath_t *srcDir) { - auto rootPath = srcDir ? srcDir : &g_rootDir; + auto rootPath = srcDir ? srcDir : &g_realRootDir; if (*rootPath == dstDir) { return true; } @@ -1484,7 +1494,7 @@ bool MMKV::restoreOneFromDirectory(const string &mmapKey, const MMKVPath_t &srcP } bool MMKV::restoreOneFromDirectory(const string &mmapID, const MMKVPath_t &srcDir, const MMKVPath_t *dstDir) { - auto rootPath = dstDir ? dstDir : &g_rootDir; + auto rootPath = dstDir ? dstDir : &g_realRootDir; if (*rootPath == srcDir) { return true; } @@ -1546,7 +1556,7 @@ size_t MMKV::restoreAllFromDirectory(const MMKVPath_t &srcDir, const MMKVPath_t } size_t MMKV::restoreAllFromDirectory(const MMKVPath_t &srcDir, const MMKVPath_t *dstDir) { - auto rootPath = dstDir ? dstDir : &g_rootDir; + auto rootPath = dstDir ? dstDir : &g_realRootDir; if (*rootPath == srcDir) { return true; } @@ -1603,7 +1613,7 @@ void MMKV::setLogLevel(MMKVLogLevel level) { } static void mkSpecialCharacterFileDirectory() { - MMKVPath_t path = g_rootDir + MMKV_PATH_SLASH + SPECIAL_CHARACTER_DIRECTORY_NAME; + MMKVPath_t path = g_realRootDir + MMKV_PATH_SLASH + SPECIAL_CHARACTER_DIRECTORY_NAME; mkPath(path); } @@ -1661,7 +1671,19 @@ static MMKVPath_t encodeFilePath(const string &mmapID, const MMKVPath_t &rootDir } string mmapedKVKey(const string &mmapID, const MMKVPath_t *rootPath) { - if (rootPath && g_rootDir != (*rootPath)) { + MMKVPath_t path; + // compare by pointer to speedup a bit, it's OK false detecting + if (rootPath && (rootPath != &g_realRootDir)) { + auto tmp = *rootPath + MMKV_PATH_SLASH + string2MMKVPath_t(mmapID); + path = absolutePath(tmp); + } else { + path = g_realRootDir + MMKV_PATH_SLASH + string2MMKVPath_t(mmapID); + } + return md5(path); +} + +string legacyMmapedKVKey(const string &mmapID, const MMKVPath_t *rootPath) { + if (rootPath && (*rootPath != g_rootDir)) { return md5(*rootPath + MMKV_PATH_SLASH + string2MMKVPath_t(mmapID)); } return mmapID; @@ -1669,28 +1691,21 @@ string mmapedKVKey(const string &mmapID, const MMKVPath_t *rootPath) { MMKVPath_t mappedKVPathWithID(const string &mmapID, MMKVMode mode, const MMKVPath_t *rootPath) { #ifndef MMKV_ANDROID - if (rootPath) { + if (rootPath && (rootPath != &g_realRootDir)) { #else if (mode & MMKV_ASHMEM) { return ashmemMMKVPathWithID(encodeFilePath(mmapID)); - } else if (rootPath) { + } else if (rootPath && (rootPath != &g_realRootDir)) { #endif - return *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapID); + auto path = *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapID, *rootPath); + return absolutePath(path); } - return g_rootDir + MMKV_PATH_SLASH + encodeFilePath(mmapID); + auto path = g_realRootDir + MMKV_PATH_SLASH + encodeFilePath(mmapID); + return path; } -MMKVPath_t crcPathWithID(const string &mmapID, MMKVMode mode, const MMKVPath_t *rootPath) { -#ifndef MMKV_ANDROID - if (rootPath) { -#else - if (mode & MMKV_ASHMEM) { - return ashmemMMKVPathWithID(encodeFilePath(mmapID)) + CRC_SUFFIX; - } else if (rootPath) { -#endif - return *rootPath + MMKV_PATH_SLASH + encodeFilePath(mmapID) + CRC_SUFFIX; - } - return g_rootDir + MMKV_PATH_SLASH + encodeFilePath(mmapID) + CRC_SUFFIX; +MMKVPath_t crcPathWithPath(const MMKVPath_t &kvPath) { + return kvPath + CRC_SUFFIX; } MMKVRecoverStrategic onMMKVCRCCheckFail(const string &mmapID) { @@ -1707,4 +1722,42 @@ MMKVRecoverStrategic onMMKVFileLengthError(const string &mmapID) { return OnErrorDiscard; } +// NameSpace + +NameSpace MMKV::nameSpace(const MMKVPath_t &rootDir) { + if (!g_instanceLock) { + ensureMinimalInitialize(); + } + + static std::once_flag flag; + std::call_once(flag, []{ + g_namespaceLock = new ThreadLock; + g_namespaceLock->initialize(); + }); + SCOPED_LOCK(g_namespaceLock); + + auto itr = g_realRootMap.find(rootDir); + if (itr == g_realRootMap.end()) { + auto realRoot = absolutePath(rootDir); + if (realRoot.ends_with(MMKV_PATH_SLASH)) { + realRoot.erase(realRoot.size() - 1); + } + itr = g_realRootMap.emplace(rootDir, realRoot).first; + } + return NameSpace(itr->second); +} + +NameSpace MMKV::defaultNameSpace() { + if (g_rootDir.empty()) { + MMKVWarning("MMKV has not been initialized, there's no default NameSpace."); + return NameSpace(""); + } + return NameSpace(g_realRootDir); +} + +MMKV *NameSpace::mmkvWithID(const string &mmapID, MMKVMode mode, const string *cryptKey, const MMKVPath_t *rootPath, size_t expectedCapacity) { + auto theRootPath = rootPath ? rootPath : &m_rootDir; + return MMKV::mmkvWithID(mmapID, mode, cryptKey, theRootPath, expectedCapacity); +} + MMKV_NAMESPACE_END diff --git a/Core/MMKV.h b/Core/MMKV.h index 68ac866e..fe9fb68e 100644 --- a/Core/MMKV.h +++ b/Core/MMKV.h @@ -46,6 +46,7 @@ struct MMKVMetaInfo; class FileLock; class InterProcessLock; class ThreadLock; +class NameSpace; } // namespace mmkv MMKV_NAMESPACE_BEGIN @@ -95,7 +96,8 @@ concept MMKV_SUPPORTED_VALUE_TYPE = MMKV_SUPPORTED_PRIMITIVE_VALUE_TYPE || MM class MMKV { #ifndef MMKV_ANDROID - MMKV(const std::string &mmapID, MMKVMode mode, std::string *cryptKey, MMKVPath_t *rootPath, size_t expectedCapacity = 0); + std::string m_mmapKey; + MMKV(const std::string &mmapID, MMKVMode mode, const std::string *cryptKey, const MMKVPath_t *rootPath, size_t expectedCapacity = 0); #else // defined(MMKV_ANDROID) mmkv::FileLock *m_fileModeLock; mmkv::InterProcessLock *m_sharedProcessModeLock; @@ -249,7 +251,7 @@ public: static void initializeMMKV(const MMKVPath_t &rootDir, MMKVLogLevel logLevel = MMKVLogInfo, mmkv::LogHandler handler = nullptr); // a generic purpose instance - static MMKV *defaultMMKV(MMKVMode mode = MMKV_SINGLE_PROCESS, std::string *cryptKey = nullptr); + static MMKV *defaultMMKV(MMKVMode mode = MMKV_SINGLE_PROCESS, const std::string *cryptKey = nullptr); #ifndef MMKV_ANDROID @@ -258,8 +260,8 @@ public: // cryptKey: 16 bytes at most static MMKV *mmkvWithID(const std::string &mmapID, MMKVMode mode = MMKV_SINGLE_PROCESS, - std::string *cryptKey = nullptr, - MMKVPath_t *rootPath = nullptr, + const std::string *cryptKey = nullptr, + const MMKVPath_t *rootPath = nullptr, size_t expectedCapacity = 0); #else // defined(MMKV_ANDROID) @@ -283,6 +285,12 @@ public: bool checkProcessMode(); #endif // MMKV_ANDROID + // get a namespace with custom root dir + static NameSpace nameSpace(const MMKVPath_t &rootDir); + + // identical with the original MMKV with the global root dir + static NameSpace defaultNameSpace(); + // you can call this on application termination, it's totally fine if you don't call static void onExit(); @@ -591,5 +599,69 @@ bool MMKV::getVector(MMKVKey_t key, T &result) { MMKV_NAMESPACE_END +namespace mmkv { + +// a POD-like facade what wraps custom root directory +class NameSpace { + const MMKVPath_t &m_rootDir; + NameSpace(const MMKVPath_t &rootDir) : m_rootDir(rootDir) {} +public: + // return the absolute root dir of NameSpace + const MMKVPath_t &getRootDir() { return m_rootDir; } + +#ifndef MMKV_ANDROID + // mmapID: any unique ID (com.tencent.xin.pay, etc.) + // if you want a per-user mmkv, you could merge user-id within mmapID + // cryptKey: 16 bytes at most + MMKV *mmkvWithID(const std::string &mmapID, + MMKVMode mode = MMKV_SINGLE_PROCESS, + const std::string *cryptKey = nullptr, + const MMKVPath_t *rootPath = nullptr, + size_t expectedCapacity = 0); + +#else // defined(MMKV_ANDROID) + + // mmapID: any unique ID (com.tencent.xin.pay, etc.) + // if you want a per-user mmkv, you could merge user-id within mmapID + // cryptKey: 16 bytes at most + MMKV *mmkvWithID(const std::string &mmapID, + int size = mmkv::DEFAULT_MMAP_SIZE, + MMKVMode mode = MMKV_SINGLE_PROCESS, + std::string *cryptKey = nullptr, + MMKVPath_t *rootPath = nullptr, + size_t expectedCapacity = 0); +#endif // MMKV_ANDROID + + // backup one MMKV instance from srcDir to dstDir + // if srcDir is null, then backup from the root dir of MMKV + bool backupOneToDirectory(const std::string &mmapID, const MMKVPath_t &dstDir, const MMKVPath_t *srcDir = nullptr); + + // restore one MMKV instance from srcDir to dstDir + // if dstDir is null, then restore to the root dir of MMKV + bool restoreOneFromDirectory(const std::string &mmapID, const MMKVPath_t &srcDir, const MMKVPath_t *dstDir = nullptr); + + // backup all MMKV instance from srcDir to dstDir + // if srcDir is null, then backup from the root dir of MMKV + // return count of MMKV successfully backuped + size_t backupAllToDirectory(const MMKVPath_t &dstDir, const MMKVPath_t *srcDir = nullptr); + + // restore all MMKV instance from srcDir to dstDir + // if dstDir is null, then restore to the root dir of MMKV + // return count of MMKV successfully restored + size_t restoreAllFromDirectory(const MMKVPath_t &srcDir, const MMKVPath_t *dstDir = nullptr); + + // detect if the MMKV file is valid or not + // Note: Don't use this to check the existence of the instance, the return value is undefined if the file was never created. + bool isFileValid(const std::string &mmapID, MMKVPath_t *relatePath = nullptr); + + // remove the storage of the MMKV, including the data file & meta file (.crc) + // Note: the existing instance (if any) will be closed & destroyed + bool removeStorage(const std::string &mmapID, MMKVPath_t *relatePath = nullptr); + + friend class MMKV; +}; + +} + #endif // __cplusplus #endif // MMKV_MMKV_H diff --git a/Core/MMKV_IO.cpp b/Core/MMKV_IO.cpp index d347624a..d4175be8 100755 --- a/Core/MMKV_IO.cpp +++ b/Core/MMKV_IO.cpp @@ -1505,7 +1505,7 @@ bool MMKV::isFileValid(const string &mmapID, MMKVPath_t *relatePath) { return true; } - MMKVPath_t crcPath = crcPathWithID(mmapID, MMKV_SINGLE_PROCESS, relatePath); + MMKVPath_t crcPath = crcPathWithPath(kvPath); if (!isFileExist(crcPath)) { return false; } @@ -1568,7 +1568,7 @@ bool MMKV::removeStorage(const std::string &mmapID, MMKVPath_t *relatePath) { MMKVWarning("file not exist %s", kvPath.c_str()); return false; } - MMKVPath_t crcPath = crcPathWithID(realID, MMKV_SINGLE_PROCESS, relatePath); + MMKVPath_t crcPath = crcPathWithPath(kvPath); if (!isFileExist(crcPath)) { MMKVWarning("file not exist %s", crcPath.c_str()); return false; diff --git a/Core/MMKV_IO.h b/Core/MMKV_IO.h index fa3903f6..e87ebb66 100644 --- a/Core/MMKV_IO.h +++ b/Core/MMKV_IO.h @@ -27,8 +27,9 @@ MMKV_NAMESPACE_BEGIN std::string mmapedKVKey(const std::string &mmapID, const MMKVPath_t *rootPath = nullptr); +std::string legacyMmapedKVKey(const std::string &mmapID, const MMKVPath_t *rootPath = nullptr); MMKVPath_t mappedKVPathWithID(const std::string &mmapID, MMKVMode mode, const MMKVPath_t *rootPath); -MMKVPath_t crcPathWithID(const std::string &mmapID, MMKVMode mode, const MMKVPath_t *rootPath); +MMKVPath_t crcPathWithPath(const MMKVPath_t &kvPath); MMKVRecoverStrategic onMMKVCRCCheckFail(const std::string &mmapID); MMKVRecoverStrategic onMMKVFileLengthError(const std::string &mmapID); diff --git a/Core/MemoryFile.cpp b/Core/MemoryFile.cpp index 808da7dc..cdebc04b 100644 --- a/Core/MemoryFile.cpp +++ b/Core/MemoryFile.cpp @@ -36,8 +36,10 @@ # include # include # include +# include using namespace std; +namespace fs = std::filesystem; namespace mmkv { @@ -418,6 +420,13 @@ size_t getPageSize() { return static_cast(getpagesize()); } +extern MMKVPath_t absolutePath(const MMKVPath_t &path) { + fs::path relative_path(path); + fs::path absolute_path = fs::absolute(relative_path); + fs::path normalized = fs::weakly_canonical(absolute_path); + return normalized.string(); +} + #ifndef MMKV_APPLE static pair createUniqueTempFile(const char *prefix) { diff --git a/Core/MemoryFile.h b/Core/MemoryFile.h index 8f877ebe..dc3e9fb3 100644 --- a/Core/MemoryFile.h +++ b/Core/MemoryFile.h @@ -171,6 +171,7 @@ extern bool isFileExist(const MMKVPath_t &nsFilePath); extern MMBuffer *readWholeFile(const MMKVPath_t &path); extern bool zeroFillFile(MMKVFileHandle_t fd, size_t startPos, size_t size); extern size_t getPageSize(); +extern MMKVPath_t absolutePath(const MMKVPath_t &path); extern bool tryAtomicRename(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath); diff --git a/iOS/MMKV/MMKV.xcodeproj/project.pbxproj b/iOS/MMKV/MMKV.xcodeproj/project.pbxproj index 6a54d113..64889630 100644 --- a/iOS/MMKV/MMKV.xcodeproj/project.pbxproj +++ b/iOS/MMKV/MMKV.xcodeproj/project.pbxproj @@ -609,13 +609,13 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx appletvos appletvsimulator"; TVOS_DEPLOYMENT_TARGET = 13.0; - WATCHOS_DEPLOYMENT_TARGET = 4.0; + WATCHOS_DEPLOYMENT_TARGET = 6.0; }; name = Debug; }; @@ -667,13 +667,13 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx appletvos appletvsimulator"; TVOS_DEPLOYMENT_TARGET = 13.0; VALIDATE_PRODUCT = YES; - WATCHOS_DEPLOYMENT_TARGET = 4.0; + WATCHOS_DEPLOYMENT_TARGET = 6.0; }; name = Release; }; diff --git a/iOS/MMKVDemo/MMKVDemo.xcodeproj/project.pbxproj b/iOS/MMKVDemo/MMKVDemo.xcodeproj/project.pbxproj index 964e4398..217fd558 100644 --- a/iOS/MMKVDemo/MMKVDemo.xcodeproj/project.pbxproj +++ b/iOS/MMKVDemo/MMKVDemo.xcodeproj/project.pbxproj @@ -1752,7 +1752,7 @@ SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 5.0; + WATCHOS_DEPLOYMENT_TARGET = 6.0; }; name = Debug; }; @@ -1772,7 +1772,7 @@ SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 5.0; + WATCHOS_DEPLOYMENT_TARGET = 6.0; }; name = Release; }; @@ -1797,7 +1797,7 @@ SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 5.0; + WATCHOS_DEPLOYMENT_TARGET = 6.0; }; name = Debug; }; @@ -1821,7 +1821,7 @@ SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 5.0; + WATCHOS_DEPLOYMENT_TARGET = 6.0; }; name = Release; };