[TIMOB-23793] Hyperloop: iOS - Function not being converted to Block in a specific scenario
GitHub Issue | n/a |
---|---|
Type | New Feature |
Priority | High |
Status | Open |
Resolution | Unresolved |
Affected Version/s | n/a |
Fix Version/s | Hyperloop 3.2.0 |
Components | Hyperloop |
Labels | engArch, error, hyperloop, ios |
Reporter | Rodolfo Perottoni |
Assignee | Jan Vennemann |
Created | 2016-08-17T07:34:49.000+0000 |
Updated | 2019-10-15T15:48:32.000+0000 |
Description
I'm running an iOS HyperLoop project with TesseractOCR.
One of the features of TesseractOCR is detecting characters and execute a block after finishing the recognition. That is done with *NSOperationQueues*.
Inside their *G8RecognitionOperation* class (which extends NSOperation), they are defining a block type:
typedef void(^G8RecognitionOperationCallback)(G8Tesseract *tesseract);
And right after that they create a property with that type:
@property (nonatomic, copy) G8RecognitionOperationCallback recognitionCompleteBlock;
Normally with HyperLoop i'd send a JS function to that property, with:
operation = G8RecognitionOperation.alloc().init();
operation.recognitionCompleteBlock = function(obj) {
Ti.API.error('finished');
};
But when i build my project with this code i'm getting this error:
[ERROR] Script Error {
[ERROR] column = 14;
[ERROR] description = "-[KrollCallback copyWithZone:]: unrecognized selector sent to instance 0x7fe47d82bc20";
[ERROR] line = 134;
[ERROR] message = "-[KrollCallback copyWithZone:]: unrecognized selector sent to instance 0x7fe47d82bc20";
[ERROR] name = NSInvalidArgumentException;
So i went to the HyperLoop generated JS files and found out that the functions are not being converted to blocks in this case:
recognitionCompleteBlock: {
set: function (_recognitionCompleteBlock) {
if (!$init) { $initialize(); }
this.$private.recognitionCompleteBlock = _recognitionCompleteBlock;
$dispatch(this.$native, 'setRecognitionCompleteBlock:', _recognitionCompleteBlock);
},
enumerable: false
},
Normally i'd have something like... (extracted from the hyperloop examples project, inside the generated UIView JS wrapper):
// convert to block: void (^)(void)
var _animationsCallback = function () {
var args = [];
// convert arguments into local JS classes
_animations && _animations.apply(_animations, args);
};
var _animationsBlock = $dispatch(Hyperloop.createProxy({ class: 'HyperloopUIKit', alloc: false, init: 'class' }), 'Block_void_____void_:', [_animationsCallback], false);
I think that HyperLoop is not seeing blocks defined with *typedef* as "normal" blocks, which is preventing me to use this feature of TesseractOCR. If that is indeed true, i believe this is kinda critical. *typedef*'ing should be supported.
The problem here is that we usually handle blocks as parameter, not as properties. I can't think of a native usage that follows that pattern. So we would need a syntax for defining blocks manually (like the syntax you suggested above).
I could use the suggested syntax as above, but there's no selectors being generated inside the HyperLoop-generated *.m* files (inside */build/hyperloop/ios/js/*) that return what i need. (in this case, a G8Tesseract object). A possible solution for this: a default method to convert functions to blocks that return the objects of the type the user specifies.
I'm facing a similar error when trying to pass a callback as property. Like bq. myObject.callback = function() { }; and in objective c bq. @property(copy) KrollCallback* callback; I get the error: bq. [KrollCallback copyWithZone:]: unrecognized selector sent to instance
Sorry for moving this once again, but we want to get Hyperloop 3.1.0 out of the door asap, enabling full Hyperloop ES6+ development. Thanks everyone for the patience on this one!
+1... I need this as well (but for typedef'd blocks in the Stripe SDK). Is there a workaround in the meantime?
Facing the same issue with healthkit original objective c code:
JS code:
and I'm getting this error [KrollCallback copyWithZone:]: unrecognized selector sent to instance 0x600000370980