Error with MvvmCross using System.Net on MonoDroid - xamarin.android

I have referenced HttpStatusCode via System.Net in a Portable Class Library.
I then need to reference that status code from a MonoDroid project that includes that PCL. I understand that the System.Net namespace exists in the System DLL for MonoDroid and this has been included.
However this results in a build error:
CS0012: The type 'System.Net.HttpStatusCode' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Net, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes'.
Now I realise there are strong namespacing issues with referencing the PCL System.Net, and that there is a Shim DLL in MvvmCross.PortableSupport that is supposed to resolve this issue. I have included MvvmCross.PortableSupport.3.0.8.1\lib\MonoAndroid16\System.Net.dll to the MonoDroid project, but I still get the same error.
What am I missing?
Thanks!
Matthew

So I was unable to determine the underlying issue, but the workaround was to avoid referencing the System.Net symbol from the native code via the Portable Class Library (framework 104 btw)
In this instance, instead of exposing the HttpStatusCode from the PCL, I exposed it as an integer and thus worked around the problem.
Stuart is away on holiday at the moment but he suggested this as a workaround and it works fine. It's not clear why the shim System.Net.Dll that MvvmCross includes isn't redirecting the reference correctly to the native library.

Related

The "LinkAssemblies" task failed unexpectedly in Xamarin Android

I am trying to POST data using a REST API. The app used to run flawlessly, but now that I've added code to perform the POST, I'm getting a new error. Would anyone be able to help explain what's going wrong and suggest an alternative that would let me complete the POST request successfully?
Here's the error I get when I try to build the app with the linker enabled in the Release configuration:
Error The "LinkAssemblies" task failed unexpectedly.
Xamarin.Android.XamarinAndroidException: error XA2006: Reference to metadata item 'System.Runtime.InteropServices.StandardOleMarshalObject' (defined in 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089') from 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' could not be resolved. ---> Mono.Cecil.ResolutionException: Failed to resolve System.Runtime.InteropServices.StandardOleMarshalObject
at Mono.Linker.Steps.MarkStep.MarkType(TypeReference reference)
at MonoDroid.Tuner.MonoDroidMarkStep.MarkType(TypeReference reference)
at Mono.Linker.Steps.MarkStep.MarkType(TypeReference reference)
at MonoDroid.Tuner.MonoDroidMarkStep.MarkType(TypeReference reference)
at Mono.Linker.Steps.MarkStep.InitializeType(TypeDefinition type)
at Mono.Linker.Steps.MarkStep.InitializeAssembly(AssemblyDefinition assembly)
at Mono.Linker.Steps.MarkStep.Initialize()
at Mono.Linker.Steps.MarkStep.Process(LinkContext context)
at Mono.Linker.Pipeline.Process(LinkContext context)
at MonoDroid.Tuner.Linker.Process(LinkerOptions options, LinkContext& context)
at Xamarin.Android.Tasks.LinkAssemblies.Execute()
--- End of inner exception stack trace ---
at Xamarin.Android.Diagnostic.Error(Int32 code, Exception innerException, String message, Object[] args)
at Xamarin.Android.Tasks.LinkAssemblies.Execute()
at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext() GimcoIOT.Andriod
It looks like you might have added a reference to a desktop .NET assembly in your Xamarin.Android app. The System.Windows.Forms namespace is not available in the Xamarin.Android profile. (Even if the app builds successfully when you disable linking, it will in theory still fail at run time any time it tries to run code that references the System.Windows.Forms namespace.)
To solve this problem, you will want to remove the reference to the desktop .NET assembly from your Xamarin.Android project and ensure that all of your other referenced assemblies are compiled either against the Xamarin.Android profile or a supported PCL profile.
As mentioned in the documentation:
Xamarin.Android is not ABI compatible with existing assemblies compiled for a different profile. You must recompile your source code to generate assemblies targeting the Xamarin.Android profile (just as you need to recompile source code to target Silverlight and .NET 3.5 separately).
(Portable Class Libraries are the special exception to this rule.)
If you are currently using a type from the System.Windows.Forms namespace to perform the POST request, then you will need to switch to a different type. For example, one of the PostAsync() methods from System.Net.Http.HttpClient might work nicely.

Reference to type 'System.IConvertible' claims it is defined in assembly mscorlib

Anytime I try to reference an NUNIT data type in the iOS framework, I am given a compiler error saying it can't find the IConvertible type
Error CS7069: Reference to type System.IConvertible' claims it is defined assemblymscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', but it could not be found (CS7069) (logic)
I was able to reproduce this by creating a brand new Xamarin.Forms project that only targets iOS.
Immediately after creating it, I added a second Xamarin.Forms project, this time a PCL.
I then needed to add the Xamarin.iOS library so that I can reference the iOS specific APIs, specifically the Photos API. I did this by navigating to
~/Library/Frameworks/Xamarin.iOS.framework/Versions/9.0.1.29/lib/mono/Xamarin.iOS/Xamarin.iOS.dll
Lastly, I added a blank class to the new PCL project, and created a locally scoped NUNIT field. This is where the compiler error happens. This happens in my current project when I try to get the number of photos in a PHAssetCollection, as that is an NUNIT data type.
using System;
namespace logic
{
public class EmptyClass
{
public EmptyClass()
{
nuint test = 5;
}
}
}
This gives me the compiler error I've referenced above. How can I solve this? This has become a blocking issue for me, am I referencing the wrong Xamarin.iOS.dll? It's not available in the list of nuget packages when I scan for them, so I can't add it via NuGet. NuGet only has Xamarin.Forms.dll available.
Update 1
After trying a few different combinations, I think that I have a working solution. Instead of creating a Xamarin.Forms Library, I created a normal iOS PCL library instead. This solved that problem.
I don't know why the Xamarin.Forms library wouldn't work. Is it not intended to be used for platform specific code?
Xamarin Forms PCL's need to be platform agnostic. If you have a NUnit project that needs access to a Xamarin.iOS specific reference, then you need to build within the iOS project / iOS PCL.
Xamarin.iOS.dll can only be referenced from a iOS related project.

Using Late Bound Assemblies with Xamarin for iOS

I'm trying to port one of my iOS apps from the Mono versions of the
ServiceStack.Text libraries to the PCL versions for JSON
serialization/deserialization.
I have the libraries working in a regular Windows console application. When trying to port this into the iOS application, I'm getting an "Object reference not set to an instance of an object" exception from on the ServiceStack extension method classes. The error message is a red herring; the true error is getting swollowed by a try/catch.
The static constructor in ServiceStack.Text.PCL.PclExport is doing late binding for a
platform specific DLL and can't find that DLL. The build log bears out that the
Client, Interface, and Pcl libraries aren't being packaged with the .app file even though the reference are included at the project level.
I've been able to reproduce this in a basic iOS Hello World application. If I
add a line of code that references a method in the Pcl DLL, the three missing
libraries are copied. However, I'm still getting the same "Object reference not
set to an instance of an object" error.
I suspect that this is caused by the fact the Xamarin compiler doesn't translate the DLLs into iOS binaries unless they are actually used, and since they're late bound, it doesn't know they're used and so ignores them.
I didn't think late binding was legal under the licensing on at actual iPhone? doesn't the link merge everything into one exe?
See the Xamarin Linker Docs try the -nolinkaway option.

Error when building project with monodroid/mvvmcross

I've got an error when I try to build a project (monodroid/mvvmcross).
This is the message error :
Error 37 The type 'Android.App.ListActivity' is defined in an assembly that is not referenced. You must add a reference to assembly 'Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=c4c4237547e4b6cd'.
Someone have an idea how to solve this problem ? This is strange because there wasn't this error before.
This error is located in MvxDialogActivityView.cs (cirrious.MvvmCross.Dialog.Droid)
I think your problem is that parts of your code is compiled against Xamarin.Android while others are compiled against Mono for Android.
See: http://forums.xamarin.com/discussion/1476/changes-to-assembly-strongnames-in-xamarin-android-4-6-0
You will need to recompile all parts of your application to target the same version of Xamarin's products.

Missing method in mscorlib.dll included in apk

I have an obfuscated application in Monodroid and my problem is that the mscorlib assembly included in apk doesn't implements the method System.String.Intern() and my application doesn't work.
My obfuscator calls this method to obfuscate strings and I get a MissingMethodException. This method doesn't exists in the assembly included in apk but strangely it does exists in myproject/obj/release/assemblies/mscorlib.dll
These files are quite different. If I put the file myproject/obj/release/assemblies/mscorlib.dll in apk it works but this solution is a bad solution because the app fails in other point causing TypeLoadException because of the change of the dll.
Can anyone tell me why monodroid uses the mscorlib reduced file and an alternative solution?
Thanks.
Can anyone tell me why monodroid uses the mscorlib reduced file and an alternative solution?
The smaller file is used to reduce application size by linking the assemblies. Linking can be brittle, as the linker doesn't trace runtime behavior. For example, using Type.GetType("Foo") will not preserve the type Foo, and thus the linker may remove it if it's not otherwise referenced.
obj\Release\assemblies\mscorlib.dll is the source assembly. obj\Release\android/assets/mscorlib.dll is the linked (smaller) assembly, which is included in the .apk.
If your obfuscator is directly using String.Intern(), this may suggest a bug in the linker. However, if your obfuscator is using Reflection (e.g. Type.GetMethod()), then this would be expected behavior. To fix it, you explicitly use String.Intern() within a falseflag block so that the method is preserved.

Resources