0

I created a bindings library project to be able to run an Android .aar file. One of the several errors i got was:

Error  CS0115  'Call.OnWarning(IDictionary)': no suitable method found to override TwilioBindings  C:\...\TwilioBindings\obj\Debug\generated\src\Com.Twilio.Voice.Call.cs;

And to solve it i verified api.xml and saw that the method onWarning had a parameter with the type java.util.HashMap:

<method abstract="false" deprecated="not deprecated" final="false" name="onWarning" native="false" return="void" static="false" synchronized="false" visibility="public">
    <parameter name="p0" type="java.util.HashMap">
    </parameter>
</method>

The class Call is extending InternalCall which implements RTCMonitorCommand.Listener and after i checked the api.xml file i notice that the method onWarning had the follow definition:

InternalCall:

<method abstract="false" deprecated="not deprecated" final="false" name="onWarning" native="false" return="void" static="false" synchronized="false" visibility="public">
    <parameter name="warningDetails" type="java.util.HashMap&lt;java.lang.String, java.lang.Object&gt;">
    </parameter>
</method>

RTCMonitorCommand.Listener:

<method abstract="true" deprecated="not deprecated" final="false" name="onWarning" native="false" return="void" static="false" synchronized="false" visibility="public">
    <parameter name="p0" type="java.util.HashMap&lt;java.lang.String, java.lang.Object&gt;">
    </parameter>
</method>

So i came to the conclusion that only the class Call had a diferent parameter type.

Therefore i wrote the follow line in Metadata.xml to change the parameter type of the method onWarning in class Call:

<attr path="/api/package[@name='com.twilio.voice']/class[@name='Call']/method[@name='onWarning' and count(parameter)=1 and parameter[1][@type='java.util.HashMap']]/parameter[1]" name="type">java.util.HashMap&lt;java.lang.String, java.lang.Object&gt;</attr>

The error went away but i'm having some problems using this bindings project and this is the line in Metadata.xml that i'm not shure that is right.

Does anyone know if my approach was correct ?

Any help whould be apreciated,

Thank you.

rcardoso
  • 11
  • 6

2 Answers2

0

I was having problems when calling a method from this binding library and i thought that was caused by some binding error but then, after searching in the logs i came to the conclusion that the problem was that the library wasn't being able to find a dependency. The dependency project was being referenced by the binding project but somehow the reference wasn't working. So i changed the reference and instead of referencing the package i referenced the package dll and now it functions properly.

rcardoso
  • 11
  • 6
0

For future users that come across this error. I have 2 scenarios that caused this issue for me and the fix for them is below:

Scenario 1:

"no suitable method found to override" received after implementing an interface member via metadata.xml to fix the error "[className] does not implement interface member [memberName]". My [className] is DefaultTimerBar and my interface member name is ITimeBar.SetEnabled(bool).

  <!--Fixes The following metadata change will resolve "[className] does not implement interface member [memberName]",
  however it will now give the error "DefaultTimeBar.SetEnabled(bool): no suitable method found to override"-->

  <add-node path="/api/package[@name='com.mycompany.mypackage']/class[@name='DefaultTimeBar']">
    <method name="setEnabled" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
      <parameter name="p0" type="boolean"/>
    </method>
  </add-node>

  <!--The fix for this scenario was to change the name of the method from "setEnabled" to "SetEnabled". This resolved both errors-->
  <add-node path="/api/package[@name='com.mycompany.mypackage']/class[@name='DefaultTimeBar']">
    <method name="SetEnabled" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
      <parameter name="p0" type="boolean"/>
    </method>
  </add-node>

My suspicion is when the interface member is named as "getX()" or "setX()" the compiler sees this as a get/set property. In the case above for setEnabled(bool), when the method name attribute is lowercase, the method will be implemented as an override. Subsequently yielding the error: No suitable method found to override. When changed to uppercase, it will be implemented as virtual correctly. My reasoning is due to the same behavior not occurring when the method name does not begin with get/set in the .aar file.

Scenario 2:

The error [className].[methodName]: no suitable method found to override received without previous metadata transform for the specific method. My method was named SetFullScreen(bool) so I assumed it was due to the same issue with the compiler incorrectly seeing this as a getter/setter. My solution was to remove the method, then re-add the method with the leading letter of the name capitalized. I simply copied the method's details from the api.xml file within the binding project directory obj\Debug\api.xml.

  <remove-node path="/api/package[@name='com.mycompany.mypackage']/class[@name='VideoPlayerViewExo']/method[@name='setFullScreen' and count(parameter)=1 and parameter[1][@type='boolean']]"/>

  <add-node path="/api/package[@name='com.mycompany.mypackage']/class[@name='VideoPlayerViewExo']">
    <method abstract="false" deprecated="not deprecated" final="false" name="SetFullScreen" jni-signature="(Z)V" bridge="false" native="false" return="void" jni-return="V" static="false" synchronized="false" synthetic="false" visibility="public">
      <parameter name="fullscreen" type="boolean" jni-type="Z">
      </parameter>
    </method>
  </add-node>
Ashetynw
  • 198
  • 1
  • 12