Android .aar binding library in Xamarin - xamarin.android

I have a .aar library that I am trying to use in Xamarin. most of the components work perfectly however one interface is completely missing
In the binding library build in debug I found the following
1>BINDINGSGENERATOR : warning BG8604: top ancestor FaceViewFragment not found for nested type Com.Truesen.Face.Entrance.Fragment.FaceViewFragment._1.
1>BINDINGSGENERATOR : warning BG8604: top ancestor FaceViewFragment not found for nested type Com.Truesen.Face.Entrance.Fragment.FaceViewFragment._2.
1>BINDINGSGENERATOR : warning BG8604: top ancestor FaceViewFragment not found for nested type Com.Truesen.Face.Entrance.Fragment.FaceViewFragment._3.
1>BINDINGSGENERATOR : warning BG8604: top ancestor FaceViewFragment not found for nested type Com.Truesen.Face.Entrance.Fragment.FaceViewFragment.ICameraCallback.
1>BINDINGSGENERATOR : warning BG8604: top ancestor FaceViewFragment not found for nested type Com.Truesen.Face.Entrance.Fragment.FaceViewFragment.CameraOrientationDetector.
1>BINDINGSGENERATOR : warning BG8604: top ancestor FaceViewRfFragment not found for nested type Com.Truesen.Face.Entrance.Fragment.FaceViewRfFragment._1.
1>BINDINGSGENERATOR : warning BG8604: top ancestor FaceViewRfFragment not found for nested type Com.Truesen.Face.Entrance.Fragment.FaceViewRfFragment._2.
1>BINDINGSGENERATOR : warning BG8604: top ancestor FaceViewRfFragment not found for nested type Com.Truesen.Face.Entrance.Fragment.FaceViewRfFragment._3.
1>BINDINGSGENERATOR : warning BG8604: top ancestor FaceViewRfFragment not found for nested type Com.Truesen.Face.Entrance.Fragment.FaceViewRfFragment.ICameraCallback.
1>BINDINGSGENERATOR : warning BG8604: top ancestor FaceViewRfFragment not found for nested type Com.Truesen.Face.Entrance.Fragment.FaceViewRfFragment.CameraOrientationDetector.
ICameraCallback is the interface that I need, what can I do to get the interface to generate correctly ? or how can I add it manually
Here is the link to the .aar file I am using
https://drive.google.com/file/d/1ibfvjws26PesBxjojB_UNyWYiFf0yKqK/view?usp=sharing

The internal library relies on androidx.fragment and androidx.annotation, make sure you also add this as a reference to your binding project (packages are on nuget). They might be missing and therefore not create a proper binding.
It is important with android bindings to ensure that all dependencies from the java project/library are also added to the xamarin binding project and to your final project. That should let the compiler find the all of the correct references and properly make the binding.
A good way to see if the binding is done correctly is by checking your final project, open the reference to the binding (.dll) in Visual Studio and see what classes & methods are available there. This should resemble the classes and methods in your .aar project.
If this is not the case firstly check the binding for missing references, next option is to add the missing classes/methods etc to the binding manually by using the add-node tag.

Related

No compile time error in Dart when a method is given a parent class in place of its subclass

The following gives a runtime error on the last line but why do I not receive a compile time error?
Why is this? fnSub (last line) accepts a type of Sub but here I'm passing it a type of Parent and it compiles. Ok, I do get a runtime error but I'd have thought this should have given me a compile time error. Is this a bug in Dart or am I misunderstanding the limitations of the type system or have I just gone crazy?
class Parent {}
class Sub implements Parent {
String get blah => "blah";
}
String fnSub(Sub sub) => sub.blah;
String aProblem(Parent parent) => fnSub(parent);
https://dartpad.dev/acd2767cd42371deae0644fa66e8c602
The problem is that implicit-casts are enabled by default in Dart which is a feature trying to make it easier to work around types in Dart by automatically adding type casts in your code base.
This feature will no longer be available when NNBD (Non-nullable by default) are coming where implicit-dynamic also will be gone. Both features can already be disabled today by following this guide: https://dart.dev/guides/language/analysis-options#enabling-additional-type-checks
Personally, I think most projects should disable this two features already since I have seen a lot of people on Stackoverflow being confused about what Dart are doing with the types. So I cannot wait for NNBD so we can get are lot more clear type experience in Dart. And hopefully, the errors from the analyzer will be clear enough for most people so they don't need to get help.
If you disable implicit-casts you code will fail at the following line:
String aProblem(Parent parent) => fnSub(parent);
And with this error:
error - The argument type 'Parent' can't be assigned to the parameter type 'Sub'. - bin\stackoverflow.dart:9:41 - argument_type_not_assignable
If you want to test with Dartpad you can try with the following edition based on a beta version of the next Dart version which has enabled null-safety (and therefore have no implicit-casts): https://nullsafety.dartpad.dev/

Generic constraints using Xamarin

I have the following generic type with a generic type constraint.
public class GenericType<T> where T: IFoo
{
}
Then I try to create a closed generic type from the open generic type.
var fooGenericType = typeof(GenericType<>).MakeGenericType (typeof(IFoo));
var intGenericType = typeof(GenericType<>).MakeGenericType (typeof(int));
When running in the simulator it fails on trying to create a closed generic type using an int as the type parameter which is expected.
BUT, when running on the actual device (iPhone), it will also create a closed generic type using an int.
It seems like it does not respect the generic constraint, but this happens only on the device. On the simulator everything is as expected.
Any ideas?
This seems to be related to the fact that MonoTouch uses AoT compilation. It causes some limitations regarding generic types, as pointed here
Like William Barbosa mentioned there are limitations regarding generic types on iOS.
The linker excludes combinations of generic types with several parameters when it thinks they are not necassary. As the simulator is a different build target the linker might work differently.
You can force the linker to include a generic type with specific type parameters by using them anywhere in your code.
A common way is to provide a LinkerPleaseInclude.cs file like here: https://github.com/MvvmCross/MvvmCross-Tutorials/blob/master/DailyDilbert/DailyDilbert.Touch/LinkerPleaseInclude.cs
It's also pointed out here: MakeGenericMethod/MakeGenericType on Xamarin.iOS

Fully qualified name, unqualified name with import declaration resolve differently

This works
open System
let f = Action(fun () -> Unchecked.defaultof<_>)
But this
let f = System.Action(fun () -> Unchecked.defaultof<_>)
produces the compilation error
Multiple types exist called 'Action', taking different numbers of generic parameters. Provide a type instantiation to disambiguate the type resolution, e.g. 'Action<,,_,,,_,,,_>'.
I know I can fix it by adding a type parameter placeholder (System.Action<_>(...)), but any idea why they behave differently?
EDIT
Found this in the spec, section 14.1.9:
When a module or namespace declaration group F is opened, items are added to the name environment as follows:
Add the type to the TypeNames table. If the type has a CLI-mangled generic name such as List'1 then an entry is added under both List and List'1.
Is this behavior replicated for fully-qualified types (with omitted type parameters)? It doesn't appear so.
I agree with #James that this is related to the bug submitted on Connect, but I think it is a slightly different case. Anyway, I think this is not the intended behaviour. Could you report it to fsbugs at microsoft dot com?
Anyway - I did some debugging and here is what I found so far:
It seems that the compiler uses different code paths to resolve the name Action and the name System.Action. When resolving the other, it searches all loaded modules (i.e. assemblies) for a type named System.Action (see ResolveLongIndentAsModuleOrNamespaceThen function in the nameres.fs file of the open-source release).
This finds the two definitions of Action (one in mscorlib and another in System.Core). I think the issue comes from the fact that the name resolution simply iterates over the results - it finds the first one (from System.Core), which doesn't have a usable overload (because it ranges from Action<_,_,_,_,_> to a version with about 15 type parameters). After finding this type, it reports an error without even looking whether there is another type (in another assembly) that could be used.
If you don't reference system assemblies, then the F# compiler resolves the overload just fine. Running the compiler without parameters references the default assembly set, so this doesn't work:
fsc test.fs
but if I add the --noframework flag, then it compiles without issues:
fsc --noframework test.fs

What does a EClassNotFound raised at runtime really mean when the class in question is there at compile and link time, and there explicitly in code?

I have a runtime error happening in the rtl Streaming in of a form, causing an exception EClassNotFound to be raised, while doing TReader.ReadRootComponent. The particular error message is "Class not found TActionList".
What is odd is:
My main form uses Action list.
For fun, I added ActnList.pas (from the VCL source folder) to my project, to try to fix it.
This happens to me when instantiating a form that I had working until a few minutes ago. The change that I made was in some sub-frame code: I removed all its implementation section code with an ifdef marker, because I am mocking up some frames, for unit testing and prototypes.
I tried adding the action list class to the project, and I tried with and without various compiler and link options, and yet, I still get this exception. Obviously something weird is up. There must be another weird way to get this problem.
In fact, it seems there is something really weird going on. When this error is raised, I get the following call stack:
rtl.Classes.ClassNotFound('TActionList')
rtl.Classes.TReader.FindComponentClass(???)
rtl.Classes.FindExistingComponent
rtl.Classes.TReader.ReadComponent(nil) /// NIL!? WHAT!!!!!
rtl.Classes.TReader.ReadDataInner(???)
rtl.Classes.TReader.ReadData(???)
rtl.Classes.TComponent.ReadState(???)
vcl.Controls.TControl.ReadState(???)
vcl.Controls.TWinControl.ReadState($60B9CF0)
vcl.Forms.TCustomForm.ReadState(???)
rtl.Classes.TReader.ReadRootComponent($606EB90)
rtl.Classes.TStream.ReadComponent($606EB90)
rtl.Classes.InternalReadComponentRes(???,???,$606EB90)
rtl.Classes.InitComponent(TComplexFormContainingFrames)
It seems the nil is intentional, in TReader.ReadDataInner(Instance:TComponent):
while not EndOfList do ReadComponent(nil);
Update: I believe the answer to this question is to understand "serialization contexts" as Mason has mentioned. And, it's time to admit my own Stupidity: I removed the parent of the frame from the project, not realizing it was the parent of the frame. I worked around it being missing by stubbing the type declaration for TMyFrameParent as TMyFrameParent = class(TFrame), and this in turn lead to the condition in question. I am leaving the question here because I think it might be really handy in future to note when this exception occurs in arcane cases, and how to fix it. In particular, Mason has a really interesting bit of information about "serialization contexts" and how they apply to class-name-finding.
It means that the class wasn't found in the current deserialization context. Not all existing classes are registered for all loading. Each form class has RTTI containing references to the components it uses. To get this to work, make sure that your form (or frame, if this is a frame) declares at least one TActionList before the private tag:
TMyForm = class(TForm)
ActionList: TActionList;
OtherComponent: TSomeComponent;
private
//whatever
public
//whatever
end;
Use Classes.RegisterClass to register classes you want to use with the streaming system. Quote from the doc
Form classes and component classes that are referenced in a form declaration (instance variables) are automatically registered. Any other classes used by an application must be explicitly registered by calling RegisterClass if instances are to be saved. Once classes are registered, they can be loaded or saved by the component streaming system.
It seems that this happens when you copy a frame from one project to another project, and that frame inherits from something, and you fake the inheritance, but leave the "inherited" item descriptions in the frame dfm, items like this:
inherited ActionList: TActionList
Left = 520
Top = 576
end
This in turn results in the "current deserialization context" that Mason talked about, not containing the class. One fix is to change Inherited to object in all the above cases.
There is another way to get this error: put 'public' at the top of a form definition class. By default class members are 'published'. I accidentally added 'public' to the top of a form declaration and it produces multiple 'Class not found' exceptions at run-time.
I got a "EClassNotFound" error when I had a TLabel declaration present in my DFM file but there was no declaration for it in the corresponding PAS file. Somehow the form editor screwed up.
The error was not visible until I deleted all labels from my form except that particular "corrupted" one. It was difficult to hunt it down because that label was hidden under a panel.
One easy fix is to cut (ctrl+x) that label (once you find it) from the form and paste it back. This time the form editor will correctly insert a declaration for it in the PAS file.
There is yet another way to get this error: I have put 'private' at the top of a form definition class (because none of the elements were used outside the form).
So same like in previous answer (by Server Overflow): by default class members are 'published' and if you change visibility of a form declaration it produces multiple 'Class not found' exceptions at run-time.

Using bTouch to bind to the ArcGIS iOS SDK

I apologize for such a long message in advance, but I'm trying for detail here...
I'm working on using bTouch to create a compiled dll for referencing the ArcGIS iOS SDK.
When running bTouch using :
/Developer/MonoTouch/usr/bin/btouch libArcGIS.cs
it returns the following error
/tmp/fp2ivuh8.3gj/IncidentReportApp/AGSMutablePolygon.g.cs(39,31):
error CS0102: The type `IncidentReportApp.AGSMutablePolygon'
already contains a definition for `selAddPointToRing'
/tmp/fp2ivuh8.3gj/IncidentReportApp/AGSMutablePolygon.g.cs(38,31):
(Location of the symbol related to previous error)
/tmp/fp2ivuh8.3gj/IncidentReportApp/AGSMutablePolyline.g.cs(39,31): error CS0102:
The type `IncidentReportApp.AGSMutablePolyline'
already contains a definition for `selAddPointToPath'
/tmp/fp2ivuh8.3gj/IncidentReportApp/AGSMutablePolyline.g.cs(38,31):
(Location of the symbol related to previous error)
Compilation failed: 2 error(s), 0 warnings
I checked my cs class and neither type is referenced\invoked. I'd like to understand why this message is occuring.
I have tried to use the instructions (and downloaded) code by Al Pascual at How to use the ArcGIS iPhone SDK with MonoTouch to call the Map View, but when attempting to launch the view with the code causes a crash. When I try to debug, it locks up when adding a mapping layer. I tested this with the MKMapView, but didn't experience the same behavior.
The error means that you defined more than one method mapping the same objective-C method.
Without the source, it is hard to diagnose.
I'm doing the same thing actually, I heavily modified the old "parser" library and am working on doing it now, hopefully dropping it in the public domain.
I'm seeing a similar (and probably related) problem in the ApiDefinition, there is a class AGSGPResultLayer that derives from AGSDynamicLayer. The AGSGPResultLayer overrides a property called Credential among other and since both are defining the same property.
How should over-riden properties be handled in bTouch? I'm guessing I'm missing something in the syntax.
Use the solution I provide with the correct bindings

Resources