Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-26318] Hyperloop: iOS - TiApp Utility Class methods throw selector-error

GitHub Issuen/a
TypeBug
PriorityCritical
StatusResolved
ResolutionFixed
Resolution Date2018-08-21T12:58:13.000+0000
Affected Version/sHyperloop 3.1.1
Fix Version/sHyperloop 3.1.2
ComponentsHyperloop
Labelsn/a
ReporterRichard Lustemberg
AssigneeHans Knöchel
Created2018-08-18T13:03:05.000+0000
Updated2018-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

FileDateSize
Hyperloop_Test.zip2018-08-18T13:03:00.000+00004918959

Comments

  1. Hans Knöchel 2018-08-18

    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) from registerApplicationDelegate to registerApplicationDelegate:. Same goes for the unregisterApplicationDelegate and unregisterApplicationDelegate: 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) returns NO, 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:
       - (char) application:(id)arg1 didFinishLaunchingWithOptions:(id)arg2; (0x106ee60c0)
       
    You may note that it uses char instead of BOOL, but that should still work, since BOOL extends the char type. I tried with another selector (applicationDidEnterBackground:) and it also did not work. The selector for that one looks like this:
       - (void) applicationDidEnterBackground:(id)arg1; (0x106ee6c10)
       
    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 API class_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 the respondsToSelector API.
  2. Hans Knöchel 2018-08-21

    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 use defineClass 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)
  3. Richard Lustemberg 2018-08-21

    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.
  4. Hans Knöchel 2018-08-21

    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.
  5. Richard Lustemberg 2018-08-21

    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?
  6. Hans Knöchel 2018-08-21

    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.
  7. Richard Lustemberg 2018-08-21

    Supercool, that's all I needed to know :) . I'll report any issue I might have registering the UIApplicationDelegate objects.
  8. Hans Knöchel 2018-08-21

    Hyperloop 3.1.2 Beta can be checked [here](https://github.com/appcelerator-modules/hyperloop-builds/releases/tag/v3.1.2-beta.1).
  9. Richard Lustemberg 2018-08-24

    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 and applicationWillResignActive. Sorry I was a bit late in my reply.

JSON Source