Search code examples
c#xamarinrealmrealm-net

Realm exception when schema is created - on iOS only


This occurs at the first call to Realm.GetInstance. Happens only on iOS - while on Android it works fine. The Realm version is 0.77.2.

This is a Xamarin project with MvvmCross and ReactiveUI, but most likely this doesn't matter.

The call to Realm.GetInstance happens a bit late - while similar to Android - after MvvmCross is bootstrapped and at least one screen is displayed.

The error is:

System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
  at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (System.Reflection.Assembly,bool)
  at System.Reflection.Assembly.GetTypes () [0x00000] in /Users/builder/data/lanes/3539/f37444ae/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/corlib/System.Reflection/Assembly.cs:402 
  at Realms.RealmSchema.<BuildDefaultSchema>m__3 (System.Reflection.Assembly a) [0x00000] in <filename unknown>:0 
  at System.Linq.Enumerable+<SelectManyIterator>c__Iterator2`2[TSource,TResult].MoveNext () [0x00059] in /Users/builder/data/lanes/3539/f37444ae/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs:423 
  at System.Linq.Enumerable+WhereEnumerableIterator`1[TSource].MoveNext () [0x00062] in /Users/builder/data/lanes/3539/f37444ae/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs:147 
  at Realms.RealmSchema.CreateSchemaForClasses (IEnumerable`1 classes, Realms.SchemaHandle schemaHandle) [0x00025] in <filename unknown>:0 
  at Realms.RealmSchema.BuildDefaultSchema () [0x00071] in <filename unknown>:0 
  at System.Lazy`1[T].CreateValue () [0x00075] in /Users/builder/data/lanes/3539/f37444ae/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/Lazy.cs:437 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3539/f37444ae/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/3539/f37444ae/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3539/f37444ae/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3539/f37444ae/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128 
  at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in /Users/builder/data/lanes/3539/f37444ae/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:113 

Solution

  • Since it is a reflection issue (ReflectionTypeLoadException), I would have to assume the 'Xamarin.iOS` linker is removing some classes.

    You can manually add the [Xamarin.iOS.Foundation.Preserve] attribute to those classes (or members) so they are not linked out as you will probably want to set the Linker to Link all or Link Only SDK in your release builds to reduce the final .ipa size.

    You can apply this attribute on every member of a type, or on the type itself. If you want to preserve the whole type, you can use the syntax [Preserve (AllMembers = true)] on the type.

    Sometimes you want to preserve certain members, but only if the containing type was preserved. In those cases, use [Preserve (Conditional=true)]

    Ref: Preserving Code