难以绑定不带参数的iOS委托方法

时间:2015-04-28 03:33:34

标签: c# ios objective-c xamarin xamarin.ios

当绑定iOS lib.a for Xamarin时,我收到以下错误:

btouch: The delegate method Device.SomeDeviceDelegate.CaptureComplete needs to take at least one parameter (BI1003)

生成绑定Objective Sharpie

namespace Device 
{   

    // @protocol SomeDeviceDelegate <NSObject>
    [Protocol, Model, Preserve]
    [BaseType(typeof(NSObject))]
    interface SomeDeviceDelegate
    {
        // @optional -(void)CaptureComplete;
        [Export("CaptureComplete")]
        void CaptureComplete();
    }

    // @interface SomeDevice : NSObject
    [Protocol, Model, Preserve]
    [BaseType(typeof(NSObject), Delegates = new[] { "WeakDelegate" }, Events = new[] { typeof(SomeDeviceDelegate) })]
    interface SomeDevice
    {
        [Wrap("WeakDelegate")]
        SomeDeviceDelegate Delegate { get; set; }

        // @property (assign, nonatomic) id<SomeDeviceDelegate> delegate;
        [NullAllowed, Export("delegate", ArgumentSemantic.Assign)]
        SomeDeviceDelegate WeakDelegate { get; set; }
    }

}

NB。我已将名称更改为SomeDevice以隐藏硬件/设备名称(NDA)。

编译器抱怨// @optional -(void)CaptureComplete;和相应的绑定CaptureComplete()没有参数,并且它至少需要一个参数。

问:我需要做些什么才能绑定此委托?

我尝试了Binding Types Reference Guide,并尝试应用

  • EventArgs属性
  • NoDefaultValue属性
  • DefaultValueFromArgument属性

更新

我误解了NoDefaultValueDefaultValueFromArgument属性,当委托返回一个值(例如bool)时会使用它们,因为返回会干扰事件的Xamarin包装。

2 个答案:

答案 0 :(得分:2)

我昨天晚些时候找到了解决方案,并为遇到相同错误消息的其他人提出了这个问题。

注意:这次没有更改名称,因为它使答案不太明确。

处理ObjC委托的首选方法是将它们公开为事件,例如

prepareForSegue

BaseType的Delegate和Events参数生成包装ICBarCodeReaderDelegate上每个方法的代码。

// @interface ICBarCodeReader : ICISMPDevice
[DisableDefaultCtor]
[BaseType(typeof(ICISMPDevice), Delegates = new[] { "WeakDelegate" }, Events = new[] { typeof(ICBarCodeReaderDelegate) }))]
public interface ICBarCodeReader
{
    [Wrap("WeakDelegate")]
    ICBarCodeReaderDelegate Delegate { get; set; }

    // @property (assign, nonatomic) id<ICISMPDeviceDelegate,ICBarCodeReaderDelegate> delegate;
    [NullAllowed, Export("delegate", ArgumentSemantic.Assign)]
    ICBarCodeReaderDelegate WeakDelegate { get; set; }
}

允许您在项目中执行以下操作:

// @protocol ICBarCodeReaderDelegate
[Protocol, Model, Preserve]
[BaseType(typeof(ICISMPDeviceDelegate))]
public interface ICBarCodeReaderDelegate
{
    // @required -(void)barcodeData:(id)data ofType:(int)type;
    [Abstract]
    [Export("barcodeData:ofType:")]
    [EventArgs("BarcodeData")]
    void BarcodeData(string data, BarCodeSymbologies type);

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

但是,当方法没有参数时,这种方法会失败,如btouch错误消息所述。

我发现的另一种方法(现在看起来很简单直接)不是将委托包装为事件,例如

public void Init()
{
    _sharedBarCodeReader.BarcodeData += OnBarcodeData;
}

private void OnBarcodeData(object sender, BarcodeDataEventArgs e)
{
    var barcode = Convert.ToString(sender); // this maps to string data
    //BarCodeSymbologies is in BarcodeDataEventArgs

    var handler = BarCodeData;
    if (handler != null)
        handler(this, barcode);
}

而是创建Delegate接口的实现。

e.g。

// @interface ICBarCodeReader : ICISMPDevice
[DisableDefaultCtor]
[BaseType(typeof(ICISMPDevice))]
public interface ICBarCodeReader
{
    [Wrap("WeakDelegate")]
    ICBarCodeReaderDelegate Delegate { get; set; }

    // @property (assign, nonatomic) id<ICISMPDeviceDelegate,ICBarCodeReaderDelegate> delegate;
    [NullAllowed, Export("delegate", ArgumentSemantic.Assign)]
    ICBarCodeReaderDelegate WeakDelegate { get; set; }
}

我希望这有助于其他人。

答案 1 :(得分:0)

“CaptureComplete:”可能会期待发件人?