Bind Method With Delegate

2019-06-22 01:22发布

问题:

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.

回答1:

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());
}


回答2:

Along with Cola Xia's answer you may also need to make sure that, such third party device SDK integration requires some entries in the info.plist file's "Supported external accessory protocols" key.

Please check XCode sample and check if there is an entry for the "Supported external accessory protocols" key. If it is there, then you should add them in your Xamarin.iOS project's info.plist file.

I hope this may help!