[TIMOB-25478] Hyperloop: iOS - Cannot use Hyperloop.defineClass with a Classic (Non-Alloy) project
GitHub Issue | n/a |
Type | Bug |
Priority | Critical |
Status | Resolved |
Resolution | Won't Do |
Resolution Date | 2018-08-22T06:29:12.000+0000 |
Affected Version/s | n/a |
Fix Version/s | n/a |
Components | Hyperloop, iOS |
Labels | alloy, hyperloop, ios |
Reporter | Joe Falcone |
Assignee | Jan Vennemann |
Created | 2017-11-03T14:46:25.000+0000 |
Updated | 2018-08-27T09:23:46.000+0000 |
Description
While the Hyperloop requirements state "Alloy 1.8.0+" does this mean that you MUST use Alloy for your UI or just that you have Alloy 1.8.0+ installed.
We have tried to use Hyperloop with a Classic project for iOS and while the correct JS and Objective-C code was generated, the app was not able to resolve references to classes generated by the Hyperloop invocations.
We put the same code into the Hyperloop-examples app (which is Alloy) and it compiled and ran OK.
We can get more specific about the problems and submit example code but I wanted initially to see whether the intention was to allow Hyperloop to work with Classic (Non-Alloy UI) apps.
Attachments
The requirements of Alloy 1.8+ are actually only for using Hyperloop with common-js tags (e.g. exposing native api's as view tags like
<UILabel />
using own tag-classes). I am pretty sure it should work with classic Titanium but let me attach a project to verify. *EDIT*: It works, I attached an example project. I probably know you issue :-) You may created a classic project, included the module but not the plugin. Please check the tiapp.xml of the attached example and let me know, I'll keep the ticket open until then.That wasn't the problem. We're trying to use the iOS Bluetooth Library and we can get the same code to work when we include it in the Hyperloop-examples app but not in our own Classic app. We'll attach our example app but for a preview... This is the error we get at runtime from this line... var CentralManagerDelegate = Hyperloop.defineClass('CentralManagerDelegate', 'NSObject', ['CBCentralManagerDelegate']); [ERROR] : Cannot find class with name: CentralManagerDelegate ... /BLETest.app/centralmanagerdelegate.js
It is starting to look to me like its all about the file system hierarchy with Classic doing its own thing vs Alloy. I was able to get defineClass to work in a Classic project but I'm waiting for my colleague to compare what I've done to what he was trying to do.
So I went back to my colleague's test program and it is also very simple but it generates these errors from this call (I will attach his ap): var CentralManagerDelegate = Hyperloop.defineClass('CentralManagerDelegate', 'NSObject', ['CBCentralManagerDelegate']); Cannot find class with name: CentralManagerDelegate [ERROR] : Script Error { [ERROR] : column = 181; [ERROR] : description = "Cannot find class with name: CentralManagerDelegate"; [ERROR] : line = 1; [ERROR] : message = "Cannot find class with name: CentralManagerDelegate"; [ERROR] : name = ClassNotFound; [ERROR] : nativeStack = "1 libobjc.A.dylib 0x0000000111dc7f41 objc_exception_throw + 48\n2 BLETest 0x000000010af508e2 -[HyperloopClass initWithClassName:alloc:init:args:] + 386\n3 BLETest 0x000000010af43614 DefineClass + 452\n4 BLETest 0x000000010ad07c21 _ZN2TI19APICallbackFunction4callINS_18JSCallbackFunctionEEExPNS_9ExecStateE + 593\n5 BLETest 0x000000010adb6187 _ZN2TI5LLInt9setUpCallEPNS_9ExecStateEPNS_11InstructionENS_22CodeSpecializationKindENS_7TiValueEPNS_17LLIntCallLinkInfoE + 503\n6 BLETest 0x000000010adbabbd llint_op_call + 148"; [ERROR] : sourceURL = "file:///Users/jrf/Library/Developer/CoreSimulator/Devices/88EBE46A-7202-4E84-8CF2-D18FEA477C6A/data/Containers/Bundle/Application/CAD70CE8-BD5C-47D3-880E-FF5DAC2ADC7B/BLETest.app/centralmanagerdelegate.js"; [ERROR] : stack = "defineClass@[native code]\nfile:///Users/jrf/Library/Developer/CoreSimulator/Devices/88EBE46A-7202-4E84-8CF2-D18FEA477C6A/data/Containers/Bundle/Application/CAD70CE8-BD5C-47D3-880E-FF5DAC2ADC7B/BLETest.app/centralmanagerdelegate.js:1:181\nglobal code@file:///Users/jrf/Library/Developer/CoreSimulator/Devices/88EBE46A-7202-4E84-8CF2-D18FEA477C6A/data/Containers/Bundle/Application/CAD70CE8-BD5C-47D3-880E-FF5DAC2ADC7B/BLETest.app/centralmanagerdelegate.js:63:70\nrequire@[native code]\nfile:///Users/jrf/Library/Developer/CoreSimulator/Devices/88EBE46A-7202-4E84-8CF2-D18FEA477C6A/data/Containers/Bundle/Application/CAD70CE8-BD5C-47D3-880E-FF5DAC2ADC7B/BLETest.app/centralble.js:13:37\nglobal code@file:///Users/jrf/Library/Developer/CoreSimulator/Devices/88EBE46A-7202-4E84-8CF2-D18FEA477C6A/data/Containers/Bundle/Application/CAD70CE8-BD5C-47D3-880E-FF5DAC2ADC7B/BLETest.app/centralble.js:96:70\nrequire@[native code]\nfile:///Users/jrf/Library/Developer/CoreSimulator/Devices/88EBE46A-7202-4E84-8CF2-D18FEA477C6A/data/Containers/Bundle/Application/CAD70CE8-BD5C-47D3-880E-FF5DAC2ADC7B/BLETest.app/app.js:62:27\nglobal code@file:///Users/jrf/Library/Developer/CoreSimulator/Devices/88EBE46A-7202-4E84-8CF2-D18FEA477C6A/data/Containers/Bundle/Application/CAD70CE8-BD5C-47D3-880E-FF5DAC2ADC7B/BLETest.app/app.js:65:3"; [ERROR] : } [ERROR] : Script Error Module "centralmanagerdelegate.js" failed to leave a valid exports object [ERROR] : ErrorController is up. ABORTING showing of modal controller [ERROR] : Script Error Module "centralble.js" failed to leave a valid exports object [ERROR] : ErrorController is up. ABORTING showing of modal controller
Maybe I'm missing something somewhere but I can't find where to add an attachment. In any case, here is the class definition file - centralmanagerdelegate.js:
And here is the file that uses the new class... centralble.js
and here is app.js
I put all 3 of these files in the top level (Resources). That's it for the code files.
As I noted before, this code works when it is integrated into Hyperloop-examples which is an Alloy app.
So we investigates this internally and I even ran into this myself while trying to setup a test app. The reason it does does not work is that you need to import a Hyperloop-related class in order to trigger the Hyperloop compiler. Since there is no case where you would define a class without assigning it to a native class (e.g. as a delegate in 90 %), this does not represent an issue that should block anyone. An example to resolve this:
So importing any random class will do the trick and "fix" this problem. Thanks for pointing this out.
[~jfalcone] I am wondering what you do with the created native class if not passed to any other Hyperloop based API (class/method/property). I personally only used it for subclassing / delegate-handling so far, but if there is a case where you would use it without that, we can make that happen as well. A simple change would be to scan for the "Hyperloop.defineClass" call like we do for the specific require/import statements already. All in for better UX!
(define) var CentralManagerDelegate = Hyperloop.defineClass('CentralManagerDelegate', 'NSObject', ['CBCentralManagerDelegate']); ... module.exports = CentralManagerDelegate; (use) var CentralManagerDelegate = require('centralmanagerdelegate'); at no point is the BLE code directly associated w/ any native UI. so BLE is not a "Hyperloop based API"?
What my colleague is saying is that there are situations where you would be using classes that may not be associated with native UX classes such as artificial intelligence/neural networks, data mining, communications and the like.
[~weevil], [~jfalcone], i think there might be a misunderstanding here. At some point you will do
The first line is your native class usage that will trigger Hyperloop. It is not required to use any UI related classes, just any native class will do. Hans' code using the UIButton was only an example for a native class usage. I hope this clears things up :)