Skip to content

Commit 8c1142c

Browse files
authored
Followup to #6922 refactoring after_realm_open into exclude_from_icloud_backup (#6927)
* Avoid including realm core headers in platform.hpp * Add tests * Update contrib guide and script to reference integration tests * Add note in the changelog
1 parent d5e901b commit 8c1142c

File tree

12 files changed

+125
-69
lines changed

12 files changed

+125
-69
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* None
55

66
### Enhancements
7-
* Added `excludeFromIcloudBackup` option to the `Realm` constructor to exclude the realm files from iCloud backup. ([#4139](https://github.com/realm/realm-js/issues/4139))
7+
* Added `excludeFromIcloudBackup` option to the `Realm` constructor to exclude the realm files from iCloud backup. ([#4139](https://github.com/realm/realm-js/issues/4139) and [#6927](https://github.com/realm/realm-js/pull/6927))
88
```typescript
99
const realm = new Realm({
1010
schema: [

contrib/guide-testing-exclude-icloud-backup.md

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,29 @@
11
# Guide: Testing Exclude iCloud Backup
22

3+
## Prerequisites
4+
5+
- macOS
6+
- iOS Simulator
7+
8+
## Testing
9+
10+
Ensure you have booted a simulator and execute the integration tests on iOS:
11+
12+
```sh
13+
MOCHA_REMOTE_GREP='icloud' npm run test:ios --workspace @realm/react-native-test-app-tests
14+
```
15+
16+
In the command above, we're explicitly grepping for the icloud backup tests.
17+
18+
To verify if a file has been successfully excluded from iCloud backup, you need to check the file's attributes.
19+
We provide an easy script to do so:
20+
21+
```sh
22+
./contrib/scripts/check-exclude-icloud-backup.sh
23+
```
24+
25+
## Testing in your own app
26+
327
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:
428

529
```javascript
@@ -16,20 +40,7 @@ const realm = new Realm(realmConfig);
1640

1741
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.
1842

19-
## Prerequisites
20-
21-
- macOS
22-
- iOS Simulator
23-
24-
## Testing
25-
26-
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:
27-
28-
```sh
29-
contrib/scripts/check-exclude-icloud-backup.sh <com.your.app.bundle>
30-
```
31-
32-
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:
43+
First, get the path of the Realm files from the simulator's Documents folder by running:
3344

3445
```sh
3546
open `xcrun simctl get_app_container booted com.your.app.bundleId data`/Documents

contrib/scripts/check-exclude-icloud-backup.sh

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
#!/bin/bash
22

3-
# Check if appbundle parameter is provided
4-
if [ -z "$1" ]; then
5-
echo "Usage: $0 <com.app.bundle.id>"
6-
exit 1
7-
fi
8-
9-
appbundle=$1
3+
TEST_APP_BUNDLE_ID=com.microsoft.ReactTestApp
104

115
# Check if a simulator is booted
126
booted_simulators=$(xcrun simctl list | grep "Booted")
@@ -25,15 +19,15 @@ if [ "$booted_count" -gt 1 ]; then
2519
fi
2620

2721
# Extract the name of the booted simulator
28-
booted_simulator=$(echo "$booted_simulator" | xargs)
22+
booted_simulator=$(echo "$booted_simulators" | xargs)
2923
echo -e "Running script on simulator: $booted_simulator\n"
3024

3125
# Get the app container path
32-
app_container_path=$(xcrun simctl get_app_container booted "$appbundle" data 2>/dev/null)
26+
app_container_path=$(xcrun simctl get_app_container booted "$TEST_APP_BUNDLE_ID" data 2>/dev/null)
3327

3428
# Check if the command was successful
3529
if [ $? -ne 0 ] || [ -z "$app_container_path" ]; then
36-
echo "Failed to get app container path for $appbundle"
30+
echo "Failed to get app container path for $TEST_APP_BUNDLE_ID"
3731
exit 1
3832
fi
3933

@@ -47,7 +41,7 @@ if [ ! -d "$documents_path" ]; then
4741
fi
4842

4943
# Run xattr on all files in the directory
50-
for file in "$documents_path"/*; do
44+
for file in "$documents_path"/icloud-backup-tests/*.realm; do
5145
if [ -e "$file" ]; then
5246
filename=$(basename "$file")
5347
attrs=$(xattr "$file" 2>/dev/null)

integration-tests/tests/src/tests.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import "./tests/counter";
5454
import "./tests/dictionary";
5555
import "./tests/dynamic-schema-updates";
5656
import "./tests/enums";
57+
import "./tests/exclude-from-icloud-backup";
5758
import "./tests/iterators";
5859
import "./tests/linking-objects";
5960
import "./tests/list";
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
////////////////////////////////////////////////////////////////////////////
2+
//
3+
// Copyright 2024 Realm Inc.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
//
17+
////////////////////////////////////////////////////////////////////////////
18+
19+
import Realm from "realm";
20+
21+
const BASE_PATH = "icloud-backup-tests";
22+
23+
describe("icloud backup", () => {
24+
// This is in a separate suite to avoid
25+
// See contrib/guide-testing-exclude-icloud-backup.md to verify the result of the test
26+
it("excludes", () => {
27+
const realm = new Realm({
28+
path: `${BASE_PATH}/excluded.realm`,
29+
schema: [],
30+
excludeFromIcloudBackup: true,
31+
});
32+
realm.close();
33+
});
34+
35+
it("removes exclusion", () => {
36+
const path = `${BASE_PATH}/reincluded.realm`;
37+
{
38+
const realm = new Realm({
39+
path,
40+
schema: [],
41+
excludeFromIcloudBackup: true,
42+
});
43+
realm.close();
44+
}
45+
{
46+
const realm = new Realm({
47+
path,
48+
excludeFromIcloudBackup: false,
49+
});
50+
realm.close();
51+
}
52+
});
53+
});

packages/realm/bindgen/js_opt_in_spec.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,8 @@ classes:
237237
- remove_realm_files_from_directory
238238
- remove_file
239239
- remove_directory
240+
- exclude_from_icloud_backup
240241
- get_cpu_arch
241-
- after_realm_open
242242

243243
WeakSyncSession:
244244
methods:

packages/realm/bindgen/js_spec.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ classes:
1414
remove_realm_files_from_directory: '(directory: const std::string&)'
1515
remove_file: '(path: const std::string&)'
1616
remove_directory: '(path: const std::string&)'
17+
exclude_from_icloud_backup: '(path: const std::string&, value: bool)'
1718
get_cpu_arch: () -> std::string
18-
after_realm_open: '(realm: SharedRealm, exclude_from_icloud_backup: bool)'
1919
# print: (const char* fmt, ...) # can't expose varargs directly. Could expose a fixed overload.
2020

2121
WeakSyncSession:

packages/realm/binding/android/src/main/cpp/platform.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ void JsPlatformHelpers::remove_file(const std::string& path)
123123
fs::remove(path);
124124
}
125125

126+
void JsPlatformHelpers::exclude_from_icloud_backup(const std::string&, bool)
127+
{
128+
// no-op
129+
}
130+
126131
void JsPlatformHelpers::print(const char* fmt, ...)
127132
{
128133
va_list vl;
@@ -131,8 +136,6 @@ void JsPlatformHelpers::print(const char* fmt, ...)
131136
va_end(vl);
132137
}
133138

134-
void JsPlatformHelpers::after_realm_open(SharedRealm, bool) {}
135-
136139
std::string JsPlatformHelpers::get_cpu_arch()
137140
{
138141
#if defined(__arm__)

packages/realm/binding/apple/platform.mm

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,32 +35,6 @@
3535
return error.localizedDescription;
3636
}
3737

38-
static void RLMCheckSkipBackupAttributeToItemAtPath(std::string_view path, bool exclude_from_icloud_backup) {
39-
NSNumber *current;
40-
41-
[[NSURL fileURLWithPath:@(path.data())]
42-
getResourceValue:&current
43-
forKey:NSURLIsExcludedFromBackupKey
44-
error:nil];
45-
46-
if (current.boolValue != exclude_from_icloud_backup) {
47-
[[NSURL fileURLWithPath:@(path.data())]
48-
setResourceValue:@(exclude_from_icloud_backup)
49-
forKey:NSURLIsExcludedFromBackupKey
50-
error:nil];
51-
52-
}
53-
}
54-
55-
static void RLMCheckSkipBackupAttributeToRealmFilesAtPath(std::string path, bool exclude_from_icloud_backup) {
56-
const std::vector<std::string> extensions = {"", ".lock", ".note",
57-
".management"};
58-
59-
for (const auto& ext : extensions) {
60-
RLMCheckSkipBackupAttributeToItemAtPath(path + ext, exclude_from_icloud_backup);
61-
}
62-
}
63-
6438
static std::string s_default_realm_directory;
6539

6640
namespace realm {
@@ -184,15 +158,28 @@ static void RLMCheckSkipBackupAttributeToRealmFilesAtPath(std::string path, bool
184158
}
185159
}
186160

187-
void JsPlatformHelpers::after_realm_open(const SharedRealm realm, bool exclude_from_icloud_backup) {
188-
RLMCheckSkipBackupAttributeToRealmFilesAtPath(realm->config().path, exclude_from_icloud_backup);
189-
}
190-
191161
void JsPlatformHelpers::remove_directory(const std::string &path)
192162
{
193163
remove_file(path); // works for directories too
194164
}
195165

166+
void JsPlatformHelpers::exclude_from_icloud_backup(const std::string& path, bool value) {
167+
NSNumber *current;
168+
169+
[[NSURL fileURLWithPath:@(path.data())]
170+
getResourceValue:&current
171+
forKey:NSURLIsExcludedFromBackupKey
172+
error:nil];
173+
174+
if (current.boolValue != value) {
175+
[[NSURL fileURLWithPath:@(path.data())]
176+
setResourceValue:@(value)
177+
forKey:NSURLIsExcludedFromBackupKey
178+
error:nil];
179+
180+
}
181+
}
182+
196183
void JsPlatformHelpers::print(const char *fmt, ...) {
197184
va_list vl;
198185
va_start(vl, fmt);

packages/realm/binding/node/platform.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ void JsPlatformHelpers::remove_file(const std::string& path)
209209
}
210210
}
211211

212+
void JsPlatformHelpers::exclude_from_icloud_backup(const std::string&, bool)
213+
{
214+
// no-op
215+
}
216+
212217
void JsPlatformHelpers::print(const char* fmt, ...)
213218
{
214219
va_list vl;
@@ -219,11 +224,6 @@ void JsPlatformHelpers::print(const char* fmt, ...)
219224
va_end(vl);
220225
}
221226

222-
void JsPlatformHelpers::after_realm_open(SharedRealm, bool)
223-
{
224-
// no-op
225-
}
226-
227227
// this should never be called
228228
std::string JsPlatformHelpers::get_cpu_arch()
229229
{

0 commit comments

Comments
 (0)