Skip to content

Releases: realm/realm-dotnet

10.16.0

03 Oct 14:57
a5d560c
Compare
Choose a tag to compare

10.16.0 (2022-10-03)

Enhancements

  • Introduced AsymmetricObject intended for write-heavy workloads, where high performance is generally important. This new object:

    1. syncs data unidirectionaly, from the clients to the server
    2. can't be queried, deleted, or modified once added to the Realm
    3. is only usable with flexible sync
    4. can't be the receiveing end of any type of relationship
    5. can contain EmbeddedObjects but cannot link to RealmObject or AsymmetricObject.

    In the same write transaction, it is legal to add AsymmetricObjects and RealmObjects

    class Measurement : AsymmetricObject
    {
        [PrimaryKey, MapTo("_id")]
        public Guid Id { get; private set; } = Guid.NewGuid();
    
        public double Value { get; set; }
    
        public DataTimeOffset Timestamp { get; private set; } = DateTimeOffset.UtcNow;
    }
    
    class Person : RealmObject
    {
        //............
    }
    
    //.....
    
    var measurement = new Measurement
    {
      Value = 9.876
    };
    
    realm.Write(() =>
    {
        realm.Add(measurement);
    
        realm.Add(new Person());
    });
    
    _ = asymmetricObject.Value;   // runtime error
    _ = realm.All<Measurement>(); // compile time error
  • Added two client reset handlers, RecoverUnsyncedChangesHandler and RecoverOrDiscardUnsyncedChangesHandler, that try to automatically merge the unsynced local changes with the remote ones in the event of a client reset. Specifically with RecoverOrDiscardUnsyncedChangesHandler, you can fallback to the discard local strategy in case the automatic merge can't be performed as per your server's rules. These new two stragegies simplify even more the handling of client reset events when compared to DiscardUnsyncedChangesHandler.RecoverOrDiscardUnsyncedChangesHandler is going to be the default from now on. An example is as follows

  • Added two client reset handlers, RecoverUnsyncedChangesHandler and RecoverOrDiscardUnsyncedChangesHandler, that try to automatically merge the unsynced local changes with the remote ones in the event of a client reset. Specifically with RecoverOrDiscardUnsyncedChangesHandler, you can fallback to the discard unsynced strategy in case the automatic merge can't be performed as per your server's rules. These new two stragegies simplify even more the handling of client reset events when compared to DiscardUnsyncedChangesHandler.RecoverOrDiscardUnsyncedChangesHandler is going to be the default from now on. More info on the aforementioned strategies can be found in our docs page. An example usage of one of the new handler is as follows:

    var conf = new PartitionSyncConfiguration(partition, user)
    {
      ClientResetHandler = new RecoverOrDiscardUnsyncedChangesHandler
      {
        // As always, the following callbacks are optional
    
        OnBeforeReset = (beforeFrozen) =>
        {
          // executed right before a client reset is about to happen
        },
        OnAfterRecovery = (beforeFrozen, after) =>
        {
          // executed right after an automatic recovery from a client reset has completed
        },
        OnAfterDiscard = (beforeFrozen, after) =>
        {
          // executed after an automatic recovery from a client reset has failed but the DiscardUnsyncedChanges fallback has completed
        },
        ManualResetFallback = (session, err) =>
        {
          // handle the reset manually
        }
      }
    };

    (PR #2745)

  • Introducing string query support for constant list expressions such as realm.All<Car>().Filter("Color IN {'blue', 'orange'}"). This also includes general query support for list vs list matching such as realm.All<Car>().Filter("NONE Features IN {'ABS', 'Seat Heating'}"). (Core upgrade)

  • Improve performance when a new Realm file connects to the server for the first time, especially when significant amounts of data has been written while offline. (Core upgrade)

  • Shift more of the work done on the sync worker thread out of the write transaction used to apply server changes, reducing how long it blocks other threads from writing. (Core upgrade)

  • Improve the performance of the sync changeset parser, which speeds up applying changesets from the server. (Core upgrade)

Fixed

  • Added a more meaningful error message whenever a project doesn't have [TargetFramework] defined. (Issue #2843)
  • Opening a read-only Realm for the first time with a SyncConfiguration did not set the schema version, which could lead to m_schema_version != ObjectStore::NotVersioned assertion failures. (Core upgrade)
  • Upload completion callbacks (i.e. Session.WaitForUploadAsync) may have called before the download message that completed them was fully integrated. (Core upgrade)
  • Fixed an exception "fcntl() with F_BARRIERFSYNC failed: Inappropriate ioctl for device" when running with MacOS on an exFAT drive. (Core upgrade)
  • Syncing of a Decimal128 with big significand could result in a crash. (Core upgrade)
  • Realm.Refresh() did not actually advance to the latest version in some cases. If there was a version newer than the current version which did not require blocking it would advance to that instead, contrary to the documented behavior. (Core upgrade)
  • Several issues around notifications were fixed. (Core upgrade)
    • Fix a data race on RealmCoordinator::m_sync_session which could occur if multiple threads performed the initial open of a Realm at once.
    • If a SyncSession outlived the parent Realm and then was adopted by a new Realm for the same file, other processes would not get notified for sync writes on that file.
    • Fix one cause of QoS inversion warnings when performing writes on the main thread on Apple platforms. Waiting for async notifications to be ready is now done in a QoS-aware ways.
  • If you set a subscription on a link in flexible sync, the server would not know how to handle it (#5409, since v11.6.1)
  • If a case insensitive query searched for a string including an 4-byte UTF8 character, the program would crash. (Core upgrade)
  • Added validation to prevent adding a removed object using Realm.Add. (Issue #3020)

Compatibility

  • Realm Studio: 12.0.0 or later.

Internal

  • Using Core 12.7.0.

10.15.1

08 Aug 23:14
adf7474
Compare
Choose a tag to compare

10.15.1 (2022-08-08)

Fixed

  • Fixed an issue introduced in 10.15.0 that would prevent non-anonoymous user authentication against Atlas App Services. (Issue #2987)
  • Added override to User.ToString() that outputs the user id and provider. (PR #2988)
  • Added == and != operator overloads to User that matches the behavior of User.Equals. (PR #2988)

Compatibility

  • Realm Studio: 12.0.0 or later.

Internal

  • Using Core x.y.z.

10.15.0

05 Aug 15:17
8b7ad31
Compare
Choose a tag to compare

10.15.0 (2022-08-05)

Enhancements

  • Preview support for .NET 6 with Mac Catalyst and MAUI. (PR #2959)
  • Reduce use of memory mappings and virtual address space (Core upgrade)

Fixed

  • Fix a data race when opening a flexible sync Realm (Core upgrade).
  • Fixed a missing backlink removal when setting a RealmValue from a RealmObject to null or any other non-RealmObject value. Users may have seen exception of "key not found" or assertion failures such as mixed.hpp:165: [realm-core-12.1.0] Assertion failed: m_type when removing the destination object. (Core upgrade)
  • Fixed an issue on Windows that would cause high CPU usage by the sync client when there are no active sync sessions. (Core upgrade)
  • Improved performance of sync clients during integration of changesets with many small strings (totalling > 1024 bytes per changeset) on iOS 14, and devices which have restrictive or fragmented memory. (Core upgrade)
  • Fix exception when decoding interned strings in realm-apply-to-state tool. (Core upgrade)
  • Fix a data race when committing a transaction while multiple threads are waiting for the write lock on platforms using emulated interprocess condition variables (most platforms other than non-Android Linux). (Core upgrade)
  • Fix some cases of running out of virtual address space (seen/reported as mmap failures) (Core upgrade)
  • Decimal128 values with more than 110 significant bits were not synchronized correctly with the server (Core upgrade)

Compatibility

  • Realm Studio: 11.0.0 or later.

Internal

  • Using Core 12.4.0.

10.14.0

02 Jun 16:06
e77b2de
Compare
Choose a tag to compare

10.14.0 (2022-06-02)

Enhancements

  • Added a more efficient replacement for Realm.WriteAsync. The previous API would start a background thread, open the Realm there and run a synchronous write transaction on the background thread. The new API will asynchronously acquire the write lock (begin transaction) and asynchronously commit the transaction, but the actual write block will execute on the original thread. This means that objects/queries captured before the block can be used inside the block without relying on threadsafe references. Importantly, you can mix and match async and sync calls. And when calling any Realm.WriteAsync on a background thread the call is just run synchronously, so you should use Realm.Write for readability sake. The new API is made of Realm.WriteAsync<T>(Func<T> function, CancellationToken cancellationToken), Realm.WriteAsync(Action action, CancellationToken cancellationToken), Realm.BeginWriteAsync(CancellationToken cancellationToken) and Transaction.CommitAsync(CancellationToken cancellationToken). While the Transaction.Rollback() doesn't need an async counterpart. The deprecated API calls are Realm.WriteAsync(Action<Realm> action), Real.WriteAsync<T>(Func<Realm, IQueryable<T>> function), Realm.WriteAsync<T>(Func<Realm, IList<T>> function) and Realm.WriteAsync<T>(Func<Realm, T> function). Here is an example of usage:
    using Realms;
    
    var person = await _realm.WriteAsync(() =>
    {
      return _realm.Add(
        new Person
        {
          FirstName = "Marco"
        });
    });
    
    // you can use/modify person now
    // without the need of using ThreadSafeReference
    (PR #2899)
  • Added the method App.DeleteUserFromServerAsync to delete a user from the server. It will also invalidate the user locally as well as remove all their local data. It will not remove any data the user has uploaded from the server. (Issue #2675)
  • Added boolean property ChangeSet.IsCleared that is true when the collection gets cleared. Also Realm collections now raise CollectionChanged event with action Reset instead of Remove when the collections is cleared. Please note that this will work only with collection properties, such as IList and ISet. (Issue #2856)
  • Added PopulateInitialSubscriptions to FlexibleSyncConfiguration - this is a callback that will be invoked the first time a Realm is opened. It allows you to create the initial subscriptions that will be added to the Realm before it is opened. (Issue #2913)
  • Bump the SharedInfo version to 12. This requires update of any app accessing the file in a multiprocess scenario, including Realm Studio.
  • The sync client will gracefully handle compensating write error messages from the server and pass detailed info to the SDK's sync error handler about which objects caused the compensating write to occur. (#5528)

Fixed

  • Adding an object to a Set, deleting the parent object, and then deleting the previously mentioned object causes crash (#5387)
  • Flexible sync would not correctly resume syncing if a bootstrap was interrupted (#5466)
  • Flexible sync will now ensure that a bootstrap from the server will only be applied if the entire bootstrap is received - ensuring there are no orphaned objects as a result of changing the read snapshot on the server (#5331)
  • Partially fix a performance regression in write performance on Apple platforms. Committing an empty write transaction is ~10x faster than 10.13.0, but still slower than pre-10.7.1 due to using more crash-safe file synchronization (since v10.7.1). (Swift issue #7740).

Compatibility

  • Realm Studio: 11.0.0 or later.

Internal

  • Using Core 12.1.0.

10.13.0

18 May 13:07
ffdb2bb
Compare
Choose a tag to compare

10.13.0 (2022-05-18)

Enhancements

  • Adds the functionality to convert Sync Realms into Local Realms and Local Realms into Sync Realms. (Issue #2746)
  • Added support for a new client reset strategy, called Discard Unsynced Changes. This new stragegy greatly simplifies the handling of a client reset event on a synchronized Realm.
    This addition makes Session.Error deprecated. In order to temporarily contiue using the current Session.Error the following must be done:
      var conf = new PartitionSyncConfiguration(partition, user)
      {
        ClientResetHandler = new ManualRecoveryHandler();
      };
    In order to take advantage of the new Discard Unsynced Changes feature, the following should be done (all callbacks are optional):
      var conf = new PartitionSyncConfiguration(partition, user)
      {
        ClientResetHandler = new DiscardLocalResetHandler
        {
          OnBeforeReset = (beforeFrozen) =>
          {
            // executed right before a client reset is about to happen
          },
          OnAfterReset = (beforeFrozen, after) =>
          {
            // executed right after a client reset is has completed
          },
          ManualResetFallback = (session, err) =>
          {
            // handle the reset manually
          }
        }
      };
    If, instead, you want to continue using the manual solution even after the end of the deprecation period, the following should be done
      var conf = new PartitionSyncConfiguration(partition, user)
      {
        ClientResetHandler = new ManualRecoveryHandler((sender, e) =>
        {
            // user's code for manual recovery
        });

Fixed

  • Fixed a System.DllNotFoundException being thrown by Realm APIs at startup on Xamarin.iOS (Issue #2926, since 10.12.0)

Compatibility

  • Realm Studio: 11.0.0 or later.

Internal

  • Using Core 11.14.0.

10.12.0

05 May 21:20
6ee01ed
Compare
Choose a tag to compare

10.12.0 (2022-05-05)

Note for Xamarin.iOS targets: This release has a regression that causes Realm to fail to find the native binaries on iOS when using the Xamarin toolchain (not MAUI), resulting in a System.DllNotFoundException the first time a Realm API is used. Since the release only contains MAUI-related changes, it is safe to roll back to 10.11.2. The fix for the regression will be released in 10.13.0.

Enhancements

  • Preview support for .NET 6 with iOS, Android, and MAUI.
    We've added tentative support for the new .NET 6 Mobile workloads (except MacCatalyst, which will be enabled later). The .NET tooling itself is still in preview so we don't have good test coverage of the new platforms just yet. Please report any issues you find at https://github.com/realm/realm-dotnet/issues/new/choose.

Compatibility

  • Realm Studio: 11.0.0 or later.

Internal

  • Using Core 11.14.0.

10.11.2

21 Apr 10:30
653353e
Compare
Choose a tag to compare

10.11.2 (2022-04-12)

Fixed

  • Fixed corruption bugs when encryption is used. (Core Issue #5360)

Compatibility

  • Realm Studio: 11.0.0 or later.

Internal

  • Using Core 11.14.0.

10.11.1

31 Mar 11:38
319d77a
Compare
Choose a tag to compare

10.11.1 (2022-03-31)

Fixed

  • Fixed an issue that would cause the managed HttpClientHandler to be used in Xamarin applications, even if the project is configured to use the native one. (Issue #2892)

Compatibility

  • Realm Studio: 11.0.0 or later.

Internal

  • Using Core 11.12.0.

10.11.0

28 Mar 15:22
36f4dc0
Compare
Choose a tag to compare

10.11.0 (2022-03-28)

Enhancements

  • Added property Session.ConnectionState to get a Session's SessionConnectionState. Additionally, Session now implements INotifyPropertyChanged so that you can listen for changes on Session.ConnectionState. (Issue #2801)
  • Realm now supports running on Windows ARM64 for .NET Framework, .NET Core, and UWP apps. (Issues #2704 and #2817)
  • Added a property AppConfiguration.HttpClientHandler that allows you to override the default http client handler used by the Realm .NET SDK to make http calls. Note that this only affects the behavior of http calls, such as user login, function calls, and remote mongodb calls. The sync client uses a native websocket implementation and will not use the provided message handler. (Issue #2865)

Fixed

  • [Unity] Fixed an issue that caused the weaver to fail when invoked via the Tools->Realm->Weave Assemblies editor menu with the error UnityEngine.UnityException: get_dataPath can only be called from the main thread. (Issue #2836)
  • Fixed an issue that caused RealmInvalidObjectException to be caused when enumerating an invalid Realm collection (e.g. a list belonging to a deleted object). (Issue #2840)
  • Query parser would not accept "in" as a property name (Core Issue #5312)
  • Application would sometimes crash with exceptions like 'KeyNotFound' or assertion "has_refs()". Other issues indicating file corruption may also be fixed by this. The one mentioned here is the one that lead to solving the problem. (Core Issue #5283)

Compatibility

  • Realm Studio: 11.0.0 or later.

Internal

  • Using Core 11.12.0.
  • Enabled running Benchmarks on iOS devices by turning on the interpreter for some windows assemblies.

10.10.0

28 Feb 15:06
344f8a1
Compare
Choose a tag to compare

10.10.0 (2022-02-28)

Guid representation issue

This release fixes a major bug in the way Guid values are stored in the database. It provides an automatic migration for local (non-synchronized) databases, but extra caution is needed when upgrading an app that uses Sync.

Context

A Guid is represented by 4 components - int, short, short, and a byte[8]. Microsoft's Guids diverge from the UUID spec in that they encode the first three components with the endianness of the system (little-endian for all modern CPUs), while UUIDs encode their components as big-endian. The end result is that the same bytes have a different string representations when interpreted as a Guid by the .NET SDK vs when interpreted as a UUID by the Realm Database - e.g. f2952191-a847-41c3-8362-497f92cb7d24 vs 912195f2-47a8-c341-8362-497f92cb7d24 (note the swapping of bytes in the first three components). You can see the issue by opening a database created by the .NET SDK in Realm Studio and inspecting the values for Guid properties.

Fix

The fix we're providing is to adjust the behavior of the .NET SDK to read/write Guids to the database with big-endian representation. This means that the SDK and the database will consistently display the same values. This has some implications which are described in the Local- and Synchronized Realms sections.

Local Realms

For local Realms, we're executing a one-time migration the first time the Realm is opened with the new SDK. During this migration, we'll update all Guid fields to big-endian format. This means that their string representation will remain the same, but the value in the database will change to match it. This means that the upgrade process should be seamless, but if you decide to downgrade to an older version of the SDK, you'll see the byte order get flipped. The migration will not execute multiple times, even if you downgrade.

Synchronized Realms

There's no client migration provided for synchronized Realms. This is because the distributed nature of the system would mean that there will inevitably be a period of inconsistent state. Instead, the values of the Guid properties are read as they're already stored in the database, meaning the string representation will be flipped compared to previous versions of the SDK but it will now match the representation in Atlas/Compass/Realm Studio. There are three general groups your app will fall under:

  • If you don't care about the string values of Guid properties on the client, then you don't need to do anything. The values will still be unique and valid Guids.
  • If you do use the string guid values from the client app - e.g. to correlate user ids with a CMS, but have complete control over your client devices - e.g. because this an internal company app, then it's advised that you execute a one-time migration of the data in Atlas and force all users to upgrade to the latest version of the app.
  • If you can't force all users to update at the same time, you can do a live migration by adding an extra property for each Guid property that you have and write a trigger function that will migrate the data between the two. The old version of the app will write to the original property, while the new version will write to the new property and the trigger will convert between the two.

If you are using sync and need to update to the latest version of the SDK but are not ready to migrate your data yet, see the Opting out section.

Opting out

If for some reason, you want to opt out of the fixed behavior, you can temporarily opt out of it by setting the Realm.UseLegacyGuidRepresentation property to true. This is not recommended but can be used when you need more time to test out the migration while still getting bugfixes and other improvements. Setting it to true does two things:

  1. It brings back the pre-10.10.0 behavior of reading/writing Guid values with little-endian representation.
  2. It disables the migration code for local Realms. Note that it will not revert the migration if you already opened the Realm file when UseLegacyGuidRepresentation was set to false.

Enhancements

  • Lifted a limitation that would prevent you from changing the primary key of objects during a migration. It is now possible to do it with both the dynamic and the strongly-typed API:
    var config = new RealmConfiguration
    {
      SchemaVersion = 5,
      MigrationCallback = (migration, oldVersion) =>
      {
        // Increment the primary key value of all Foos
        foreach (var obj in migration.NewRealm.All<Foo>())
        {
          obj.Id = obj.Id + 1000;
        }
      }
    }
  • [Unity] The Realm menu item in the Unity Editor was moved to Tools/Realm to reduce clutter and align with other 3rd party editor plugins. (Issue #2807)

Fixed

  • Fixed an issue with xUnit tests that would cause System.Runtime.InteropServices.SEHException to be thrown whenever Realm was accessed in a non-async test. (Issue #1865)
  • Fixed a bug that would lead to unnecessary metadata allocation when freezing a realm. (Issue #2789)
  • Fixed an issue that would cause Realm-managed objects (e.g. RealmObject, list, results, and so on) allocated during a migration block to keep the Realm open until they are garbage collected. This had subtle implications, such as being unable to delete the Realm shortly after a migration or being unable to open the Realm with a different configuration. (PR #2795)
  • Fixed an issue that prevented Unity3D's IL2CPP compiler to correctly process one of Realm's dependencies. (Issue #2666)
  • Fixed the osx runtime path in the Realm NuGet package to also apply to Apple Silicon (universal) architectures (Issue #2732)

Compatibility

  • Realm Studio: 11.0.0 or later.

Internal

  • Using Core 11.8.0