Siphon is shutting down on 27th July 2016. To our customers, users and supporters: unfortunately this is the end of the road for Siphon. Our long-term goal was to create the most developer friendly end-to-end publishing platform for mobile apps.

Due to some inherent limitations in the early design decisions that we made (in particular the inability to compile your own native modules with Siphon) we have come to the regrettable conclusion that this vision is not possible at this time. We hoped that these native bridged modules would mature and become less important over time, but this has turned out to not be the case.

All apps created using Siphon are fully compatible with the standard React Native framework and transferring your app should only take a few minutes. Please email us if you need any help migrating your app.

Thanks to everyone who supported us over the past few months.
/docs
Fundamentals Quickstart FAQ Native modules Base versions Running on your device How publishing works Assets Ignoring files Over-the-air updates Convert an existing React Native app Sharing Beta testing Collaborating in a team Tutorials Build a real-time chat app Build a YouTube video browser Using Facebook's SDK with Siphon Turn an existing React Native app into a Siphon app Siphon Sandbox iOS (App Store) Android (Google Play)
Build a real-time chat app with Siphon

We're going to build a simple real-time chat application using React Native. Follow the quickstart tutorial first if you haven't yet set up your machine to use Siphon.

Install the command-line tool

Create a new Siphon app

Navigate to a suitable directory (anywhere is fine) and type the following command to create a new app:

$ siphon create chat-app

You can call it anything you like, but for the rest of this tutorial we will refer to the app as chat-app.

A new directory containing the basic app template will be created on your local machine and the files will be pushed to our servers.

Open up the Siphon Sandbox app on your iOS device and tap the new app icon to run it.

The app directory works like a typical Node.js project directory; you can install
suitable third-party modules using npm install and the command-line tool will push the node_modules directory and bundle it with your app.
Add a simple user interface

We're going to alter the template app that we just created. Open up the file called chat-app/index.js in your favourite editor.

Lets add a minimal user interface ready for sending and receiving chat messages. Remove the contents of that file and paste in the following code:


'use strict';

var React = require('react-native');
var {
  AppRegistry,
  Text,
  TextInput,
  ScrollView,
  View
} = React;

var App = React.createClass({
  getInitialState: function() {
    return {
      messages: []
    }
  },
  handleSubmit: function(event) {
    // Does nothing yet.
  },
  render: function() {
    return (
      <View style={{paddingTop: 20}}>
        <TextInput
          ref='textInput'
          autoCapitalize='none'
          autoCorrect={ false }
          placeholder='Enter a chat message...'
          returnKeyType='send'
          style={{
            height: 40,
            borderColor: 'gray',
            borderWidth: 1,
            margin: 10,
            padding: 5
          }}
          onSubmitEditing={this.handleSubmit.bind(this)}
        />
        <ScrollView style={{height: 400}}>
          {
            this.state.messages.map(m => {
              return <Text style={{margin: 10}}>{m}</Text>
            })
          }
        </ScrollView>
      </View>
    );
  }
});

AppRegistry.registerComponent('App', () => App);

Later we'll use a websocket to connect to the server and append incoming messages to the messages state, but for now the UI is going to look quite empty.

Save the file and push your changes to Siphon:

$ siphon push

The app will reload itself and you should see something like this:

Receiving chat messages with a websocket

We're going to use the WebSocket class provided by React Native to send and receive chat messages.

First we will only log incoming messages to the console. Add these two methods to your App class definition:


componentDidMount: function() {
  console.log('Connecting...');
  this.ws = new WebSocket('wss://siphon-chat.herokuapp.com');
  this.ws.onmessage = function(event) {
    if (event.data != 'ping') {
      console.log('Received: ' + event.data);
    }
  }.bind(this);
  this.ws.onerror = function() {
    console.log('WebSocket error: ', arguments);
  };
},
componentWillUnmount: function() {
  this.ws.close();
},

After the App component gets rendered, its going to open up a socket and start printing incoming messages to the console.

Open up a separate terminal window and leave it streaming the logs from your app:

$ cd chat-app
$ siphon logs

Now save the file and switch back to the other terminal window to push the changes:

$ siphon push

You should see some log output in the new terminal window. If there are other Siphon users currently chatting, you may see some incoming messages in the logs.

We set up a shared Node.js chat server at siphon-chat.herokuapp.com. When you've finished the app, you get to chat to everyone else taking this tutorial too!
Mutating state with incoming chat messages

Let's make a small change so that incoming chat messages are displayed in the UI. Replace the definition of componentDidMount with this one:


componentDidMount: function() {
  this.ws = new WebSocket('wss://siphon-chat.herokuapp.com');
  this.ws.onmessage = function(event) {
    if (event.data != 'ping') {
      this.setState({
        messages: [event.data].concat(this.state.messages)
      });
    }
  }.bind(this);
  this.ws.onerror = function() {
    console.log('WebSocket error: ', arguments);
  };
},

Push your changes and run the app in the sandbox:

$ siphon push

Any incoming chat messages will now be displayed visually.

Sending chat messages

Lets hook up the <TextInput> component so that it broadcasts its contents to the chat server when we hit send.

Replace the empty definition of handleSubmit with this one:


handleSubmit: function(event) {
  console.log('Sending: ' + event.nativeEvent.text);
  this.ws.send(event.nativeEvent.text);
  this.refs.textInput.setNativeProps({text: ''});
},

Now when you hit send, it sends the message across the websocket that we created earlier and then clears the contents of the <TextInput>.

Push your changes and open the app. It should look like this:

Complete source code for this app is available on GitHub.

That's the end of the tutorial, thanks for following along.

Next up

Build a YouTube browser FAQs How to publish an app

Watch the video
More docs
Fundamentals Quickstart FAQ Native modules Base versions Running on your device How publishing works Assets Ignoring files Over-the-air updates Convert an existing React Native app Sharing Beta testing Collaborating in a team Tutorials Build a real-time chat app Build a YouTube video browser Using Facebook's SDK with Siphon Turn an existing React Native app into a Siphon app Siphon Sandbox iOS (App Store) Android (Google Play)