From 576f7c0a0bec86cbaa8f00a1a730374eda7920b1 Mon Sep 17 00:00:00 2001 From: Krzysztof Borowy Date: Thu, 8 Oct 2020 22:49:46 +0200 Subject: [PATCH 1/6] feat: disable backup for AsyncStorage --- ios/RNCAsyncStorage.m | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/ios/RNCAsyncStorage.m b/ios/RNCAsyncStorage.m index 8b20cc2f..b8e7f446 100644 --- a/ios/RNCAsyncStorage.m +++ b/ios/RNCAsyncStorage.m @@ -34,6 +34,27 @@ } } +static BOOL setBackupEnabled(NSString* path, BOOL isEnabled) +{ + NSFileManager *fileManager = [[NSFileManager alloc] init]; + + BOOL isDir; + BOOL exists = [fileManager fileExistsAtPath:path isDirectory:&isDir]; + BOOL success = false; + + if(isDir && exists) { + NSURL* pathUrl = [NSURL fileURLWithPath:path]; + NSError *error = nil; + success = [pathUrl setResourceValue:[NSNumber numberWithBool:isEnabled] forKey:NSURLIsExcludedFromBackupKey error: &error]; + + if(!success){ + NSLog(@"Could not exclude AsyncStorage dir from backup %@", error); + } + } + return success; + +} + static void RCTAppendError(NSDictionary *error, NSMutableArray **errors) { if (error && errors) { @@ -320,7 +341,10 @@ - (instancetype)init // Then migrate what's in "Documents/.../RCTAsyncLocalStorage_V1" to "Application Support/[bundleID]/RCTAsyncLocalStorage_V1" RCTStorageDirectoryMigrationCheck(RCTCreateStorageDirectoryPath_deprecated(RCTStorageDirectory), RCTCreateStorageDirectoryPath(RCTStorageDirectory), NO); - + + // exclude from backup + //setBackupEnabled(RCTCreateStorageDirectoryPath(RCTStorageDirectory), false); + return self; } From 3c71c86cc486f614c7c357c81243ad28861ebbd2 Mon Sep 17 00:00:00 2001 From: Krzysztof Borowy Date: Tue, 13 Oct 2020 21:08:45 +0200 Subject: [PATCH 2/6] fix: review suggestions --- ios/RNCAsyncStorage.m | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ios/RNCAsyncStorage.m b/ios/RNCAsyncStorage.m index b8e7f446..50dc5c7d 100644 --- a/ios/RNCAsyncStorage.m +++ b/ios/RNCAsyncStorage.m @@ -34,7 +34,7 @@ } } -static BOOL setBackupEnabled(NSString* path, BOOL isEnabled) +static BOOL RCTAsyncStorageSetBackupEnabled(NSString* path, BOOL isEnabled) { NSFileManager *fileManager = [[NSFileManager alloc] init]; @@ -42,17 +42,16 @@ static BOOL setBackupEnabled(NSString* path, BOOL isEnabled) BOOL exists = [fileManager fileExistsAtPath:path isDirectory:&isDir]; BOOL success = false; - if(isDir && exists) { + if (isDir && exists) { NSURL* pathUrl = [NSURL fileURLWithPath:path]; NSError *error = nil; - success = [pathUrl setResourceValue:[NSNumber numberWithBool:isEnabled] forKey:NSURLIsExcludedFromBackupKey error: &error]; + success = [pathUrl setResourceValue:@(isEnabled) forKey:NSURLIsExcludedFromBackupKey error:&error]; - if(!success){ + if (!success) { NSLog(@"Could not exclude AsyncStorage dir from backup %@", error); } } return success; - } static void RCTAppendError(NSDictionary *error, NSMutableArray **errors) @@ -342,8 +341,8 @@ - (instancetype)init // Then migrate what's in "Documents/.../RCTAsyncLocalStorage_V1" to "Application Support/[bundleID]/RCTAsyncLocalStorage_V1" RCTStorageDirectoryMigrationCheck(RCTCreateStorageDirectoryPath_deprecated(RCTStorageDirectory), RCTCreateStorageDirectoryPath(RCTStorageDirectory), NO); - // exclude from backup - //setBackupEnabled(RCTCreateStorageDirectoryPath(RCTStorageDirectory), false); + // todo: decide how to read the flag + //RCTAsyncStorageSetBackupEnabled(RCTCreateStorageDirectoryPath(RCTStorageDirectory), false); return self; } From 3db0b424f017b4bf796a32ca7611aad14106829b Mon Sep 17 00:00:00 2001 From: Krzysztof Borowy Date: Thu, 15 Oct 2020 16:16:34 +0200 Subject: [PATCH 3/6] fix: add feature flag to info.plist Feature flag "AsyncStorage_excludeFromBackup" in info.plist will enable/disable exclusion from iCloud storage. Excluded by default. --- ios/RNCAsyncStorage.m | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/ios/RNCAsyncStorage.m b/ios/RNCAsyncStorage.m index 50dc5c7d..32f60e11 100644 --- a/ios/RNCAsyncStorage.m +++ b/ios/RNCAsyncStorage.m @@ -34,7 +34,7 @@ } } -static BOOL RCTAsyncStorageSetBackupEnabled(NSString* path, BOOL isEnabled) +static BOOL RCTAsyncStorageSetExcludedFromBackup(NSString* path, NSNumber* isExcluded) { NSFileManager *fileManager = [[NSFileManager alloc] init]; @@ -45,7 +45,7 @@ static BOOL RCTAsyncStorageSetBackupEnabled(NSString* path, BOOL isEnabled) if (isDir && exists) { NSURL* pathUrl = [NSURL fileURLWithPath:path]; NSError *error = nil; - success = [pathUrl setResourceValue:@(isEnabled) forKey:NSURLIsExcludedFromBackupKey error:&error]; + success = [pathUrl setResourceValue:isExcluded forKey:NSURLIsExcludedFromBackupKey error:&error]; if (!success) { NSLog(@"Could not exclude AsyncStorage dir from backup %@", error); @@ -340,9 +340,6 @@ - (instancetype)init // Then migrate what's in "Documents/.../RCTAsyncLocalStorage_V1" to "Application Support/[bundleID]/RCTAsyncLocalStorage_V1" RCTStorageDirectoryMigrationCheck(RCTCreateStorageDirectoryPath_deprecated(RCTStorageDirectory), RCTCreateStorageDirectoryPath(RCTStorageDirectory), NO); - - // todo: decide how to read the flag - //RCTAsyncStorageSetBackupEnabled(RCTCreateStorageDirectoryPath(RCTStorageDirectory), false); return self; } @@ -414,8 +411,17 @@ - (NSDictionary *)_ensureSetup } RCTHasCreatedStorageDirectory = YES; } - + if (!_haveSetup) { + // iCloud backup exclusion + NSNumber* isExcludedFromBackup = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AsyncStorage_excludeFromBackup"]; + if(isExcludedFromBackup == nil) { + // by default, we want to exclude AsyncStorage data from backup + isExcludedFromBackup = @YES; + } + RCTAsyncStorageSetExcludedFromBackup(RCTCreateStorageDirectoryPath(RCTStorageDirectory), isExcludedFromBackup); + + NSDictionary *errorOut = nil; NSString *serialized = RCTReadFile(RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()), RCTManifestFileName, &errorOut); if (!serialized) { From c6a65408827376fc5a4deeaaa1d0b5ae5bcbe1df Mon Sep 17 00:00:00 2001 From: Krzysztof Borowy Date: Sat, 17 Oct 2020 13:24:46 +0200 Subject: [PATCH 4/6] fix: review --- ios/RNCAsyncStorage.m | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ios/RNCAsyncStorage.m b/ios/RNCAsyncStorage.m index 32f60e11..6a268fb7 100644 --- a/ios/RNCAsyncStorage.m +++ b/ios/RNCAsyncStorage.m @@ -340,7 +340,7 @@ - (instancetype)init // Then migrate what's in "Documents/.../RCTAsyncLocalStorage_V1" to "Application Support/[bundleID]/RCTAsyncLocalStorage_V1" RCTStorageDirectoryMigrationCheck(RCTCreateStorageDirectoryPath_deprecated(RCTStorageDirectory), RCTCreateStorageDirectoryPath(RCTStorageDirectory), NO); - + return self; } @@ -411,17 +411,16 @@ - (NSDictionary *)_ensureSetup } RCTHasCreatedStorageDirectory = YES; } - + if (!_haveSetup) { // iCloud backup exclusion - NSNumber* isExcludedFromBackup = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AsyncStorage_excludeFromBackup"]; - if(isExcludedFromBackup == nil) { + NSNumber* isExcludedFromBackup = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"RCTAsyncStorageExcludeFromBackup"]; + if (isExcludedFromBackup == nil) { // by default, we want to exclude AsyncStorage data from backup isExcludedFromBackup = @YES; } RCTAsyncStorageSetExcludedFromBackup(RCTCreateStorageDirectoryPath(RCTStorageDirectory), isExcludedFromBackup); - NSDictionary *errorOut = nil; NSString *serialized = RCTReadFile(RCTCreateStorageDirectoryPath(RCTGetManifestFilePath()), RCTManifestFileName, &errorOut); if (!serialized) { From 50a73df0a39c6eb075a274945746b5dd15998947 Mon Sep 17 00:00:00 2001 From: Krzysztof Borowy Date: Sun, 18 Oct 2020 22:03:30 +0200 Subject: [PATCH 5/6] docs: feature description --- example/ios/AsyncStorageExample/Info.plist | 2 ++ website/docs/advanced/Backup.md | 29 +++++++++++++++++++ .../docs/advanced/BrownfieldIntegration.md | 18 +----------- website/docs/advanced/DedicatedExecutor.md | 17 +---------- website/docs/advanced/IncreaseDbSize.md | 18 +----------- website/sidebars.js | 4 +-- website/src/components/Platform.js | 20 +++++++++++++ 7 files changed, 56 insertions(+), 52 deletions(-) create mode 100644 website/docs/advanced/Backup.md create mode 100644 website/src/components/Platform.js diff --git a/example/ios/AsyncStorageExample/Info.plist b/example/ios/AsyncStorageExample/Info.plist index 7ac62b4f..5135a604 100644 --- a/example/ios/AsyncStorageExample/Info.plist +++ b/example/ios/AsyncStorageExample/Info.plist @@ -2,6 +2,8 @@ + RCTAsyncStorageExcludeFromBackup + CFBundleDevelopmentRegion en CFBundleDisplayName diff --git a/website/docs/advanced/Backup.md b/website/docs/advanced/Backup.md new file mode 100644 index 00000000..b9ad4e41 --- /dev/null +++ b/website/docs/advanced/Backup.md @@ -0,0 +1,29 @@ +--- +id: backup +title: Database backup exclusion +sidebar_label: iCloud backup +--- +import PlatformSupport from "../../src/components/Platform.js" + +**Supported platforms:** + + +--- + +Async Storage stores data in `Application Support` directory, which is backed up by iCloud by default. +This can lead to unintentional behavior where data is persisted even after an app re-installation. + +Async Storage disables that feature by default. + +In order to enable iCloud backup, open your app's `info.plist` and add **boolean** entry called **RCTAsyncStorageExcludeFromBackup** and set its value to **NO** (NO as no for exclusion) + + +```diff ++ RCTAsyncStorageExcludeFromBackup ++ +``` + + + + +--- diff --git a/website/docs/advanced/BrownfieldIntegration.md b/website/docs/advanced/BrownfieldIntegration.md index e4a6f692..ee40df01 100644 --- a/website/docs/advanced/BrownfieldIntegration.md +++ b/website/docs/advanced/BrownfieldIntegration.md @@ -3,6 +3,7 @@ id: brownfield title: Brownfield integration sidebar_label: Brownfield integration --- +import PlatformSupport from "../../src/components/Platform.js" **Supported platforms:** @@ -109,20 +110,3 @@ Called by `getItem` and `multiGet` in JS. **Optional:** Returns whether the delegate should be treated as a passthrough. This is useful for monitoring storage usage among other things. Returns `NO` by default. - - - - -export const PlatformSupport = ({platformIcon, title}) => ( -
- -

{title}

-
- ); diff --git a/website/docs/advanced/DedicatedExecutor.md b/website/docs/advanced/DedicatedExecutor.md index 197309f5..eed6cba6 100644 --- a/website/docs/advanced/DedicatedExecutor.md +++ b/website/docs/advanced/DedicatedExecutor.md @@ -3,6 +3,7 @@ id: executor title: Dedicator Thread Executor sidebar_label: Dedicated Executor --- +import PlatformSupport from "../../src/components/Platform.js" **Supported platforms:** @@ -27,19 +28,3 @@ Add a `AsyncStorage_dedicatedExecutor` property to your `android/gradle.properti ``` AsyncStorage_dedicatedExecutor=true ``` - - - -export const PlatformSupport = ({platformIcon, title}) => ( -
- -

{title}

-
- ); diff --git a/website/docs/advanced/IncreaseDbSize.md b/website/docs/advanced/IncreaseDbSize.md index 349ee30d..4ffadb05 100644 --- a/website/docs/advanced/IncreaseDbSize.md +++ b/website/docs/advanced/IncreaseDbSize.md @@ -3,7 +3,7 @@ id: db_size title: Increasing Storage size sidebar_label: Storage space increase --- - +import PlatformSupport from "../../src/components/Platform.js" **Supported platforms:** @@ -21,19 +21,3 @@ AsyncStorage_db_size_in_MB=10 ``` Now you can define the new size in MB. In this example, the new limit is 10 MB. - - - -export const PlatformSupport = ({platformIcon, title}) => ( -
- -

{title}

-
- ); diff --git a/website/sidebars.js b/website/sidebars.js index 5c16ecb0..3646e727 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -1,7 +1,7 @@ module.exports = { docs: { 'Getting started': ['install', 'usage', 'link', 'api'], - Advanced: ['advanced/jest', 'advanced/brownfield', 'advanced/executor', 'advanced/db_size'], - Help: ['help/troubleshooting'] + Advanced: ['advanced/jest', 'advanced/brownfield', 'advanced/backup', 'advanced/executor', 'advanced/db_size'], + Help: ['help/troubleshooting'], }, }; diff --git a/website/src/components/Platform.js b/website/src/components/Platform.js new file mode 100644 index 00000000..a69afff4 --- /dev/null +++ b/website/src/components/Platform.js @@ -0,0 +1,20 @@ +import React from "react"; + +const PlatformSupport = ({ platformIcon, title }) => ( +
+ +

{title}

+
+); + +export default PlatformSupport; From 67f7cd3ee4b5507a5b5a11df35a2be4f6bd96710 Mon Sep 17 00:00:00 2001 From: Krzysztof Borowy Date: Mon, 19 Oct 2020 09:51:38 +0200 Subject: [PATCH 6/6] docs: correction --- website/docs/advanced/Backup.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/website/docs/advanced/Backup.md b/website/docs/advanced/Backup.md index b9ad4e41..a7dcc67f 100644 --- a/website/docs/advanced/Backup.md +++ b/website/docs/advanced/Backup.md @@ -15,15 +15,10 @@ This can lead to unintentional behavior where data is persisted even after an ap Async Storage disables that feature by default. -In order to enable iCloud backup, open your app's `info.plist` and add **boolean** entry called **RCTAsyncStorageExcludeFromBackup** and set its value to **NO** (NO as no for exclusion) - +In order to enable iCloud backup, open your app's `info.plist` in Xcode and add **boolean** entry called **RCTAsyncStorageExcludeFromBackup** and set its value to **NO** (NO as no for exclusion). +Alternatively, you can open `info.plist` in editor and add new entry: ```diff + RCTAsyncStorageExcludeFromBackup + ``` - - - - ----