when binding ios lib.a xamarin, i'm getting following error:
btouch: delegate method device.somedevicedelegate.capturecomplete needs take @ least 1 parameter (bi1003)
the bindings generated 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. i've changed name somedevice
hide hardware/device name (nda).
the compiler complaining // @optional -(void)capturecomplete;
, respective binding capturecomplete()
has no parameters , needs @ least one.
q: need bind delegate?
i have tried binding types reference guide , have tried applying the
eventargs
attributenodefaultvalue
attributedefaultvaluefromargument
attribute
update
i misunderstood nodefaultvalue
, defaultvaluefromargument
attributes, used when delegate returns value (e.g. bool
) return interferes xamarin wrapping of event.
i found solution late yesterday , closing out question others encounter same error message.
nb: haven't change names time made answer less clear.
the preferred way of handling objc delegate expose them events, e.g.
// @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; } }
the delegate , events parameter of basetype, generates codes wraps each method on icbarcodereaderdelegate.
// @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(); }
which allows in project do:
public void init() { _sharedbarcodereader.barcodedata += onbarcodedata; } private void onbarcodedata(object sender, barcodedataeventargs e) { var barcode = convert.tostring(sender); // maps string data //barcodesymbologies in barcodedataeventargs var handler = barcodedata; if (handler != null) handler(this, barcode); }
however approach fails when method has no parameters, told btouch error message.
the other approach discovered (and appears straight forward , simple) not wrap delegate events, 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; } }
and instead create implementation of delegate interface.
e.g.
public void init() { _sharedbarcodereader.delegate = new barcodereaderdelegate(this); } private class barcodereaderdelegate : icbarcodereaderdelegate { public barcodereaderdelegate(barcodescanner barcodescanner) { _barcodescanner = barcodescanner; } public override void barcodedata(string data, barcodesymbologies type) { var handler = _barcodescanner.barcodedata; if (handler != null) handler(this, data); } public override void configurationrequest() { } private readonly barcodescanner _barcodescanner; }
i hope helps else.