Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my Xamarin PCL throw a runtime exception when Building release for Universal App?

I have a xamarin PCL that builds fine in x86 Debug mode. When I switch it to Release Mode (x86 or x64) or x64 Debug, I am getting runtime exceptions. It probably relates to

https://forums.xamarin.com/discussion/57810/issue-with-xamarin-forms-in-windows-uwp-app-compiled-in-the-release-mode

but I don't know what other assembly I'm using. How can I tell?

My computer is x64. When I run x64 in either debug or release I get

Exception "System.NotImplementedException" in MyApp.Interop.dll. Additional Info Arg_NotImplementedException.

Before entering the constructor App(). The call to the constructor is here:

LoadApplication(new MyApp.App());

When I build x86 I get a little bit further. It gets into the MyAppConstructor and calls the xaml constructor and gives exception:

System.Reflection.MissingMetadataException in System.Private.Reflection.Core.dll AdditionalInfo:Arg_InvokeMethodMissingMetadata, System.EventHandler. For more information, visit http://go.microsoft.com/fwlink/?LinkId=623485

So it looks like a Xaml assembly I'm missing. How do I find out what assembly I need to add?

I put it back on Debug, but turned it to "use the Native Compiler" so I could get more details on the exceptions:

x86: Additional information: Cannot create a delegate on type 'System.EventHandler' as it is missing metadata for the Invoke method. For more information, please visit http://go.microsoft.com/fwlink/?LinkID=616867

x64: An exception of type 'System.NotImplementedException' occurred in Xamarin.Forms.Platform.UAP.dll but was not handled in user code

Additional information: The method or operation is not implemented.

UPDATE: I am guessing x64 is not supported in Xamarin because no mobile product has x64 processor? Still leaves the problem with the x86 release. I have tried adding the following assemblies in my Universal App.xaml.cs

  List<Assembly> assembliesToInclude = new List<Assembly>();
  assembliesToInclude.Add(typeof(MyApp.MyAppMainPage).GetTypeInfo().Assembly);
  assembliesToInclude.Add(typeof(Xamarin.Forms.ImageSource).GetTypeInfo().Assembly);
  assembliesToInclude.Add(typeof(Xamarin.Forms.StackLayout).GetTypeInfo().Assembly);
  assembliesToInclude.Add(typeof(Xamarin.Forms.Label).GetTypeInfo().Assembly);
  assembliesToInclude.Add(typeof(Xamarin.Forms.Button).GetTypeInfo().Assembly);
  assembliesToInclude.Add(typeof(Xamarin.Forms.FormattedString).GetTypeInfo().Assembly);
  assembliesToInclude.Add(typeof(Xamarin.Forms.Span).GetTypeInfo().Assembly);
  assembliesToInclude.Add(typeof(Xamarin.Forms.Image).GetTypeInfo().Assembly);
  assembliesToInclude.Add(typeof(Xamarin.Forms.ScrollView).GetTypeInfo().Assembly);
  assembliesToInclude.Add(typeof(Xamarin.Forms.WebView).GetTypeInfo().Assembly);
  // add this line
  Xamarin.Forms.Forms.Init(e,assembliesToInclude); // requires the `e` parameter

where MyAppMainPage is the xaml page I try to load in my PCL and the rest are the UI elements that the page is made up of.

I now see this Exception thrown for x86:

'System.PlatformNotSupportedException' in System.Private.Interop.dll Exception thrown: 'System.AggregateException' in System.Private.Threading.dll Exception thrown: 'System.Reflection.MissingMetadataException' in System.Private.Reflection.Core.dll

Why would the platform not be supported? Xamarin supports Universal right?

like image 246
Seth Kitchen Avatar asked Dec 22 '15 20:12

Seth Kitchen


1 Answers

I have added a Directives file. Add a file with .rd.xml ending. Mine was MyApp.rd.xml. Then include the types the exception says are missing. Mine was System.EventHandler. Here is my code (you probably don't need the other two).

<?xml version="1.0" encoding="utf-8"?>
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
  <Type Name="MyApp.MyAppMainPage" Dynamic="Required All" /> 
  <Type Name="System.EventHandler" Dynamic="Required All" /> 
  <Namespace Name="System.Private.Reflection.Core" Serialize="Required All" />
</Application>
</Directives> 

I guess in Universal Apps for Xamarin you need to include the assembly when loading embedded resources. I had to change

ImageSource.FromResource("MyApp.Images.Sign.jpg");

to

var assembly = typeof(MyAppMainPage).GetTypeInfo().Assembly;
ImageSource.FromResource("MyApp.Images.Sign.jpg",assembly);

You can check what resources you have by

foreach (var res in assembly.GetManifestResourceNames())
  System.Diagnostics.Debug.WriteLine("found resource: " + res);

x64 still broken.

like image 101
Seth Kitchen Avatar answered Nov 16 '22 01:11

Seth Kitchen