From 50b0e4c66d1957d2dbd156322ff13fdd4bfc8621 Mon Sep 17 00:00:00 2001 From: danibonilha Date: Tue, 5 Nov 2024 18:02:36 -0300 Subject: [PATCH 1/9] Add option to exclude Realm file from iCloud backup --- packages/realm/bindgen/js_opt_in_spec.yml | 2 ++ packages/realm/bindgen/js_spec.yml | 1 + .../binding/android/src/main/cpp/platform.cpp | 2 ++ packages/realm/binding/apple/platform.mm | 17 +++++++++++++++++ packages/realm/binding/node/platform.cpp | 5 +++++ packages/realm/binding/platform.hpp | 4 ++++ packages/realm/src/Configuration.ts | 6 ++++++ packages/realm/src/Realm.ts | 5 ++++- 8 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/realm/bindgen/js_opt_in_spec.yml b/packages/realm/bindgen/js_opt_in_spec.yml index ef80c1274e..86b4a53626 100644 --- a/packages/realm/bindgen/js_opt_in_spec.yml +++ b/packages/realm/bindgen/js_opt_in_spec.yml @@ -51,6 +51,7 @@ records: - initialization_function - should_compact_on_launch_function - automatically_handle_backlinks_in_migrations + - exclude_from_icloud_backup UserIdentity: fields: @@ -238,6 +239,7 @@ classes: - remove_file - remove_directory - get_cpu_arch + - after_realm_open WeakSyncSession: methods: diff --git a/packages/realm/bindgen/js_spec.yml b/packages/realm/bindgen/js_spec.yml index b6e9f28542..a7b74a62e4 100644 --- a/packages/realm/bindgen/js_spec.yml +++ b/packages/realm/bindgen/js_spec.yml @@ -15,6 +15,7 @@ classes: remove_file: '(path: const std::string&)' remove_directory: '(path: const std::string&)' get_cpu_arch: () -> std::string + after_realm_open: '(sharedRealm: std::shared_ptr)' # print: (const char* fmt, ...) # can't expose varargs directly. Could expose a fixed overload. WeakSyncSession: diff --git a/packages/realm/binding/android/src/main/cpp/platform.cpp b/packages/realm/binding/android/src/main/cpp/platform.cpp index 01072cf74a..b7766d12aa 100644 --- a/packages/realm/binding/android/src/main/cpp/platform.cpp +++ b/packages/realm/binding/android/src/main/cpp/platform.cpp @@ -115,6 +115,8 @@ void JsPlatformHelpers::print(const char* fmt, ...) va_end(vl); } +void JsPlatformHelpers::after_realm_open(const std::shared_ptr) {} + std::string JsPlatformHelpers::get_cpu_arch() { #if defined(__arm__) diff --git a/packages/realm/binding/apple/platform.mm b/packages/realm/binding/apple/platform.mm index 9df0ba724e..2fd07d4102 100644 --- a/packages/realm/binding/apple/platform.mm +++ b/packages/realm/binding/apple/platform.mm @@ -18,6 +18,7 @@ #include "../platform.hpp" +#include #include #include @@ -35,6 +36,10 @@ return error.localizedDescription; } +static void RLMAddSkipBackupAttributeToItemAtPath(std::string_view path) { + [[NSURL fileURLWithPath:@(path.data())] setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil]; +} + static std::string s_default_realm_directory; namespace realm { @@ -158,6 +163,18 @@ } } +void JsPlatformHelpers::after_realm_open(const std::shared_ptr sharedRealm) { + if(sharedRealm->config().exclude_from_icloud_backup) { + RLMAddSkipBackupAttributeToItemAtPath(sharedRealm->config().path); + RLMAddSkipBackupAttributeToItemAtPath(sharedRealm->config().path + + ".lock"); + RLMAddSkipBackupAttributeToItemAtPath(sharedRealm->config().path + + ".note"); + RLMAddSkipBackupAttributeToItemAtPath(sharedRealm->config().path + + ".management"); + } +} + void JsPlatformHelpers::remove_directory(const std::string &path) { remove_file(path); // works for directories too diff --git a/packages/realm/binding/node/platform.cpp b/packages/realm/binding/node/platform.cpp index da75d9217f..b5c4288a96 100644 --- a/packages/realm/binding/node/platform.cpp +++ b/packages/realm/binding/node/platform.cpp @@ -219,6 +219,11 @@ void JsPlatformHelpers::print(const char* fmt, ...) va_end(vl); } +void JsPlatformHelpers::after_realm_open(const std::shared_ptr) +{ + // no-op +} + // this should never be called std::string JsPlatformHelpers::get_cpu_arch() { diff --git a/packages/realm/binding/platform.hpp b/packages/realm/binding/platform.hpp index 66d5d3e451..b45a8d209f 100644 --- a/packages/realm/binding/platform.hpp +++ b/packages/realm/binding/platform.hpp @@ -19,6 +19,7 @@ #pragma once #include +#include "realm/object-store/shared_realm.hpp" namespace realm { // @@ -54,5 +55,8 @@ class JsPlatformHelpers { // print something static void print(const char* fmt, ...); + + // runs after the realm has been opened + static void after_realm_open(const std::shared_ptr sharedRealm); }; } // namespace realm diff --git a/packages/realm/src/Configuration.ts b/packages/realm/src/Configuration.ts index 76638578f0..b06fc17386 100644 --- a/packages/realm/src/Configuration.ts +++ b/packages/realm/src/Configuration.ts @@ -160,6 +160,12 @@ export type BaseConfiguration = { */ onFirstOpen?: (realm: Realm) => void; migrationOptions?: MigrationOptions; + /** + * Specifies if this Realm should be excluded from iCloud backup. + * @default false + * @since 12.13.3 + */ + excludeFromIcloudBackup?: boolean; }; export type ConfigurationWithSync = BaseConfiguration & { diff --git a/packages/realm/src/Realm.ts b/packages/realm/src/Realm.ts index 748556265c..8bb3ec086b 100644 --- a/packages/realm/src/Realm.ts +++ b/packages/realm/src/Realm.ts @@ -423,13 +423,14 @@ export class Realm { const normalizedSchema = config.schema && normalizeRealmSchema(config.schema); const schemaExtras = Realm.extractRealmSchemaExtras(normalizedSchema || []); const path = Realm.determinePath(config); - const { fifoFilesFallbackPath, shouldCompact, inMemory } = config; + const { fifoFilesFallbackPath, shouldCompact, inMemory, excludeFromIcloudBackup } = config; const bindingSchema = normalizedSchema && toBindingSchema(normalizedSchema); return { schemaExtras, bindingConfig: { path, cache: true, + excludeFromIcloudBackup, fifoFilesFallbackPath, schema: bindingSchema, inMemory: inMemory === true, @@ -579,6 +580,8 @@ export class Realm { this.schemaExtras = schemaExtras || {}; } + binding.JsPlatformHelpers.afterRealmOpen(this.internal); + Object.defineProperty(this, "classes", { enumerable: false, configurable: false, From 4e8a077319f509b02852217b046b52f5662a6072 Mon Sep 17 00:00:00 2001 From: danibonilha Date: Wed, 6 Nov 2024 10:26:20 -0300 Subject: [PATCH 2/9] Remove reference to deleted guide --- contrib/building.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contrib/building.md b/contrib/building.md index 96b28615a9..fb431d7e67 100644 --- a/contrib/building.md +++ b/contrib/building.md @@ -384,9 +384,8 @@ export NVM_DIR="$HOME/.nvm" ## Testing against real apps -There are a couple of suggested workflows for testing your changes to Realm JS against real apps: +Here's the suggested workflow for testing your changes to Realm JS against real apps: -- [Guide: Setting up watchman to copy changes from this package to an app](guide-watchman.md) - [Guide: Testing your changes against sample apps using a script](guide-testing-with-sample-apps.md) ## Debugging From 352eb10eeb298eaf6d30376b6b5705ab3ae136c9 Mon Sep 17 00:00:00 2001 From: danibonilha Date: Wed, 6 Nov 2024 11:47:37 -0300 Subject: [PATCH 3/9] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ce1cba826..72e772395f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ * None ### Enhancements -* None +* Added option to exclude realm files from iCloud backup ([#4139](https://github.com/realm/realm-js/issues/4139)) ### Fixed * ([#????](https://github.com/realm/realm-js/issues/????), since v?.?.?) From e7e54aec25e03aa4be873382cbbabea629288854 Mon Sep 17 00:00:00 2001 From: danibonilha Date: Thu, 7 Nov 2024 10:40:12 -0300 Subject: [PATCH 4/9] Use better typedef --- packages/realm/bindgen/js_spec.yml | 2 +- .../binding/android/src/main/cpp/platform.cpp | 2 +- packages/realm/binding/apple/platform.mm | 14 ++++++++------ packages/realm/binding/node/platform.cpp | 2 +- packages/realm/binding/platform.hpp | 4 ++-- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/realm/bindgen/js_spec.yml b/packages/realm/bindgen/js_spec.yml index a7b74a62e4..7e4393ea2d 100644 --- a/packages/realm/bindgen/js_spec.yml +++ b/packages/realm/bindgen/js_spec.yml @@ -15,7 +15,7 @@ classes: remove_file: '(path: const std::string&)' remove_directory: '(path: const std::string&)' get_cpu_arch: () -> std::string - after_realm_open: '(sharedRealm: std::shared_ptr)' + after_realm_open: '(realm: SharedRealm)' # print: (const char* fmt, ...) # can't expose varargs directly. Could expose a fixed overload. WeakSyncSession: diff --git a/packages/realm/binding/android/src/main/cpp/platform.cpp b/packages/realm/binding/android/src/main/cpp/platform.cpp index b7766d12aa..a4343e8e7c 100644 --- a/packages/realm/binding/android/src/main/cpp/platform.cpp +++ b/packages/realm/binding/android/src/main/cpp/platform.cpp @@ -115,7 +115,7 @@ void JsPlatformHelpers::print(const char* fmt, ...) va_end(vl); } -void JsPlatformHelpers::after_realm_open(const std::shared_ptr) {} +void JsPlatformHelpers::after_realm_open(const SharedRealm) {} std::string JsPlatformHelpers::get_cpu_arch() { diff --git a/packages/realm/binding/apple/platform.mm b/packages/realm/binding/apple/platform.mm index 2fd07d4102..3a630565f4 100644 --- a/packages/realm/binding/apple/platform.mm +++ b/packages/realm/binding/apple/platform.mm @@ -163,14 +163,16 @@ static void RLMAddSkipBackupAttributeToItemAtPath(std::string_view path) { } } -void JsPlatformHelpers::after_realm_open(const std::shared_ptr sharedRealm) { - if(sharedRealm->config().exclude_from_icloud_backup) { - RLMAddSkipBackupAttributeToItemAtPath(sharedRealm->config().path); - RLMAddSkipBackupAttributeToItemAtPath(sharedRealm->config().path + +void JsPlatformHelpers::after_realm_open(const SharedRealm realm) { + const auto path = realm->config().path; + + if(realm->config().exclude_from_icloud_backup) { + RLMAddSkipBackupAttributeToItemAtPath(path); + RLMAddSkipBackupAttributeToItemAtPath(path + ".lock"); - RLMAddSkipBackupAttributeToItemAtPath(sharedRealm->config().path + + RLMAddSkipBackupAttributeToItemAtPath(path + ".note"); - RLMAddSkipBackupAttributeToItemAtPath(sharedRealm->config().path + + RLMAddSkipBackupAttributeToItemAtPath(path + ".management"); } } diff --git a/packages/realm/binding/node/platform.cpp b/packages/realm/binding/node/platform.cpp index b5c4288a96..17f7f5f1ff 100644 --- a/packages/realm/binding/node/platform.cpp +++ b/packages/realm/binding/node/platform.cpp @@ -219,7 +219,7 @@ void JsPlatformHelpers::print(const char* fmt, ...) va_end(vl); } -void JsPlatformHelpers::after_realm_open(const std::shared_ptr) +void JsPlatformHelpers::after_realm_open(const SharedRealm) { // no-op } diff --git a/packages/realm/binding/platform.hpp b/packages/realm/binding/platform.hpp index b45a8d209f..648a031af2 100644 --- a/packages/realm/binding/platform.hpp +++ b/packages/realm/binding/platform.hpp @@ -19,7 +19,7 @@ #pragma once #include -#include "realm/object-store/shared_realm.hpp" +#include namespace realm { // @@ -57,6 +57,6 @@ class JsPlatformHelpers { static void print(const char* fmt, ...); // runs after the realm has been opened - static void after_realm_open(const std::shared_ptr sharedRealm); + static void after_realm_open(const SharedRealm realm); }; } // namespace realm From 562b01a4b2fa66fb70770586bac9a3886b51f2cb Mon Sep 17 00:00:00 2001 From: danibonilha Date: Thu, 7 Nov 2024 12:02:41 -0300 Subject: [PATCH 5/9] Add flag as param to scope feature to realmJS only --- packages/realm/bindgen/js_opt_in_spec.yml | 1 - packages/realm/bindgen/js_spec.yml | 2 +- packages/realm/binding/android/src/main/cpp/platform.cpp | 2 +- packages/realm/binding/apple/platform.mm | 4 ++-- packages/realm/binding/node/platform.cpp | 2 +- packages/realm/binding/platform.hpp | 2 +- packages/realm/src/Realm.ts | 5 ++--- 7 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/realm/bindgen/js_opt_in_spec.yml b/packages/realm/bindgen/js_opt_in_spec.yml index 86b4a53626..8dc0439138 100644 --- a/packages/realm/bindgen/js_opt_in_spec.yml +++ b/packages/realm/bindgen/js_opt_in_spec.yml @@ -51,7 +51,6 @@ records: - initialization_function - should_compact_on_launch_function - automatically_handle_backlinks_in_migrations - - exclude_from_icloud_backup UserIdentity: fields: diff --git a/packages/realm/bindgen/js_spec.yml b/packages/realm/bindgen/js_spec.yml index 7e4393ea2d..c69f0cb3a0 100644 --- a/packages/realm/bindgen/js_spec.yml +++ b/packages/realm/bindgen/js_spec.yml @@ -15,7 +15,7 @@ classes: remove_file: '(path: const std::string&)' remove_directory: '(path: const std::string&)' get_cpu_arch: () -> std::string - after_realm_open: '(realm: SharedRealm)' + after_realm_open: '(realm: SharedRealm, exclude_from_icloud_backup: bool)' # print: (const char* fmt, ...) # can't expose varargs directly. Could expose a fixed overload. WeakSyncSession: diff --git a/packages/realm/binding/android/src/main/cpp/platform.cpp b/packages/realm/binding/android/src/main/cpp/platform.cpp index a4343e8e7c..29d92d162d 100644 --- a/packages/realm/binding/android/src/main/cpp/platform.cpp +++ b/packages/realm/binding/android/src/main/cpp/platform.cpp @@ -115,7 +115,7 @@ void JsPlatformHelpers::print(const char* fmt, ...) va_end(vl); } -void JsPlatformHelpers::after_realm_open(const SharedRealm) {} +void JsPlatformHelpers::after_realm_open(SharedRealm, bool) {} std::string JsPlatformHelpers::get_cpu_arch() { diff --git a/packages/realm/binding/apple/platform.mm b/packages/realm/binding/apple/platform.mm index 3a630565f4..242fd4447a 100644 --- a/packages/realm/binding/apple/platform.mm +++ b/packages/realm/binding/apple/platform.mm @@ -163,10 +163,10 @@ static void RLMAddSkipBackupAttributeToItemAtPath(std::string_view path) { } } -void JsPlatformHelpers::after_realm_open(const SharedRealm realm) { +void JsPlatformHelpers::after_realm_open(const SharedRealm realm, bool exclude_from_icloud_backup) { const auto path = realm->config().path; - if(realm->config().exclude_from_icloud_backup) { + if(exclude_from_icloud_backup) { RLMAddSkipBackupAttributeToItemAtPath(path); RLMAddSkipBackupAttributeToItemAtPath(path + ".lock"); diff --git a/packages/realm/binding/node/platform.cpp b/packages/realm/binding/node/platform.cpp index 17f7f5f1ff..17ed50d1ae 100644 --- a/packages/realm/binding/node/platform.cpp +++ b/packages/realm/binding/node/platform.cpp @@ -219,7 +219,7 @@ void JsPlatformHelpers::print(const char* fmt, ...) va_end(vl); } -void JsPlatformHelpers::after_realm_open(const SharedRealm) +void JsPlatformHelpers::after_realm_open(SharedRealm, bool) { // no-op } diff --git a/packages/realm/binding/platform.hpp b/packages/realm/binding/platform.hpp index 648a031af2..d9286e3998 100644 --- a/packages/realm/binding/platform.hpp +++ b/packages/realm/binding/platform.hpp @@ -57,6 +57,6 @@ class JsPlatformHelpers { static void print(const char* fmt, ...); // runs after the realm has been opened - static void after_realm_open(const SharedRealm realm); + static void after_realm_open(const SharedRealm realm, const bool exclude_from_icloud_backup = false); }; } // namespace realm diff --git a/packages/realm/src/Realm.ts b/packages/realm/src/Realm.ts index 8bb3ec086b..495f292e1f 100644 --- a/packages/realm/src/Realm.ts +++ b/packages/realm/src/Realm.ts @@ -423,14 +423,13 @@ export class Realm { const normalizedSchema = config.schema && normalizeRealmSchema(config.schema); const schemaExtras = Realm.extractRealmSchemaExtras(normalizedSchema || []); const path = Realm.determinePath(config); - const { fifoFilesFallbackPath, shouldCompact, inMemory, excludeFromIcloudBackup } = config; + const { fifoFilesFallbackPath, shouldCompact, inMemory } = config; const bindingSchema = normalizedSchema && toBindingSchema(normalizedSchema); return { schemaExtras, bindingConfig: { path, cache: true, - excludeFromIcloudBackup, fifoFilesFallbackPath, schema: bindingSchema, inMemory: inMemory === true, @@ -580,7 +579,7 @@ export class Realm { this.schemaExtras = schemaExtras || {}; } - binding.JsPlatformHelpers.afterRealmOpen(this.internal); + binding.JsPlatformHelpers.afterRealmOpen(this.internal, config.excludeFromIcloudBackup ?? false); Object.defineProperty(this, "classes", { enumerable: false, From ed5d0dbfd854ba19028a653286dcdcf072c1b57d Mon Sep 17 00:00:00 2001 From: danibonilha Date: Thu, 7 Nov 2024 13:07:03 -0300 Subject: [PATCH 6/9] Update implementation to enable/disable icloud backup dynamically --- packages/realm/binding/apple/platform.mm | 40 +++++++++++++++--------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/packages/realm/binding/apple/platform.mm b/packages/realm/binding/apple/platform.mm index 242fd4447a..325949a19a 100644 --- a/packages/realm/binding/apple/platform.mm +++ b/packages/realm/binding/apple/platform.mm @@ -36,8 +36,30 @@ return error.localizedDescription; } -static void RLMAddSkipBackupAttributeToItemAtPath(std::string_view path) { - [[NSURL fileURLWithPath:@(path.data())] setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil]; +static void RLMCheckSkipBackupAttributeToItemAtPath(std::string_view path, bool exclude_from_icloud_backup) { + NSNumber *current; + + [[NSURL fileURLWithPath:@(path.data())] + getResourceValue:¤t + forKey:NSURLIsExcludedFromBackupKey + error:nil]; + + if (current.boolValue != exclude_from_icloud_backup) { + [[NSURL fileURLWithPath:@(path.data())] + setResourceValue:@(exclude_from_icloud_backup) + forKey:NSURLIsExcludedFromBackupKey + error:nil]; + + } +} + +static void RLMCheckSkipBackupAttributeToRealmFilesAtPath(std::string path, bool exclude_from_icloud_backup) { + const std::vector extensions = {"", ".lock", ".note", + ".management"}; + + for (const auto& ext : extensions) { + RLMCheckSkipBackupAttributeToItemAtPath(path + ext, exclude_from_icloud_backup); + } } static std::string s_default_realm_directory; @@ -163,18 +185,8 @@ static void RLMAddSkipBackupAttributeToItemAtPath(std::string_view path) { } } -void JsPlatformHelpers::after_realm_open(const SharedRealm realm, bool exclude_from_icloud_backup) { - const auto path = realm->config().path; - - if(exclude_from_icloud_backup) { - RLMAddSkipBackupAttributeToItemAtPath(path); - RLMAddSkipBackupAttributeToItemAtPath(path + - ".lock"); - RLMAddSkipBackupAttributeToItemAtPath(path + - ".note"); - RLMAddSkipBackupAttributeToItemAtPath(path + - ".management"); - } +void JsPlatformHelpers::after_realm_open(const SharedRealm realm, bool exclude_from_icloud_backup) { + RLMCheckSkipBackupAttributeToRealmFilesAtPath(realm->config().path, exclude_from_icloud_backup); } void JsPlatformHelpers::remove_directory(const std::string &path) From d010d8d4d182eec2b8bdfca7ac230483574df06b Mon Sep 17 00:00:00 2001 From: danibonilha Date: Thu, 7 Nov 2024 14:11:29 -0300 Subject: [PATCH 7/9] Add guide and script to check excludeFromBackup attribute --- .../guide-testing-exclude-icloud-backup.md | 50 ++++++++++++++ .../scripts/check-exclude-icloud-backup.sh | 65 +++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 contrib/guide-testing-exclude-icloud-backup.md create mode 100755 contrib/scripts/check-exclude-icloud-backup.sh diff --git a/contrib/guide-testing-exclude-icloud-backup.md b/contrib/guide-testing-exclude-icloud-backup.md new file mode 100644 index 0000000000..fe57cddff1 --- /dev/null +++ b/contrib/guide-testing-exclude-icloud-backup.md @@ -0,0 +1,50 @@ +# Guide: Testing Exclude iCloud Backup + +Before starting the testing process, you need to configure your Realm database to either include or exclude files from iCloud backup. This is done by setting the `excludeFromIcloudBackup` property in your Realm configuration. Here is an example of how to set this property: + +```javascript +const realmConfig = { + schema: [ + /* your schema */ + ], + path: "default.realm", + excludeFromIcloudBackup: true, // Set to true to exclude from iCloud backup, false to include, defaults to false +}; + +const realm = new Realm(realmConfig); +``` + +Make sure to replace the schema and path with your actual Realm schema and desired file path. Once you have configured this property, you can proceed with the following steps to test if the exclusion from iCloud backup is working correctly. + +## Prerequisites + +- macOS +- iOS Simulator + +## Testing + +To verify if a file has been successfully excluded from iCloud backup, you need to check the file's attributes. We provide an easy script to do so. Ensure you have booted a simulator with an app using Realm. From the root of the project, run: + +```sh +contrib/scripts/check-exclude-icloud-backup.sh +``` + +If the script doesn't work, you can also check it manually. First, get the path of the Realm files from the simulator's Documents folder by running: + +```sh +open `xcrun simctl get_app_container booted com.your.app.bundleId data`/Documents +``` + +This will open a Finder window with the files. Drag and drop each file to the terminal after adding `xattr`: + +```sh +xattr +``` + +If this command returns: + +```sh +com.apple.metadata:com_apple_backup_excludeItem +``` + +It means the file has been successfully marked as excluded from backup 🎉. If it returns nothing, the file has no attributes and is not excluded from backup. diff --git a/contrib/scripts/check-exclude-icloud-backup.sh b/contrib/scripts/check-exclude-icloud-backup.sh new file mode 100755 index 0000000000..41d4127697 --- /dev/null +++ b/contrib/scripts/check-exclude-icloud-backup.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Check if appbundle parameter is provided +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +appbundle=$1 + +# Check if a simulator is booted +booted_simulators=$(xcrun simctl list | grep "Booted") + +if [ -z "$booted_simulators" ]; then + echo "No simulator booted. Please boot a simulator with the React Native app running and re-run the script." + exit 1 +fi + +# Count the number of booted simulators +booted_count=$(echo "$booted_simulators" | wc -l) + +if [ "$booted_count" -gt 1 ]; then + echo "More than one simulator is booted. Please keep only one open and re-run the script." + exit 1 +fi + +# Extract the name of the booted simulator +booted_simulator=$(echo "$booted_simulator" | xargs) +echo -e "Running script on simulator: $booted_simulator\n" + +# Get the app container path +app_container_path=$(xcrun simctl get_app_container booted "$appbundle" data 2>/dev/null) + +# Check if the command was successful +if [ $? -ne 0 ] || [ -z "$app_container_path" ]; then + echo "Failed to get app container path for $appbundle" + exit 1 +fi + +# Append /Documents to the path +documents_path="$app_container_path/Documents" + +# Check if the directory exists +if [ ! -d "$documents_path" ]; then + echo "Documents directory does not exist at $documents_path" + exit 1 +fi + +# Run xattr on all files in the directory +for file in "$documents_path"/*; do + if [ -e "$file" ]; then + filename=$(basename "$file") + attrs=$(xattr "$file" 2>/dev/null) + if [ -z "$attrs" ]; then + echo -e "\033[1;33m$filename:\033[0m no attributes set ❌" + else + if echo "$attrs" | grep -q "com_apple_backup_excludeItem"; then + echo -e "\033[0;32m\033[1m$filename:\033[0m: $attrs\033[0;32m ✅\033[0m" + else + echo "$filename: $attrs" + fi + fi + fi +done + From a7cd1bf09f7e64f4f5cd4fff824cb3924f194612 Mon Sep 17 00:00:00 2001 From: danibonilha Date: Thu, 7 Nov 2024 14:20:11 -0300 Subject: [PATCH 8/9] Add missing requirement for android build --- contrib/building.md | 4 +++- packages/realm/binding/apple/platform.mm | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/contrib/building.md b/contrib/building.md index fb431d7e67..7d5c72a7b3 100644 --- a/contrib/building.md +++ b/contrib/building.md @@ -52,6 +52,7 @@ The following dependencies are required. All except Xcode can be installed by fo - [Android NDK 23](https://developer.android.com/ndk/downloads/index.html) - [Android CMake](https://developer.android.com/ndk/guides/cmake) - [Docker](https://www.docker.com/) is used for testing. You can install it [as a desktop app](https://www.docker.com/products/docker-desktop/) or through Homebrew: `brew install --cask docker`. +- [Ninja](https://ninja-build.org/) `brew install ninja` Moreover, in order to avoid introducing false positives in our analytics dataset, it is highly recommended to disable analytics by adding the following to your shell configuration: @@ -83,9 +84,10 @@ brew install cmake #### Android -First, install OpenJDK: +First, install OpenJDK and Ninja: ```sh +brew install ninja brew install --cask temurin # Check this returns: openjdk version "18.0.1" 2022-04-19 diff --git a/packages/realm/binding/apple/platform.mm b/packages/realm/binding/apple/platform.mm index 325949a19a..3408a6aba0 100644 --- a/packages/realm/binding/apple/platform.mm +++ b/packages/realm/binding/apple/platform.mm @@ -18,7 +18,6 @@ #include "../platform.hpp" -#include #include #include From ffc1883c85f3ce59e42049206764b63886274082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Fri, 8 Nov 2024 14:36:58 +0100 Subject: [PATCH 9/9] Update wording in CHANGELOG.md and adding an example --- CHANGELOG.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72e772395f..49d55d2be3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,16 @@ * None ### Enhancements -* Added option to exclude realm files from iCloud backup ([#4139](https://github.com/realm/realm-js/issues/4139)) +* Added `excludeFromIcloudBackup` option to the `Realm` constructor to exclude the realm files from iCloud backup. ([#4139](https://github.com/realm/realm-js/issues/4139)) +```typescript +const realm = new Realm({ + schema: [ + /* your schema */ + ], + // Set to true to exclude from iCloud backup, false to include, defaults to false + excludeFromIcloudBackup: true, +}); +``` ### Fixed * ([#????](https://github.com/realm/realm-js/issues/????), since v?.?.?)