Harrison Harnisch
Blog About
15 April 2015
Categories React Native Meteor

Some Thoughts On Gluing React Native and Meteor

I spent some time running through the React Native tutorial and studying the APIs. It’s a great tutorial because it shows you how to get data from a RESTful API and update a React Native view. One thing that seems understated is that you can use NPM packages.

My first reaction was to try an build a app that uses the DDP NPM package to connect it to Meteor. Unfortunately the DDP NPM package didn’t work because there’s not a built in interface for websockets (yet). I ended up using an alternative approach and used the React Native bridge to connect to Objective DDP.

React Native and Meteor with Objective-DDP

First you need to connect to Meteor through Objective-DDP through the React Native bridge.

- (void)connectWithURL:(NSString *)URLString {
  RCT_EXPORT(); // tell the bridge that this function is available in JavaScript
  self.meteorClient = [[MeteorClient alloc] initWithDDPVersion:@"1"]; // use the latest DDP version
  ObjectiveDDP *ddp = [[ObjectiveDDP alloc] initWithURLString:URLString delegate:self.meteorClient];
  self.meteorClient.ddp = ddp;
  [self.meteorClient.ddp connectWebSocket]; // Connect!

  // subscribe to "added" subscription events
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(added:)
                                               name:@"added"
                                             object:nil];

  // ... add other observers for changed and removed events
}

Now create a function that exposes the Objective-DDP addSubscription.

- (void)subscribe:(NSString *)name {
  RCT_EXPORT(); // tell the bridge that this function is available in JavaScript
  [self.meteorClient addSubscription:name]; // subscribe with a subscription name
}

In the JavaScript connect to the Meteor server and subscribe to the publication.

var DDPClient = require('NativeModules').DDPClient;
DDPClient.connectWithURL('ws://localhost:3000/websocket');
DDPClient.subscribe('publicLists');

After connecting to Meteor via DDP and subscribing to a publication you push data into the Javascript runtime with the eventDispatcher.

- (void)added:(NSNotification *)notification {
  NSDictionary *added = notification.userInfo; // parse added data from the notification

  [_bridge.eventDispatcher sendDeviceEventWithName:@"added"
                                              body:added];
}

The notification is generated by the NSNotificationCenter, parses the added data, then pushes it into the eventDispacther.

In the JavaScript you listen for added events.

var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var currentRows = Immutable.List.of(); // list representation the ListView rows

var addedObserver = RCTDeviceEventEmitter.addListener('added', function(data) {
 currentRows = currentRows.push(data);
 // ... update your ListView
});

I’ve pushed a self contained, complete example of this approach on github. It handles adding, changing, and removing data that’s displayed in a React Native ListView.

React Native and Meteor with Websocket Polyfills

I think the better solution is to use a Websocket Polyfill and DDP NPM package to connect to a Meteor server. It fits more closely with the React Native mentality learn once write anywhere as it keeps your head in JavaScript working with familiar tools. I could see a future where you can use the Meteor client side packages like minimongo and ddp directly to get the data.

Current State of Websocket Polyfills In React Native

At the time of writing Websockets are not available directly in the ReactNative JavaScript runtime. There is a pretty active issue on github which seems like it’s getting some traction. This is something I’m very interested in seeing implemented for React Native as I think it’s something developers want.

React Native has definitely taken much of the friction out of iOS development (probably even more for Android when it get’s released), and because of it’s hackable architecture I think it’s going be an attractive option for mobile.