0
votes

I'm an objective-c novice, so please forgive what may be incorrect terminology.

In Xamarin.iOS, I am successfully employing a C# class with multiple static methods to implement callback functionality from objective-C to C#. I'd like to avoid the creation of a binding library (don't want to use Sharpie and related tools / steps). I'm looking for a way for objective-c to callback to non-static methods in C#. Is it possible for objective-c to callback to non-static Xamarin.iOS C# methods? My objective-c to C# call-back technique is as follows and is further described below:

  • Create a class in C# that contains my static call-back methods. This class inherits from NSObject.
  • Create a @protocol in objective-c that matches the "call-back" class defined in C#.
  • Instantiate the "call-back" class in C# and get its NSObject.Class.Handle
  • Pass the NSObject.Class.Handle for the "call-back" class instance from C# to objective-c,
  • In objective-c, cast the handle to an id (for the previously defined @protocol) and use this id as a delegate to the C# class instance (which now appears as an @interface instance in objective-c).

Using this technique, I am able to treat my C# "call-back" class instance as an @interface instance in objective-c. In objective-c, I can call methods in my C# class instance by treating them as @interface instance methods.

In C#

  • Define a class that inherits from NSObject (NSObject includes Class.Handle definition)
  • [Register] the class and [Export] the static callbacks within the class
  • Use 'NSObject.Class.Handle' to get IntPtr class handle
  • Marshal the class instance handle (IntPtr) to objective-c as 'UnmanagedType.IUnknown'

In objective-c

  • define a '@protocol' that corresponds to the C# class. The @protocol has instance methods that correspond to each static callback method in the C# class
  • cast the IntPtr (from C#) as an 'id' for the '@protocol'
  • use the id as a delegate to the C# class instance (which behaves as an objective-c @interface instance)

Using this technique, I can use the C# class handle as a protocol id in objective-c and reference the C# class as an @interface in objective-c.

Can this same (or similar) method (passing a class handle from C# to objective-c and using this class handle as the delegate) be employed to call non-static C# methods from objective-c?

    // C# "call-back" class
    [Register("AppDelegate")]
    public class AppDelegate : NSObject
    {
        [Export("OnLoginSucceeded:")]
        public static void OnLoginSucceeded(string sessionToken)
        {
            // Do stuff
        }

        [Export("OnRequestFailed")]
        public static void OnRequestFailed()
        {
            // Do stuff
        }

        [Export("OnConnectionFailed")]
        public static void OnConnectionFailed()
        {
            // Do stuff
        }

        public IntPtr GetInstancePointer()
        {
            IntPtr self = Class.Handle;
            return self;
        }
    }


    // objective-c protocol for C# "call-back" class
    #import <Foundation/Foundation.h>

   @protocol AppDelegate <NSObject>
    - (void)OnLoginSucceeded : (NSString*)sessionToken;
    - (void)OnRequestFailed;
    - (void)OnConnectionFailed;

    @end


    // objective-c calls to C# callback
    [self.appDelegate OnLoginSucceeded : response.sessionToken];
    [self.appDelegate OnRequestFailed];
    [self.appDelegate OnConnectionFailed];
1
If answer be helpful , remember to mark ot vote up later when have time.Thanks in advance *.^Junior Jiang
Your article is very informative. Thank you. I'm not ready to mark it as "the answer" to my question, but it contains more information than I've found anywhere else about C# / objective-c bindings.Tony

1 Answers

0
votes

Is it possible for objective-c to callback to non-static Xamarin.iOS C# methods?

Not too much understanding non-static , howver I know that when binding custom controls , Binding properties must be static .

  • Binding properties must be static - When defining the binding of properties, the [Static] attribute must be used.