Xamarin Linker : Default constructor not found for type Cirrious.CrossCore.IoC.MvxPropertyInjector - xamarin.ios

With a skeleton project with FirstView from HotTuna package, and with Build linker behavior set to "Link all assemblies", I get the following error:
System.MissingMethodException: Default constructor not found for type Cirrious.CrossCore.IoC.MvxPropertyInjector
Using NuGet package v3.1.1 for all MvvmCross (4 packages)
LinkerPleaseInclude file does have the line
[MonoTouch.Foundation.Preserve(AllMembers = true)]
Using the latest stable build:
On PC:
Xamarin for VS 1.12.278
Xamarin.iOS 1.12.278
Mac:
Xamarin.iOS 7.2.2.2
Of course with Linker behavior of SDK only, it runs fine. Any suggestions anyone?

Solved; So, with the basic project, there were three consecutive errors in the following order:
System.MissingMethodException: Default constructor not found for type Cirrious.CrossCore.IoC.MvxPropertyInjector
can be resolved either by --linkskip=Cirrious.Core (ugly), or by including the following in LinkerPleaseInclude.cs
public void Include(MvxPropertyInjector injector){
injector = new MvxPropertyInjector ();
}
Next error is:
Cirrious.CrossCore.Exceptions.MvxException: Failed to construct and initialize ViewModel for type {0} from locator MvxDefaultViewModelLocator - check MvxTrace for more information
This one is difficult; Simple fix is to ofcourse to do a --linkskip=portableLibrary, or to crate an instance of the ViewModel somewhere (perhaps in LinkerPleaseInclude.cs); problem with the second approach at-least in my case is, most of my VM doesn't have a parameter less constructor, and obviously using IOC in this case wouldn't help.
Final Error:
System.ArgumentNullException: missing source event info in MvxWeakEventSubscription
Parameter name: sourceEventInfo
Either use --linkskip=System (ugly), or add the following to LinkerPleaseInclude.cs
public void Include(INotifyPropertyChanged changed)
{
changed.PropertyChanged += (sender, e) => {
var test = e.PropertyName;
};
}
This was enough for my basic project to run with LinkAllAssemblies, Using LLVM optimizer, and Use SGen collector.
Hope this will help anyone looking for a solution.

I hit this when my XCode was out of sync with the latest Xamarin on my Mac. Upgrading XCode to the latest resolved the problem.

Related

Groovy how can I build a custom library and use it in a project as dependency

I have a set of code procedures I use in a lot of places and I'm trying to basically move it to a library.
So I created my library with some unit test and everything was looking promising and at least working localy..
When I went to my project and deleted the files locally and then try to import them from my library as a dependency the code does not work.
I always get this kind of error
Class does not define or inherit an implementation of the resolved method abstract getProperty(Ljava/lang/String;)Ljava/lang/Object; of interface groovy.lang.GroovyObject.
I'm definitely not an expert on groovy but basically I use it in my Jenkins and Gradle for pipelines and some basic packaging or environment deployments.
I can show my class:
class ConsoleRow implements Comparable {
...
final Integer priority
final String rowStatus
final String message
final String rowReportClass
ConsoleRow(Integer priority, String status, String msg, String rowC) {
this.priority = priority
this.rowStatus = status
this.message = msg
this.rowReportClass = rowC
}
#Override
int compareTo(Object o) {
return this.priority <=> ((ConsoleRow) o).priority
}
The line that gives me the error is this actual compareTo when trying to do the "this.priority"
Caused by: java.lang.AbstractMethodError: Receiver class com.abc.insight.jenkins.ConsoleRow does not define or inherit an implementation of the resolved method abstract getProperty(Ljava/lang/String;)Ljava/lang/Object; of interface groovy.lang.GroovyObject.
at com.abc.insight.jenkins.ConsoleRow.compareTo(ConsoleRow.groovy:24)
at com.abc.insight.jenkins.ConsoleOutputHtmlBuilder.processOutput(ConsoleOutputHtmlBuilder.groovy:115)
at com.abc.insight.jenkins.ConsoleOutputHtmlBuilder.processOutput(ConsoleOutputHtmlBuilder.groovy)
at com.abc.insight.jenkins.ConsoleOutputHtmlBuilder.buildReport(ConsoleOutputHtmlBuilder.groovy:20)
at com.abc.insight.jenkins.ConsoleOutputHtmlBuilder$buildReport.call(Unknown Source)
at build_e548mc0tqjmi822clitlsycdk.runReport(C:\dev\repo\insight\insight-health-check\data-foundation\smoke-test\build.gradle:77)
The calling function is just trying to sort a list of those objects
List<ConsoleRow> outputRows = []
...
return outputRows.sort()
The part that gets me really confused is that if instead of importing the library as a dependency I just do this directly in this repo and put my sources in my buildSrc\src\main\groovy\com\abc\insight the code works fine...
So I really think it might be how I package and publish my library that might be wrong.
I'm really sure this is some basic error on my part because I never did a groovy library before but somehow I can't make it work.
It might be that my publication is just wrong, on my library side I'm using this plugins to do the publishing.
plugins {
id 'groovy'
id 'java-library'
id 'base'
}
publishing {
publications {
maven(MavenPublication) {
from components.java
}
}
}
I tried to change components.groovy but somehow it does not work.
Any ideas or tips, I think my question probably is showing some really lack of know-how on groovy but looking at the documentation and examples I could not figure it out.
Doing some debug in my IDE the compareTo that generates the exception looks like this.
public int compareTo(Object o) {
CallSite[] var2 = $getCallSiteArray();
return ScriptBytecodeAdapter.compareTo(this.priority, var2[0].callGroovyObjectGetProperty((ConsoleRow)ScriptBytecodeAdapter.castToType(o, ConsoleRow.class)));
}
I tried following this guide and code structure when doing moving the code to a library
https://docs.gradle.org/current/samples/sample_building_groovy_libraries.html
Thanks for any feedback
p.s: My code might look weird, I tried first to have everything with the def blablabla but I was having some issues with typecasting but I don't think this would be the reason for the problem I'm facing.
Anyway I got a look at the generated code in my IDE and I see a lot of get methods just no idea where they expected this getProperty from
Ok this was definitely a user error.
I am using distribution version of gradle 6.5.1
When I did the gradle init to bootstrap my project I was provided with the dependency of gradle groovy-all version 2.5.11
implementation group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.5.11'
I thought that was a mistake and just updated to the latest version.
implementation group: 'org.codehaus.groovy', name: 'groovy-all', version: '3.0.9'
Now the problem is that the project in which I'm using the library is also running with gradle 6.5.1 so probably this version missmatch between compiple and usage was causing the problem.
By reverting to the correct version suggested by gradle the problem is gone.

Groovy version downgrade 2.2.1

We have been building our application using groovy 2.3.6. Now because of some platform level issues we are advised to downgrade our groovy version to 2.2.1. I am facing no. of issues regarding this downgrade.
groovy is not able to infer the type of it variable in ver 2.2.1 so if i have code something like this
names.any { sliceName.endsWith(it) }
it gives me exception
[Static type checking] - Cannot find matching method java.lang.String#endsWith(java.lang.Object)
Secondly all the default method that i had used in collections no longer seem to exist
positions.any { it.primary }
groovy is unable to find the any method on list.
One way would be turn off static type checking, which will expose the code to a lot more runtime errors.
Is there any way to resolve these errors, without turning off static type checking. Also are these features only added in groovy 2.3.6 like default groovy methods and type inference for it variable
If you go back to an old version, old bugs will bite you.
Try giving the static compiler more of a hint
names.any { String it -> sliceName.endsWith(it) }

iOS Project Fails to Compile

When compiling iOS project developed with MvvmCross version 3.5.0, I get the following error:
Failed to resolve "Foundation.NSDate Foundation.NSDate::op_Explicit(System.DateTime)" reference from "Xamarin.iOS, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065"
You are likely using an outdated version of MvvmCross (or another 3rd party) that used an old, preview version of the unified API.
The error tells you an assembly (binary) is looking for a member that it cannot find, because it was removed: see section "Converting DateTime to NSDate".
Updating your dependencies (any assembly binaries) will solve this correctly, without potentially introducing other issue(s).
The bug is in the method:
public void Include(UIDatePicker date) in LinkerPleaseInclude class.
Trying to pass DateTime as NSDate.
Just comment out or remove following code :
public void Include(UIDatePicker date)
{
date.Date = date.Date.AddSeconds(1);
date.ValueChanged += (sender, args) => { date.Date=NSDate.DistantFuture; };
}
Also can be resolved by updating binary libraries to unified api.
You can get detailed information on
http://developer.xamarin.com/guides/cross-platform/macios/unified/

Autofac quit resolving constructors on iOS after Xamarin update

So I updated my Xamarin install today to the latest stable version. Since the update, my app won't run on iOS (runs fine on Android)... the error is that it can't resolve the constructor.
Autofac.Core.DependencyResolutionException: No constructors on type 'FutureState.AppCore.Migrations.Migration001' can be found with the constructor finder 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'.
My original constructor is
public Migration001(IUserRepository userRepository,
IRoleRepository roleRepository,
IPermissionRepository permissionRepository,
IPasswordHasher passwordHasher)
{
_userRepository = userRepository;
_roleRepository = roleRepository;
_permissionRepository = permissionRepository;
_passwordHasher = passwordHasher;
MigrationVersion = 1;
}
but I even tried changing it to service location just to see if Autofac would find the constructor.
public Migration001()
{
_userRepository = App.Container.Resolve<IUserRepository>();
_roleRepository = App.Container.Resolve<IRoleRepository>();
_permissionRepository = App.Container.Resolve<IPermissionRepository>();
_passwordHasher = App.Container.Resolve<IPasswordHasher>();
MigrationVersion = 1;
}
but unfortunately, it results in the exact same issue.
Autofac.Core.DependencyResolutionException: No constructors on type 'FutureState.AppCore.Migrations.Migration001' can be found with the constructor finder 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'.
what would cause something like this? This is a Xamarin.Forms app, so the exact same code is run without issue on Android.
Looks like it was an issue with the Xamarian release at that time. I've re-updated to the latest version (yesterday) and no longer have this issue.
Further there were a number of breaking bugs in the September 2014 releases, so if you're on 3.5... upgrade.
I had similar issue after upgrading Xamarin iOS SDK to Alpha (3.9.289). Changing Linker Behaviour to 'Don't link' solved my problem.
Changing Linker Behaviour to Link Framework SDKs Only solved my problem.

How to force Monotouch AOT Compiler to see a nested generic method?

I've had to jump through hoops, but I've almost managed to get ServiceStack working on iOS with Monotouch in my project. One runtime JIT exception is holding out:
System.ExecutionEngineException: Attempting to JIT compile method 'ServiceStack.Text.Json.JsonTypeSerializer:GetWriteFn<int> ()' while running with --aot-only.
The offending code is quite simple:
internal WriteObjectDelegate GetWriteFn<T>()
{
return JsonWriter<T>.WriteFn();
}
As a test, I modified the SS code to make the internal methods and types public and included the following in the startup code of my project (to actually get called).
var ick = ServiceStack.Text.Json.JsonWriter<int>.WriteFn();
var erk = ServiceStack.Text.Json.JsonTypeSerializer.Instance.GetWriteFn<int>();
This still doesn't alert the AOT for some reason, I get the exception when the code above executes! Is this because the generic parameter is a value type? Or is it because these are static classes and methods? How can I force Monotouch to AOT the methods above?
The SS code in question is in JsonTypeSerializer.cs and JsonWriter.Generic.cs at:
https://github.com/ServiceStack/ServiceStack.Text/tree/master/src/ServiceStack.Text/Json
There are some generic limitations in monotouch now. I think you should check your code to one of them.

Resources