{ "id": "162650", "key": "TIMOB-23793", "fields": { "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "20128", "name": "Hyperloop 3.2.0", "archived": true, "released": false } ], "resolution": null, "resolutiondate": null, "created": "2016-08-17T07:34:49.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "engArch", "error", "hyperloop", "ios" ], "versions": [], "issuelinks": [], "assignee": { "name": "jvennemann", "key": "jvennemann", "displayName": "Jan Vennemann", "active": true, "timeZone": "Europe/Berlin" }, "updated": "2019-10-15T15:48:32.000+0000", "status": { "description": "The issue is open and ready for the assignee to start work on it.", "name": "Open", "id": "1", "statusCategory": { "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "components": [ { "id": "13715", "name": "Hyperloop", "description": "Hyperloop project" } ], "description": "I'm running an iOS HyperLoop project with TesseractOCR.\r\nOne of the features of TesseractOCR is detecting characters and execute a block after finishing the recognition. That is done with *NSOperationQueues*.\r\n\r\nInside their *G8RecognitionOperation* class (which extends NSOperation), they are defining a block type:\r\n\r\n{code:java}\r\ntypedef void(^G8RecognitionOperationCallback)(G8Tesseract *tesseract);\r\n{code}\r\n\r\nAnd right after that they create a property with that type: \r\n\r\n{code:java}\r\n@property (nonatomic, copy) G8RecognitionOperationCallback recognitionCompleteBlock;\r\n{code}\r\n\r\nNormally with HyperLoop i'd send a JS function to that property, with:\r\n\r\n{code:java}\r\noperation = G8RecognitionOperation.alloc().init();\r\noperation.recognitionCompleteBlock = function(obj) {\r\n Ti.API.error('finished');\r\n};\r\n{code}\r\n\r\nBut when i build my project with this code i'm getting this error:\r\n\r\n{code:java}\r\n[ERROR] Script Error {\r\n[ERROR] column = 14;\r\n[ERROR] description = \"-[KrollCallback copyWithZone:]: unrecognized selector sent to instance 0x7fe47d82bc20\";\r\n[ERROR] line = 134;\r\n[ERROR] message = \"-[KrollCallback copyWithZone:]: unrecognized selector sent to instance 0x7fe47d82bc20\";\r\n[ERROR] name = NSInvalidArgumentException;\r\n{code}\r\n\r\nSo i went to the HyperLoop generated JS files and found out that the functions are not being converted to blocks in this case:\r\n\r\n{code:java}\r\nrecognitionCompleteBlock: {\t\t\r\n set: function (_recognitionCompleteBlock) {\r\n if (!$init) { $initialize(); }\r\n\tthis.$private.recognitionCompleteBlock = _recognitionCompleteBlock;\r\n $dispatch(this.$native, 'setRecognitionCompleteBlock:', _recognitionCompleteBlock);\r\n },\r\n enumerable: false\r\n},\r\n{code}\r\n\r\nNormally i'd have something like... (extracted from the hyperloop examples project, inside the generated UIView JS wrapper):\r\n\r\n{code:java}\r\n// convert to block: void (^)(void)\r\nvar _animationsCallback = function () {\r\n var args = [];\r\n // convert arguments into local JS classes\r\n _animations && _animations.apply(_animations, args);\r\n};\r\nvar _animationsBlock = $dispatch(Hyperloop.createProxy({ class: 'HyperloopUIKit', alloc: false, init: 'class' }), 'Block_void_____void_:', [_animationsCallback], false);\r\n{code}\r\n\r\nI 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.\r\n\r\n\r\n\r\n\r\n\r\n\r\n", "attachment": [], "flagged": false, "summary": "Hyperloop: iOS - Function not being converted to Block in a specific scenario", "creator": { "name": "rdperottoni", "key": "rdperottoni", "displayName": "Rodolfo Perottoni", "active": true, "timeZone": "Australia/Brisbane" }, "subtasks": [], "reporter": { "name": "rdperottoni", "key": "rdperottoni", "displayName": "Rodolfo Perottoni", "active": true, "timeZone": "Australia/Brisbane" }, "environment": "Hyperloop 1.2.5\r\nTi SDK 5.4.0.GA\r\n", "comment": { "comments": [ { "id": "393645", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "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). ", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-08-19T18:59:42.000+0000", "updated": "2016-08-19T18:59:42.000+0000" }, { "id": "394016", "author": { "name": "rdperottoni", "key": "rdperottoni", "displayName": "Rodolfo Perottoni", "active": true, "timeZone": "Australia/Brisbane" }, "body": "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).\r\n\r\nA possible solution for this: a default method to convert functions to blocks that return the objects of the type the user specifies.", "updateAuthor": { "name": "rdperottoni", "key": "rdperottoni", "displayName": "Rodolfo Perottoni", "active": true, "timeZone": "Australia/Brisbane" }, "created": "2016-08-24T00:37:36.000+0000", "updated": "2016-08-24T00:37:36.000+0000" }, { "id": "406119", "author": { "name": "a.marcone", "key": "a.marcone", "displayName": "Alberto Marcone", "active": true, "timeZone": "Europe/Berlin" }, "body": "I'm facing a similar error when trying to pass a callback as property.\r\n\r\nLike \r\n\r\nbq. myObject.callback = function() { };\r\n\r\nand in objective c\r\n\r\nbq. @property(copy) KrollCallback* callback;\r\n\r\nI get the error:\r\n\r\nbq. [KrollCallback copyWithZone:]: unrecognized selector sent to instance ", "updateAuthor": { "name": "a.marcone", "key": "a.marcone", "displayName": "Alberto Marcone", "active": true, "timeZone": "Europe/Berlin" }, "created": "2017-02-02T08:16:12.000+0000", "updated": "2017-02-02T08:16:12.000+0000" }, { "id": "436047", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "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!", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-03-28T18:49:14.000+0000", "updated": "2018-03-28T18:49:14.000+0000" }, { "id": "436203", "author": { "name": "bjenkins", "key": "bjenkins", "displayName": "Brad Jenkins", "active": true, "timeZone": "America/Los_Angeles" }, "body": "+1... I need this as well (but for typedef'd blocks in the Stripe SDK). Is there a workaround in the meantime? ", "updateAuthor": { "name": "bjenkins", "key": "bjenkins", "displayName": "Brad Jenkins", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-04-03T00:15:47.000+0000", "updated": "2018-04-03T00:15:47.000+0000" }, { "id": "446557", "author": { "name": "sali.abdullah", "key": "sali.abdullah", "displayName": "sali.abdullah", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Facing the same issue with healthkit \r\noriginal objective c code: \r\n{code:objectivec}\r\nquery.initialResultsHandler =\r\n^(HKStatisticsCollectionQuery *query, HKStatisticsCollection *results, NSError *error) {\r\n})\r\n{code}\r\n\r\nJS code: \r\n\r\n{code:java}\r\nquery.initialResultsHandler = function(query, results, error){\r\n \r\n };\r\n{code}\r\n and I'm getting this error [KrollCallback copyWithZone:]: unrecognized selector sent to instance 0x600000370980\r\n", "updateAuthor": { "name": "sali.abdullah", "key": "sali.abdullah", "displayName": "sali.abdullah", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-03-05T18:49:16.000+0000", "updated": "2019-03-05T18:49:16.000+0000" } ], "maxResults": 7, "total": 7, "startAt": 0 } } }