Releases: realm/realm-swift
v10.39.0
Enhancements
-
Add support for actor-isolated Realms, opened with
try await Realm(actor: actor)
.Rather than being confined to the current thread or a dispatch queue, actor-isolated Realms are isolated to an actor. This means that they can be used from any thread as long as it's within a function isolated to that actor, and they remain valid over suspension points where a task may hop between threads. Actor-isolated Realms can be used with either global or local actors:
@MainActor function mainThreadFunction() async throws { // These are identical: the async init continues to produce a // MainActor-confined Realm if no actor is supplied let realm1 = try await Realm() let realm2 = try await Realm(MainActor.shared) } // A simple example of a custom global actor @globalActor actor BackgroundActor: GlobalActor { static var shared = BackgroundActor() } @BackgroundActor backgroundThreadFunction() async throws { // Explicitly specifying the actor is required for everything but MainActor let realm = try await Realm(actor: BackgroundActor.shared) try await realm.write { _ = realm.create(MyObject.self) } // Thread-confined Realms would sometimes throw an exception here, as we // may end up on a different thread after an `await` print("\(realm.objects(MyObject.self).count)") } actor MyActor { // An implicitly-unwrapped optional is used here to let us pass `self` to // `Realm(actor:)` within `init` var realm: Realm! init() async throws { realm = try await Realm(actor: self) } var count: Int { realm.objects(MyObject.self).count } func create() async throws { try await realm.asyncWrite { realm.create(MyObject.self) } } } // This function isn't isolated to the actor, so each operation has to be async func createObjects() async throws { let actor = try await MyActor() for _ in 0..<5 { await actor.create() } print("\(await actor.count)") } // In an isolated function, an actor-isolated Realm can be used synchronously func createObjects(in actor: isolated MyActor) async throws { await actor.realm.write { actor.realm.create(MyObject.self) } print("\(actor.realm.objects(MyObject.self).count)") }
Actor-isolated Realms come with a more convenient syntax for asynchronous writes.
try await realm.write { ... }
will suspend the current task, acquire the write lock without blocking the current thread, and then invoke the block. The actual data is then written to disk on a background thread, and the task is resumed once that completes. As this does not block the calling thread while waiting to write and does not perform i/o on the calling thread, this will often be safe to use from@MainActor
functions without blocking the UI. Sufficiently large writes may still benefit from being done on a background thread.Asynchronous writes are only supported for actor-isolated Realms or in
@MainActor
functions.Actor-isolated Realms require Swift 5.8 (Xcode 14.3). Enabling both strict concurrency checking (
SWIFT_STRICT_CONCURRENCY=complete
in Xcode) and runtime actor data race detection (OTHER_SWIFT_FLAGS=-Xfrontend -enable-actor-data-race-checks
) is strongly recommended when using actor-isolated Realms. -
Add support for automatic partition-based to flexible sync migration. Connecting to a server-side app configured to use flexible sync with a client-side partition-based sync configuration is now supported, and will automatically create the appropriate flexible sync subscriptions to subscribe to the requested partition. This allows changing the configuration on the server from partition-based to flexible without breaking existing clients. (Core #6554)
-
Now you can use an array
[["_id": 1], ["breed": 0]]
as sorting option for a MongoCollection. This new API fixes the issue where the resulting documents when using more than one sort parameter were not consistent between calls. (#7188, since v10.0.0). -
Add support for adding a user created default logger, which allows implementing your own logging logic and the log threshold level. You can define your own logger creating an instance of
Logger
and define the log function which will be invoked whenever there is a log message.let logger = Logger(level: .all) { level, message in print("Realm Log - \(level): \(message)") }
Set this custom logger as Realm default logger using
Logger.shared
.Logger.shared = logger
-
It is now possible to change the default log threshold level at any point of the application's lifetime.
Logger.shared.logLevel = .debug
This will override the log level set anytime before by a user created logger.
-
We have set
.info
as the default log threshold level for Realm. You will now see some log message in your console. To disable useLogger.shared.level = .off
.
Fixed
- Several schema initialization functions had incorrect
@MainActor
annotations, resulting in runtime warnings if the first time a Realm was opened was on a background thread (#8222, since v10.34.0).
Deprecations
App.SyncManager.logLevel
andApp.SyncManager.logFunction
are deprecated in favour of setting a default logger.
Compatibility
- Realm Studio: 14.0.1 or later.
- APIs are backwards compatible with all previous releases in the 10.x.y series.
- Carthage release for Swift is built with Xcode 14.3.
- CocoaPods: 1.10 or later.
- Xcode: 13.4-14.3.
Internal
- Upgraded realm-core from v13.9.4 to v13.10.0.
v10.38.3
Enhancements
- Improve performance of cancelling a write transactions after making changes. If no KVO observers are used this is now constant time rather than taking time proportional to the number of changes to be rolled back. Cancelling a write transaction with KVO observers is 10-20% faster. (Core PR #6513).
Fixed
- Performing a large number of queries without ever performing a write resulted in steadily increasing memory usage, some of which was never fully freed due to an unbounded cache (#7978, since v10.27.0).
Compatibility
- Realm Studio: 14.0.1 or later.
- APIs are backwards compatible with all previous releases in the 10.x.y series.
- Carthage release for Swift is built with Xcode 14.3.
- CocoaPods: 1.10 or later.
- Xcode: 13.4-14.3.
Internal
- Upgraded realm-core from 13.9.3 to 13.9.4
v10.38.2
Enhancements
- Improve performance of equality queries on a non-indexed AnyRealmValue
property by about 30%. (Core #6506)
Fixed
- SSL handshake errors were treated as fatal errors rather than errors which
should be retried. (Core #6434, since v10.35.0)
Compatibility
- Realm Studio: 14.0.1 or later.
- APIs are backwards compatible with all previous releases in the 10.x.y series.
- Carthage release for Swift is built with Xcode 14.3.
- CocoaPods: 1.10 or later.
- Xcode: 13.4-14.3.
Internal
- Upgraded realm-core from 13.9.0 to 13.9.3.
v10.38.1
Fixed
- The error handler set on EventsConfiguration was not actually used (since v10.26.0).
Compatibility
- Realm Studio: 13.0.2 or later.
- APIs are backwards compatible with all previous releases in the 10.x.y series.
- Carthage release for Swift is built with Xcode 14.3.
- CocoaPods: 1.10 or later.
- Xcode: 13.4-14.3.
v10.38.0
Switch to building the Carthage release with Xcode 14.3.
Enhancements
- Add Xcode 14.3 binaries to the release package. Note that CocoaPods 1.12.0 does not support Xcode 14.3.
- Add support for sharing encrypted Realms between multiple processes. (Core #1845)
Fixed
- Fix a memory leak reported by Instruments on
URL.path
inRealm.Configuration.fileURL
when using a string partition key in Partition Based Sync (#8195), since v10.0.0). - Fix a data race in version management. If one thread committed a write transaction which increased the number of live versions above the previous highest seen during the current session at the same time as another thread began a read, the reading thread could read from a no-longer-valid memory mapping. This could potentially result in strange crashes when opening, refreshing, freezing or thawing a Realm (Core #6411, since v10.35.0).
Compatibility
- Realm Studio: 13.0.2 or later.
- APIs are backwards compatible with all previous releases in the 10.x.y series.
- Carthage release for Swift is built with Xcode 14.3.
- CocoaPods: 1.10 or later.
- Xcode: 13.4-14.3.
Internal
- Upgraded realm-core from 13.8.0 to 13.9.0.
v10.37.2
Fixed
- Copying a
RLMRealmConfiguration
failed to copy several fields. This resulted in migrations being passed the incorrect object type in Swift when using the default configuration (since v10.34.0) or async open (since v10.37.0). This also broke using the Events API in those two scenarios (since v10.26.0 for default configuration and v10.37.0 for async open). (#8190)
Compatibility
- Realm Studio: 13.0.2 or later.
- APIs are backwards compatible with all previous releases in the 10.x.y series.
- Carthage release for Swift is built with Xcode 14.2.
- CocoaPods: 1.10 or later.
- Xcode: 13.3-14.2.
v10.37.1
Enhancements
- Performance improvement for the following queries (Core #6376):
- Significant (~75%) improvement when counting (
Results.count
) the number of exact matches (with no other query conditions) on a string/int/UUID/ObjectID property that has an index. This improvement will be especially noticeable if there are a large number of results returned (duplicate values). - Significant (~99%) improvement when querying for an exact match on a Date property that has an index.
- Significant (~99%) improvement when querying for a case insensitive match on an AnyRealmValue property that has an index.
- Moderate (~25%) improvement when querying for an exact match on a Bool property that has an index.
- Small (~5%) improvement when querying for a case insensitive match on an AnyRealmValue property that does not have an index.
- Significant (~75%) improvement when counting (
Fixed
- Add missing
@Sendable
annotations to several sync and app services related callbacks (PR #8169, since v10.34.0). - Fix some bugs in handling task cancellation for async Realm init. Some very specific timing windows could cause crashes, and the download would not be cancelled if the Realm was already open (PR #8178, since v10.37.0).
- Fix a crash when querying an AnyRealmValue property with a string operator (contains/like/beginswith/endswith) or with case insensitivity. (Core #6376, since v10.8.0)
- Querying for case-sensitive equality of a string on an indexed AnyRealmValue property was returning case insensitive matches. For example querying for
myIndexedAny == "Foo"
would incorrectly match on values of "foo" or "FOO" etc. (Core #6376, since v10.8.0) - Adding an index to an AnyRealmValue property when objects of that type already existed would crash with an assertion. (Core #6376, since v10.8.0).
- Fix a bug that may have resulted in arrays being in different orders on different devices. Some cases of “Invalid prior_size” may be fixed too. (Core #6191, since v10.25.0).
Compatibility
- Realm Studio: 13.0.2 or later.
- APIs are backwards compatible with all previous releases in the 10.x.y series.
- Carthage release for Swift is built with Xcode 14.2.
- CocoaPods: 1.10 or later.
- Xcode: 13.3-14.2.
Internal
- Upgraded realm-core from 13.6.0 to 13.8.0
v10.37.0
Enhancements
MongoCollection.watch().subscribe(on:)
now supports any swift Scheduler rather than only dispatch queues (PR #8131).- Add an async sequence wrapper for
MongoCollection.watch()
, allowing you to dofor try await change in collection.changeEvents { ... }
(PR #8131). - The internals of error handling and reporting have been significantly reworked. The visible effects of this are that some errors which previously had unhelpful error messages now include more detail about what went wrong, and App errors now expose a much more complete set of error codes (PR #8002).
- Expose compensating write error information. When the server rejects a modification made by the client (such as if the user does not have the required permissions), a
SyncError
is delivered to the sync error handler with the code.writeRejected
and a non-nilcompensatingWriteInfo
field which contains information about what was rejected and why. This information is intended primarily for debugging and logging purposes and may not have a stable format. (PR #8002) - Async
Realm.init()
now handles Task cancellation and will cancel the async open if the Task is cancelled (PR #8148). - Cancelling async opens now has more consistent behavior. The previously intended and documented behavior was that cancelling an async open would result in the callback associated with the specific task that was cancelled never being called, and all other pending callbacks would be invoked with an ECANCELED error. This never actually worked correctly, and the callback which was not supposed to be invoked at all sometimes would be. We now unconditionally invoke all of the exactly once, passing ECANCELED to all of them (PR #8148).
Fixed
UserPublisher
incorrectly bounced all notifications to the main thread instead of setting up the Combine publisher to correctly receive on the main thread. (#8132, since 10.21.0)- Fix warnings when building with Xcode 14.3 beta 2.
- Errors in async open resulting from invalid queries in
initialSubscriptions
would result in the callback being invoked with both a non-nil Realm and a non-nil Error even though the Realm was in an invalid state. Now only the error is passed to the callback (PR #8148, since v10.28.0). - Converting a local realm to a synced realm would crash if an embedded object was null (Core #6294, since v10.22.0).
- Subqueries on indexed properties performed extremely poorly. (Core #6327, since v5.0.0)
- Fix a crash when a SSL read successfully read a non-zero number of bytes and also reported an error. (Core #5435, since 10.0.0)
- The sync client could get stuck in an infinite loop if the server sent an invalid changeset which caused a transform error. This now results in a client reset instead. (Core #6051, since v10.0.0)
- Strings in queries which contained any characters which required multiple bytes when encoded as utf-8 were incorrectly encoded as binary data when serializing the query to send it to the server for a flexible sync subscription, resulting the server rejecting the query (Core #6350, since 10.22.0).
Compatibility
- Realm Studio: 13.0.2 or later.
- APIs are backwards compatible with all previous releases in the 10.x.y series.
- Carthage release for Swift is built with Xcode 14.2.
- CocoaPods: 1.10 or later.
- Xcode: 13.3-14.2.
Internal
- Upgraded realm-core from 13.4.1 to 13.6.0
v10.36.0
Enhancements
- Add support for multiple overlapping or nested event scopes.
Events.beginScope()
now returns aScope
object which is used to commit or cancel that scope, and if more than one scope is active at a time events are reported to all active scopes.
Fixed
- Fix moving
List
items to a higher index in SwiftUI results in wrong destination index (#7956, since v10.6.0). - Using the
searchable
view modifier with@ObservedResults
in iOS 16 would cause the collection observation subscription to cancel. (#8096, since 10.21.0) - Client reset with recovery would sometimes crash if the recovery resurrected a dangling link (Core #6292, since v10.32.0).
Compatibility
- Realm Studio: 13.0.2 or later.
- APIs are backwards compatible with all previous releases in the 10.x.y series.
- Carthage release for Swift is built with Xcode 14.2.
- CocoaPods: 1.10 or later.
- Xcode: 13.3-14.2.
Internal
- Upgraded realm-core from 13.4.0 to 13.4.1
v10.35.1
Fixed
- Client reset with recovery would crash if a client reset occurred the very first time the Realm was opened with async open. The client reset callbacks are now not called if the Realm had never been opened before (PR #8125, since 10.32.0).
Compatibility
- Realm Studio: 13.0.2 or later.
- APIs are backwards compatible with all previous releases in the 10.x.y series.
- Carthage release for Swift is built with Xcode 14.2.
- CocoaPods: 1.10 or later.
- Xcode: 13.3-14.2.