Marcel N. Marcel N. - 3 months ago 23
C# Question

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

Answer

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