Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind Method With Delegate

Tags:

I'm creating a binding library to bind native Objective-C framework.

I have the following delegate which I need to add it's declaration to ApiDefinition file and then I need to implement it using my Xamarin.iOS app:

- (void)Initialize:(id <MMSDKDelegate> _Nullable)pDelegate;

MMSDKDelegate:

@protocol MMSDKDelegate <IMMDelegate>
- (void)Started;
@end

IMMDelegate:

@protocol IMMDelegate
- (void)Inserted;
- (void)Removed;
- (void)ReaderConnected;
- (void)ReaderRemoved;
@end

I need the required definition in ApiDefinition file and I need a sample code to call this method from my Xamarin.iOS app.

Update

The Framework I'm dealing with is communicating with card reader device attached with iPhone to read ID card info, it has methods to be called on reader inserted / removed & card inserted / removed..

I have implemented the answer by @cole-xia, but the issue is the methods inside IMMDelegate are never called when I insert card reader or ID. When I call ReadCardData(), it should call Started() which will display information saved by Inserted(), but the current result is that Started() method is called after calling ReadCardData(), but Inserted() and ReaderConnected() are never called in any stage.

In the demo app of Framework, it is used as the following (and works properly):

// Demo app -> ViewController.m

@interface ViewController () <MMSDKDelegate>

@end


@implementation ViewController {
    MMSDK *sdkInstance;
}


- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    sdkInstance = [MMSDK SharedInstance];
    [sdkInstance Initialize:self];
}


- (void)Started
{
    // Update UI by: reading in progress ..
}


- (void)Inserted
{
    // Update UI by: card inserted
    // And read card data
    [self readData:self];
}

- (void)Removed
{
    // Update UI by: card removed
}

- (void)ReaderConnected
{
    // Update UI by: card reader connected
}

- (void)ReaderRemoved
{
    // Update UI by: card reader removed
}


- (IBAction)readData:(id)sender
{
    var *data = [sdkInstance ReadCardData:YES pWithSignatureImage:YES pWithAddressData:YES];
    if (data.hasError) {
        // No data fetched
        return;
    }

    if (data) {
        // return card data
    }
}

All suggestions are welcome and appreciated.

In summary, I just need to do same functionality of demo app in Xamarin.iOS app.

like image 443
Moamen Naanou Avatar asked Nov 08 '17 10:11

Moamen Naanou


People also ask

Why delegates why not call methods directly?

If you think of delegates as being similar to interface definitions for a specific type of method, you can start to see why delegates exist. They allow clients of our delegates to ignore all the details of their implementations - even their names!

How do you call a delegate method in C#?

In C# 3.0 and later, delegates can also be declared and instantiated by using a lambda expression, as shown in the following example. // Instantiate Del by using a lambda expression. Del del4 = name => { Console. WriteLine($"Notification received for: {name}"); };

What is a delegate method?

A delegate is a type that represents references to methods with a particular parameter list and return type. When you instantiate a delegate, you can associate its instance with any method with a compatible signature and return type. You can invoke (or call) the method through the delegate instance.

How do you use delegates?

Delegates allow methods to be passed as parameters. Delegates can be used to define callback methods. Delegates can be chained together; for example, multiple methods can be called on a single event. Methods don't have to match the delegate type exactly.


1 Answers

Use Sharpie to create ApiDefinition

The result on my side :

// @protocol IMMDelegate
[BaseType (typeof (NSObject))]
[Protocol, Model]
interface IMMDelegate
{
    // @required -(void)Inserted;
    [Abstract]
    [Export ("Inserted")]
    void Inserted ();

    // @required -(void)Removed;
    [Abstract]
    [Export ("Removed")]
    void Removed ();
}

// @protocol MMSDKDelegate <IMMDelegate>
[BaseType (typeof (NSObject))]
[Protocol, Model]
interface MMSDKDelegate : IMMDelegate
{
    // @required -(void)Started;
    [Abstract]
    [Export ("Started")]
    void Started ();
}

// @interface ACR : NSObject
[BaseType (typeof(NSObject))]
interface YourClass
{
    // -(void)Initialize:(id<MMSDKDelegate> _Nullable)pDelegate;
    [Export ("Initialize:")]
    void Initialize ([NullAllowed] MMSDKDelegate pDelegate);
}

Usage:

class MyDelegate : MMSDKDelegate {
    public void Started()
    {
    }

    public override void Removed()
    {
    }
    public override void Inserted()
    {
    }
}


//In ViewController

public override void ViewDidLoad()
{
    base.ViewDidLoad();

    YourClass yourClass = new YourClass();
    yourClass.Initialize(new MyDelegate());
}
like image 64
ColeX - MSFT Avatar answered Sep 20 '22 12:09

ColeX - MSFT