Bug 57268 - Binding obj-c protocols errors in Cannot create an instance of "_" because it is an abstract class
Summary: Binding obj-c protocols errors in Cannot create an instance of "_" because it...
Status: RESOLVED ANSWERED
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: XI 10.10 (d15-2)
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2017-06-08 08:31 UTC by nazar
Modified: 2017-06-13 06:45 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
sustemInfo (1.65 KB, text/plain)
2017-06-08 08:31 UTC, nazar
Details
screenshot of InterfaceProtocolWrapper (143.34 KB, image/png)
2017-06-08 08:32 UTC, nazar
Details
test project which reproduces the issue (50.24 KB, application/zip)
2017-06-08 08:33 UTC, nazar
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED ANSWERED

Description nazar 2017-06-08 08:31:28 UTC
Created attachment 22767 [details]
sustemInfo

Hi, 

I'm trying to bind protocols properly and faced an issue with it.
To reproduce it I've created a super small project which shows the problem. (see that project in attachments)
Also please see system info in attached .txt file.

So based on example I provide, there is the InterfaceProtocol in my iOS framework, and I bind it like the following

    [Protocol, Model]
    [BaseType(typeof(NSObject))]
    interface InterfaceProtocol

Later on, I need to use in my ObjectBuilder as a returned type, please see the binding statement below:

        [Export("createInterfaceProtocol")]
        InterfaceProtocol CreateInterfaceProtocol();

During use that method in my test app, I got the following issue:

     Cannot create an instance of TestProject.InterfaceProtocol because it is an abstract class

Here is the thing. I've googled that and found suggestions to create a bare template for my protocol, so it could be used in bindings like the following:
      
     //bare interface
     interface IInterfaceProtocol { }

     //use it instead of InterfaceProtocol in my ObjectBuilder.
     [Export("createInterfaceProtocol")]
     IInterfaceProtocol CreateInterfaceProtocol();

If do that, it does work, but in real time, it returns me InterfaceProtocolWrapper which can't be used as it's real implementation (Interface)


You can try both, just go into ApiDefinitions.cs and add\remove IInterfaceProtocol, and use or don't use it in CreateInterfaceProtocol method.

Hope you can suggest me the proper way. Also, I might do something wrong, so corrections are highly appreciated.

Thanks in advance.
Comment 1 nazar 2017-06-08 08:32:54 UTC
Created attachment 22768 [details]
screenshot of InterfaceProtocolWrapper
Comment 2 nazar 2017-06-08 08:33:24 UTC
Created attachment 22769 [details]
test project which reproduces the issue
Comment 3 Timothy Risi 2017-06-08 21:32:18 UTC
Hello,

The second version (with the bare interface for IInterfaceProtocol) is the correct way to do it.

It returns an InterfaceProtocolWrapper object because a protocol itself cannot be passed between objective-c and c#, it has to be attached to an actual object.  The wrapper lets it go back and forth.  Anything on the protocol can be called on the wrapper (in your code for instance, you can call:

interfaceProtocol.IsInterface after the CreateInterfaceProtocol to access the IsInterface property.  If you need the actual Interface object that was created as opposed to just the protocol, you can call:

Runtime.GetNSObject<Interface> (wrapper.Handle)

to get it.
Comment 4 nazar 2017-06-13 06:45:32 UTC
Hello Timothy,

Thanks for your clarifications, now it's pretty clear, but we do have few other issues related to protocols, could you please take a look?

https://bugzilla.xamarin.com/show_bug.cgi?id=57268

Thank you in advance!!!

Best regards,
Nazar R.
Comment 5 nazar 2017-06-13 06:45:59 UTC
sorry, wrong link

here is the correct one

https://bugzilla.xamarin.com/show_bug.cgi?id=57374