Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failure to find callback when communicating from native code to Javascript #1104

Closed
bhatti opened this issue May 2, 2015 · 8 comments
Closed
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@bhatti
Copy link

bhatti commented May 2, 2015

I am writing a native module which allows Javascript client to register for events with a callback and then receive events. I used examples from http://facebook.github.io/react-native/docs/nativemodulesios.html, e.g.

-(void)subscribe:(NSString *)event withCallback:(RCTResponseSenderBlock) callback;

and used RCT macros to expose those methods.

I then connected to the module from Javascript, e.g.
var SubscriptionManager = require('NativeModules').SubscriptionManager;
SubscriptionManager.subscribe("type", function(error, events) {...});

When I run the app, I receive events for a few seconds and then the native code fails to send event with warning:

2015-05-01 18:59:12.904 [info][tid:com.facebook.React.JavaScript] "Warning: Cannot find callback with CBID 73. Native module may have invoked both the success callback and the error callback."

and the app crashes with error
crash

Can someone suggest fix for this issue?

Thanks.

@ide
Copy link
Contributor

ide commented May 2, 2015

Are you invoking the Obj-C block more than once? That would cause this error.

@cxfeng1-zz
Copy link
Contributor

@ide if I want to invoke the response block more than once, how can I do?

@ide
Copy link
Contributor

ide commented May 5, 2015

You can't and will have to fire events though DeviceEventEmitter instead (grep the native module docs for examples).

@bhatti
Copy link
Author

bhatti commented May 6, 2015

The native code was calling callback block to pass events to Javascript. I can use DeviceEventEmitter but callback would have been easier as I can encapsulate logic within the block. Thanks.

@cxfeng1-zz
Copy link
Contributor

Agree with @bhatti , using callback in JS may be more intuitive. @vjeux @nicklockwood

For some reason I'm using RCTRootView along with my native component(not a react one), and I'm attempting to hook the native button from react.

    var ButtonHooker = require("NativeModules").ButtonHooker;
    ButtonHooker.hook(function() {
        // Do something
    });

On native side I keep the response callback, and every time the button is clicked, I callback to JS.

This results in above error when the button is clicked twice: null is not an object (evaluating 'cb.apply')

So I have to change the code like this:

    var ButtonHooker = require("NativeModules").ButtonHooker;
    ButtonHooker.hook();//prevent the default behaviour
    DeviceEventEmitter.addListener('ButtonClicked', function (e) {
    //Do something.
    });

Much more unreadable.

@ide
Copy link
Contributor

ide commented May 6, 2015

This might be possible if the callbacks are NSObjects instead of blocks, and in -[dealloc] they tell JS to free the corresponding JS closure. My sense is this feature is desirable but the implementation might feel a bit sketchy. Also building it on Android would require a different bag of tricks but might be possible with WeakReferences or finalize().

@bhatti
Copy link
Author

bhatti commented May 6, 2015

I am switching to DeviceEventEmitter using
var DeviceEventEmitter = require('RCTDeviceEventEmitter');
and then calling addListener per your partial examples (I didn't see how you get hold of DeviceEventEmitter), however I am seeing following error when I launch the app:

message: Requiring unknown module "RCTNativeAppEventEmitter". If you are sure the module is there, try restarting the packager."

I noticed #394 refers to this issue. Can I still use DeviceEventEmitter? I am using 0.4.0 version of the react-native library.
Thanks.

@bhatti
Copy link
Author

bhatti commented May 7, 2015

FYI, I got it working when using sendDeviceEventWithName to publish events instead of sendAppEventWithName, which was suggested by examples (https://facebook.github.io/react-native/docs/nativemodulesios.html#content).

@facebook facebook locked as resolved and limited conversation to collaborators May 29, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

5 participants