Footnotes: Getting Digits session data back to Javascript

JP
4 min readMay 8, 2016

--

Hi there! I’m JP, a developer working with Twitter’s Fabric SDK and React Native.

Today there was a question asked on the Twitter Dev Forums about getting session data back from Digits.

I previously wrote a post on Getting Started with Digits and React Native that provided a quick walkthrough of how to wrap an (Objective C) native Digits button and vend it to a React Native app.

You’ll probably want to read that first…

So using the strategy detailed in the original post, you can easily access the session data as you normally would on the Objective C side. But what about JavaScript?

UPDATE: May 10th, 2016

Please see @Jean Lebrument ’s open-source implementation of Digits in React Native here https://github.com/JeanLebrument/react-native-fabric-digits

Events and Callbacks

There are essentially two ways of getting data from native back to React — Events, and Callbacks. Which of these you can use depends on whether your native component is a View or an arbitrary Module.

If you are using a native View and want to trigger a native Event on that view, you need to render the View at least once before your Event will work.

This is because when React renders your view it assigns it a unique reactTag, and you need to include that reactTag in your Event payload so that it can be routed to the corresponding JavaScript component correctly.

Callbacks on the other hand can be passed to any Module that you have exported to the React Bridge.

Hopefully that makes sense… In a nutshell: Events need a reactTag which means you have to render first, Callbacks do not.

Ok — so which of them can we use for our Digits button? Let’s go with a Callback for now. Though if people are interested, I’d be happy to do an example of triggering a native Event later on. Let me know 😊

DigitsManager changes

So previously, our Digits button from the last post subclassed RCTViewManager. What that means is the button that was rendered was the actual, truly native UIButton provided by DigitsKit wrapped up in a UIView.

We’re actually going to change that now. We need an authenticate method that we can both call from JavaScript, and that we can pass our callback function to as a parameter.

Now in our DigitsManager.m file:-

  • we’re subclassing RCTBridgeModule instead of RCTViewManager
  • we now have a single method called didTapButton that takes in a callback
RCT_EXPORT_METHOD(didTapButton:(RCTResponseSenderBlock)callback)
  • we’ve change from using buttonWithAuthenticationCompletion to simply authenticateWithCompletion
  • and we’re defining an NSDictionary and returning it in our callback at the end of our didTapButton method
NSDictionary *events = @{
@"userID": session.userID,
@"phoneNumber": session.phoneNumber,
};
callback(@[[NSNull null], events]);

Nothing particularly fancy here, other than RCT_EXPORT_METHOD. In combination with subclassing RCTBridgeModule, that’s going to let us call this method from JavaScript exactly as we would any other method.

The actual data that goes into your events dictionary can be anything you want. Here I’m only including userID and phoneNumber, but I could including any other properties from the Digits session.

DigitsLogin changes

Part of changing from using RCTViewManager to RCTBridgeModule means we are no longer exporting the native UIButton that DigitsKit provides.

But that’s ok — we can still access the shared Digits session (sharedInstance), and we’re now free to customize the button any way we want. So for instance, we could make it an Image now if we wanted.

So on the JavaScript side of things, we need to import a couple of extra items including TouchableHighlight, since we need to construct our button manually now. Our render method looks like this:

render() {
return
<TouchableHighlight onPress={this._onPressButton}>
<View>
<Text>Use my phone number</Text>
</View>
</TouchableHighlight>
}

and that _onPressButton method looks like this:

_onPressButton() {
var DigitsManager = NativeModules.DigitsManager;
DigitsManager.didTapButton((error, events) => {
if (error) {
console.error(error);
} else {
console.log(events);
}
});
}

Nice and simple!

Wrap-up

So to wrap up, we’ve

  • changed our native code to only trigger the authentication when didTapButton is called, not render the UIButton
  • changed our JavaScript code to handle rendering the TouchableHighlight and call didTapButton on the exported native module
  • built an NSDictionary of session data and passed it back to JavaScript in our callback function

And that, is how you get sessionID and phoneNumber back from Digits in React Native. Here’s our demo running in the Chrome developer tools.

(Obviously I’ve blanked out my own userID and phoneNumber)

As always, if anyone has any questions or comments leave them below or get me @jpdriver on Twitter. Thanks for reading!

--

--