diff --git a/CHANGELOG.md b/CHANGELOG.md index cbfd5a354e..defebf08b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ x.y.z Release notes (yyyy-MM-dd) * The `baseURL` field of `AppConfiguration` can now be updated, rather than the value being persisted between runs of the application in the metadata storage. ([Core #7201](https://github.com/realm/realm-core/issues/7201)) +* Allow in-memory synced Realms. This will allow setting an in-memory identifier on + a flexible sync realm. ### Fixed * `@Persisted`'s Encodable implementation did not allow the encoder to @@ -9393,7 +9395,7 @@ Prebuilt frameworks are now built with Xcode 7.1. the properties in a `RLMObject` subclass. * Fix crash on IN query with several thousand items. * Fix crash when querying indexed `NSString` properties. -* Fixed an issue which prevented in-memory Realms from being used accross multiple threads. +* Fixed an issue which prevented in-memory Realms from being used across multiple threads. * Preserve the sort order when querying a sorted `RLMResults`. * Fixed an issue with migrations where if a Realm file is deleted after a Realm is initialized, the newly created Realm can be initialized with an incorrect schema version. diff --git a/Realm/ObjectServerTests/AsyncSyncTests.swift b/Realm/ObjectServerTests/AsyncSyncTests.swift index 64b6d734bc..74bf5fece5 100644 --- a/Realm/ObjectServerTests/AsyncSyncTests.swift +++ b/Realm/ObjectServerTests/AsyncSyncTests.swift @@ -514,6 +514,52 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase { checkCount(expected: 10, realm, SwiftPerson.self) } + @MainActor + func testFlexibleSyncInitInMemory() async throws { + try await populateSwiftPerson(5) + + let user = try await createUser() + try await Task { + var config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in + subs.append(QuerySubscription { + $0.age > 0 && $0.firstName == self.name + }) + }) + config.objectTypes = [SwiftPerson.self] + config.inMemoryIdentifier = "identifier" + let inMemoryRealm = try await Realm(configuration: config, downloadBeforeOpen: .always) + XCTAssertEqual(inMemoryRealm.objects(SwiftPerson.self).count, 5) + try! inMemoryRealm.write { + let person = SwiftPerson(firstName: self.name, + lastName: "lastname_10", + age: 10) + inMemoryRealm.add(person) + } + XCTAssertEqual(inMemoryRealm.objects(SwiftPerson.self).count, 6) + try await inMemoryRealm.syncSession?.wait(for: .upload) + }.value + + var config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in + subs.append(QuerySubscription { + $0.age > 5 && $0.firstName == self.name + }) + }) + config.objectTypes = [SwiftPerson.self] + config.inMemoryIdentifier = "identifier" + let inMemoryRealm = try await Realm(configuration: config, downloadBeforeOpen: .always) + XCTAssertEqual(inMemoryRealm.objects(SwiftPerson.self).count, 1) + + var config2 = user.flexibleSyncConfiguration(initialSubscriptions: { subs in + subs.append(QuerySubscription { + $0.age > 0 && $0.firstName == self.name + }) + }) + config2.objectTypes = [SwiftPerson.self] + config2.inMemoryIdentifier = "identifier2" + let inMemoryRealm2 = try await Realm(configuration: config2, downloadBeforeOpen: .always) + XCTAssertEqual(inMemoryRealm2.objects(SwiftPerson.self).count, 6) + } + @MainActor func testStates() async throws { let realm = try await openRealm() diff --git a/Realm/RLMRealmConfiguration.h b/Realm/RLMRealmConfiguration.h index d09e5c215b..fadefa9b07 100644 --- a/Realm/RLMRealmConfiguration.h +++ b/Realm/RLMRealmConfiguration.h @@ -80,8 +80,8 @@ typedef void(^RLMFlexibleSyncInitialSubscriptionsBlock)(RLMSyncSubscriptionSet * @property (nonatomic, copy, nullable) NSURL *fileURL; /// A string used to identify a particular in-memory Realm. Mutually exclusive with `fileURL`, -/// `seedFilePath`and `syncConfiguration`; -/// setting any one of the three properties will automatically nil out the other two. +/// `seedFilePath`. +/// setting an in-memory identifier will automatically nil out the other two. @property (nonatomic, copy, nullable) NSString *inMemoryIdentifier; /// A 64-byte key to use to encrypt the data, or `nil` if encryption is not enabled. diff --git a/Realm/RLMRealmConfiguration.mm b/Realm/RLMRealmConfiguration.mm index 692922b550..bfeeadace7 100644 --- a/Realm/RLMRealmConfiguration.mm +++ b/Realm/RLMRealmConfiguration.mm @@ -174,7 +174,6 @@ - (void)setInMemoryIdentifier:(NSString *)inMemoryIdentifier { if (inMemoryIdentifier.length == 0) { @throw RLMException(@"In-memory identifier must not be empty"); } - _config.sync_config = nullptr; _seedFilePath = nil; RLMNSStringToStdString(_config.path, [NSTemporaryDirectory() stringByAppendingPathComponent:inMemoryIdentifier]); @@ -367,7 +366,6 @@ - (void)setSyncConfiguration:(RLMSyncConfiguration *)syncConfiguration { } NSAssert(user.identifier, @"Cannot call this method on a user that doesn't have an identifier."); - _config.in_memory = false; _config.sync_config = std::make_shared(syncConfiguration.rawConfiguration); _config.path = syncConfiguration.path; diff --git a/RealmSwift/RealmConfiguration.swift b/RealmSwift/RealmConfiguration.swift index fdec05b357..226d82193f 100644 --- a/RealmSwift/RealmConfiguration.swift +++ b/RealmSwift/RealmConfiguration.swift @@ -51,8 +51,9 @@ extension Realm { /** Creates a `Configuration` which can be used to create new `Realm` instances. - - note: The `fileURL`, `inMemoryIdentifier`, and `syncConfiguration` parameters are mutually exclusive. Only + - note: The `fileURL`, and `inMemoryIdentifier`, parameters are mutually exclusive. Only set one of them, or none if you wish to use the default file URL. + Synced Realms will set a unique file path unless is an in-memory realm. - parameter fileURL: The local URL to the Realm file. - parameter inMemoryIdentifier: A string used to identify a particular in-memory Realm. @@ -106,15 +107,13 @@ extension Realm { // MARK: Configuration Properties /** - A configuration value used to configure a Realm for synchronization with Atlas App Services. Mutually - exclusive with `inMemoryIdentifier`. + A configuration value used to configure a Realm for synchronization with Atlas App Services. */ public var syncConfiguration: SyncConfiguration? { get { return _syncConfiguration } set { - _inMemoryIdentifier = nil _syncConfiguration = newValue } } @@ -128,15 +127,13 @@ extension Realm { } } - /// A string used to identify a particular in-memory Realm. Mutually exclusive with `fileURL` and - /// `syncConfiguration`. + /// A string used to identify a particular in-memory Realm. Mutually exclusive with `fileURL`. public var inMemoryIdentifier: String? { get { return _inMemoryIdentifier } set { fileURL = nil - _syncConfiguration = nil _inMemoryIdentifier = newValue } }