[TIMOB-26318] Hyperloop: iOS - TiApp Utility Class methods throw selector-error
GitHub Issue | n/a |
Type | Bug |
Priority | Critical |
Status | Resolved |
Resolution | Fixed |
Resolution Date | 2018-08-21T12:58:13.000+0000 |
Affected Version/s | Hyperloop 3.1.1 |
Fix Version/s | Hyperloop 3.1.2 |
Components | Hyperloop |
Labels | n/a |
Reporter | Richard Lustemberg |
Assignee | Hans Knöchel |
Created | 2018-08-18T13:03:05.000+0000 |
Updated | 2018-08-24T07:48:39.000+0000 |
Description
When attempting to register a UIApplicationDelegate instance through hyperloop the following exception is thrown:
{noformat}
[ERROR] : can't find selector registerApplicationDelegate for
[ERROR] : -[HyperloopPointer registerApplicationDelegate]: unrecognized selector sent to instance 0x60c00009c520
[ERROR] : Script Error {
[ERROR] : column = 26;
[ERROR] : description = "-[HyperloopPointer registerApplicationDelegate]: unrecognized selector sent to instance 0x60c00009c520";
[ERROR] : line = 128;
[ERROR] : message = "-[HyperloopPointer registerApplicationDelegate]: unrecognized selector sent to instance 0x60c00009c520";
[ERROR] : name = NSInvalidArgumentException;
[ERROR] : nativeStack = "1 libobjc.A.dylib 0x0000000114af1031 objc_exception_throw + 48\n2 CoreFoundation 0x0000000115beb784 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132\n3 Hyperloop Test 0x000000010d1ab106 +[HyperloopUtils invokeSelector:args:target:instance:] + 4646\n4 Hyperloop Test 0x000000010d19f1a1 Dispatch + 1489\n5 JavaScriptCore 0x000000010d5a0b63 _ZN3JSC19APICallbackFunction4callINS_18JSCallbackFunctionEEExPNS_9ExecStateE + 595\n6 ??? 0x000002c074094034 0x0 + 3025603739700\n7 JavaScriptCore 0x000000010d567d00 llint_entry + 29438\n8 JavaScriptCore 0x000000010d567d00 llint_entry + 29438\n9 JavaScriptCore 0x000000010d56081a vmEntryToJavaScript + 304\n10 JavaScriptCore 0x000000010da41d43 _ZN3JSC7JITCode7executeEPNS_2VMEPNS_14ProtoCallFrameE + 147\n11 JavaScriptCore 0x000000010d9fd617 _ZN3JSC11Interpreter14executeProgramERKNS_10SourceCodeEPNS_9ExecStateEPNS_8JSObjectE + 12343\n12 JavaScriptCore 0x000000010dc442c4 _ZN3JSC8evaluateEPNS_9ExecStateERKNS_10SourceCodeENS_7JSValueERN3WTF8NakedPtrINS_9ExceptionEEE + 308\n13 JavaScriptCore 0x000000010d59fec2 JSEvaluateScript + 482\n14 Hyperloop Test 0x000000010cece121 -[KrollBridge evalFileOnThread:context:] + 1281\n15 Hyperloop Test 0x000000010ced3f0c -[KrollInvocation invoke:] + 124\n16 Hyperloop Test 0x000000010ced53df -[KrollContext invoke:] + 159\n17 Hyperloop Test 0x000000010ced5775 -[KrollContext invokeOnThread:method:withObject:callback:selector:] + 165\n18 Hyperloop Test 0x000000010cece293 -[KrollBridge evalFile:callback:selector:] + 115\n19 Hyperloop Test 0x000000010cecf105 -[KrollBridge didStartNewContext:] + 2565\n20 Hyperloop Test 0x000000010ced605b -[KrollContext main] + 1819\n21 Hyperloop Test 0x000000010ced51b6 __21-[KrollContext start]_block_invoke + 38\n22 libdispatch.dylib 0x0000000116da86cb _dispatch_call_block_and_release + 12\n23 libdispatch.dylib 0x0000000116da9709 _dispatch_client_callout + 8\n24 libdispatch.dylib 0x0000000116db3708 _dispatch_main_queue_callback_4CF + 1279\n25 CoreFoundation 0x0000000115b2cc99 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9\n26 CoreFoundation 0x0000000115af0ea6 __CFRunLoopRun + 2342\n27 CoreFoundation 0x0000000115af030b CFRunLoopRunSpecific + 635\n28 GraphicsServices 0x0000000118ad4a73 GSEventRunModal + 62\n29 UIKit 0x000000010f7dd057 UIApplicationMain + 159\n30 Hyperloop Test 0x000000010cebae04 main + 100\n31 libdyld.dylib 0x0000000116e1e955 start + 1\n32 ??? 0x0000000000000001 0x0 + 1";
[ERROR] : sourceURL = "file:///Users/richard/Library/Developer/CoreSimulator/Devices/21CF36EB-29EB-4B54-980E-5E6B514B4869/data/Containers/Bundle/Application/EEC17584-4B00-4E92-A39A-8F5E8DDECBCC/Hyperloop%20Test.app/hyperloop/titanium/tiapp.js";
[ERROR] : stack = " at dispatch@[native code]\n at value@file:///Users/richard/Library/Developer/CoreSimulator/Devices/21CF36EB-29EB-4B54-980E-5E6B514B4869/data/Containers/Bundle/Application/EEC17584-4B00-4E92-A39A-8F5E8DDECBCC/Hyperloop%20Test.app/hyperloop/titanium/tiapp.js:128:26)\n at global code@file:///Users/richard/Library/Developer/CoreSimulator/Devices/21CF36EB-29EB-4B54-980E-5E6B514B4869/data/Containers/Bundle/Application/EEC17584-4B00-4E92-A39A-8F5E8DDECBCC/Hyperloop%20Test.app/app.js:31:40)";
[ERROR] : }
{noformat}
I'm providing an example project where I've copied and pasted the example code from Titanium's wiki
Attachments
This looks valid - although I tested it just a few weeks ago. Let me check this on Monday and come back to you asap! *EDIT*: Found it. What a silly error, sorry for that! You can patch your Hyperloop simply by going to
<project>/modules/iphone/hyperloop/3.1.1/hooks/generate/templates/builtins/titanium.js
and change line 132 (the selector) fromregisterApplicationDelegate
toregisterApplicationDelegate:
. Same goes for theunregisterApplicationDelegate
andunregisterApplicationDelegate:
if used. It will be added to Hyperloop 3.1.2 asap! *EDIT 2*: Ok, so the method works now, but the selector does not seem to be picked up so far. Debugging the iOS source, it looks like the [tryToInvokeSelector:
call](https://github.com/appcelerator/titanium_mobile/blame/7_3_X/iphone/Classes/TiApp.m#L694) returnsNO
, indicating that the method selector cannot be resolved. Then I debugged all methods that the generated Hyperloop-class has and it indeed includes the selector:You may note that it uses
char
instead ofBOOL
, but that should still work, sinceBOOL
extends thechar
type. I tried with another selector (applicationDidEnterBackground:
) and it also did not work. The selector for that one looks like this:Which is also fine. The only difference is that the "arg1" is usually called "application", but that should not matter for the selector itself. Finally, I verified that the Hyperloop-defined class indeed implements the
UIApplicationDelegate
protocol by using the objc-runtime APIclass_copyProtocolList
to introspect the class protocol definitions. I am running out of ideas, but it may be the selector-argument naming causing this. It works with native modules, so it must be a Hyperloop bug, not SDK bug. *EDIT 3*: I create a [pull request](https://github.com/appcelerator/hyperloop-examples/pull/78) to show my current state on this. *EDIT 4*: It may be that our Hyperloop-defined classes do not export a proper public header and therefore do not respond to therespondsToSelector
API.Hey [~rlustemberg], discard my previous comments. The issue why it wasn't fired after the initial fix was that I provided the wrong instance to
registerApplicationDelegate
. Passing the correct one works fine and should do for you as well. Right now, we are still investigating why the "this" from a non-require-based scope does not work (e.g. if you usedefineClass
in the same file as the execution). Let me know if your test cases work already! [Working example here](https://github.com/appcelerator/hyperloop-examples/pull/78/files)Great news!. I’ll test later today and let you know. BTW, is there a trick to be able to debug Hyperloop using Xcode. Out of the box it doesn’t work on my case. The Hyperloop object is not available and an exception is thrown.
Yey. The Hyperloop stubs (or "wrappers") are generated based on the usage and represent virtual classes. Using Chrome dev-tools (Android) or Safari (iOS), you could debug it down to the stubs and see the invocations, but everything else is done internally using reflection.
So if I'm using Hyperloop in a project, but also using iOS native modules, I won't be able to debug the latter because Hyperloop won't work?
I think then I misunderstood your question. You can always debug the project. You only need to make sure the Hyperloop stubs are copied to your app target, e.g. by copying the stubs from build/hyperloop/ios/js/* to your Xcode-target and be sure that they are copied to your app bundle. But this is highly unrelated to this ticket. To keep this one clean, we should focus on this one.
Supercool, that's all I needed to know :) . I'll report any issue I might have registering the UIApplicationDelegate objects.
Hyperloop 3.1.2 Beta can be checked [here](https://github.com/appcelerator-modules/hyperloop-builds/releases/tag/v3.1.2-beta.1).
It's working on my use case (registering app delegate methods for the XMPP framework). And indeed, it's necessary to generate the class in a separate require, otherwise, the 'this' in the wrapper object does't survive the app resigning active. Defining the app delegate class on a separate file works correctly. I've tested with
didFinishLaunchingWithOptions
,applicationDidBecomeActive
andapplicationWillResignActive
. Sorry I was a bit late in my reply.