Search this blog

Monday, 7 December 2015

Build a native mobile app with React Native

Anton Mills reveals how to build iOS applications using React Native, Facebook's new native application development framework.




Native mobile app development is a difficult environment. There are different operating systems, a vast array of handset manufacturers and a huge range of screen resolutions to build for. Thankfully, Facebook has released React Native – a framework designed to extend the React approach to mobile application development.
In this tutorial, we're going to build a real-time weather app using

OpenWeatherMap's free API. I will cover working with React Native components, imagery and styles, and loading and parsing JSON data.

Getting started

First, download the source files from GitHub. You will find a 'source-imagery' folder that contains the tutorial images, an 'article-steps' folder that contains the source code for each step (plus comments), and a 'completed-project' folder containing the final source project.
You'll need Xcode for compiling the iOS apps (available from the App Store) and the Homebrew OSX package manager. Once you have Homebrew installed, you can open a Terminal window and run the following commands (if you have issues, there a guide here):
  • brew install node to installNode.js
  • brew install watchman to install Watchman, a file-watching service
  • brew install flow, a static data type checker
  • npm install -g react-native-cli to install React Native
You can create the project by typingreact-native init weatherapp. Make a note of the project folder and open it to see React Native's default folder structure. The iOS directory is where the iOS platform's project files reside. The file we're interested in at this point is 'index.ios.js'. Open this up in your editor of choice.
Let's take a look at the folder structure:
  • Lines 8-11 include the React requires for this component of the app
  • Lines 15-32 declare the default class for the weatherapp and its render methods
  • Lines 34-51 define the styles used in the app
  • Line 53 is this Component's export name
The first thing we need to do is to prepare a blank canvas. Change the render method to:
  1. render: function() {
  2. return (
  3. <View style={[styles.container,{backgroundColor: this.state.backgroundColor}]}>
  4. </View>
  5. );
  6. }
This creates an empty view using an array of styles - the container style and a state variable calledbackgroundColor. We will change the backgroundColorvariable based on the current temperature when we query the weather API for data. We can also set the container's style to use flex: 1for centring.
  1. container: {
  2. flex: 1
  3. },
Now we're going to use React'sgetInitialState method. This is invoked automatically on any component when the app is run. We'll use it to declare state variables that are used later. Add this above the render method in the WeatherAppclass:
  1. getInitialState: function() {
  2. return {
  3. weatherData: null,
  4. backgroundColor: "#FFFFFF"
  5. };
  6. },
Now is a perfect time to jump into Xcode and hit play on the simulator to see your application. One of React Native's fantastic features is its recompile speed. Edit #FFFFFF to another colour and hit 'cmd+R' to see the almost instant reload – pretty neat!

Declaring constants

Let's declare the constants used for the background colours, and another for theopenweathermap.org URL that provides the weather data. Add the following just below the React requires:
  1. var BG_HOT = "#fb9f4d";
  2. var BG_WARM = "#fbd84d";
  3. var BG_COLD = "#00abe6";
  4. var REQUEST_URL ="http://api.openweathermap.org/data/2.5/weather?units=metric&";
We'll also need to use another of React's built-in methods,componentDidMount. This is invoked automatically when a component loads successfully. We'll use it to query the navigator to get the current geolocation. Add the following after getInitialState method and before the render method:
  1. componentDidMount: function() {
  2. navigator.geolocation.getCurrentPosition(
  3. location => {
  4. var formattedURL = REQUEST_URL + "lat=" +location.coords.latitude + "&lon=" +location.coords.longitude;
  5. console.log(formattedURL);
  6. },
  7. error => {
  8. console.log(error);
  9. });
  10. },
When compiled, the simulator will ask you to allow the application access to your location. You should see the completed URL (the variableformattedURL) displayed in the Xcode output window. React Native usesconsole.log() to display content like this – very handy for debugging.
The next step is to send our latitude and longitude to theopenweathermap.org API. Add the following code belowcomponentDidMount and above render:
  1. fetchData: function(url) {
  2. fetch(url)
  3. .then((response) => response.json())
  4. .then((responseData) => {
  5. var bg;
  6. var temp = parseInt(responseData.main.temp);
  7. if(temp < 14) {
  8. bg = BG_COLD;
  9. } else if(temp >= 14 && temp < 25) {
  10. bg = BG_WARM;
  11. } else if(temp >= 25) {
  12. bg = BG_HOT;
  13. }
  14. this.setState({
  15. weatherData: responseData,
  16. backgroundColor: bg
  17. });
  18. })
  19. .done();
  20. },
The above code connects to the API to get the JSON response. It then parses the location's temperature and updates the state variable backgroundColor. When the app next renders, it uses this new colour.
Finally, you need to add a line that will call this new fetchData method from the componentDidMountmethod. The following code goes directly below the console.log we used to display the URL:
  1. this.fetchData(formattedURL);
As there may be a delay in loading API data, we need to display a new view that will act as holding text. The following method will return a new view with loading text:
  1. renderLoadingView: function() {
  2. return (
  3. <View style={styles.loading}>
  4. <Text style={styles.loadingText}>
  5. Loading Weather
  6. </Text>
  7. </View>
  8. );
  9. },
As the app renders, it needs to check its state to see if the weather data is available or not:
  1. if (!this.state.weatherData) {
  2. return this.renderLoadingView();
  3. }
Now, add your own customloading andloadingText styling into the styles and this section is done.


This is the main React Native template from the CLI tool
This is the main React Native template from the CLI tool

When you test the app, you should briefly see the loading message and then a background colour that reflects the temperature.

Weather information

It's now time to create the component that displays the weather information. Create a new folder called 'App' in your project root. In this, create another folder called 'Views' , into which we'll copy the WeatherView template from the article steps.
You will notice it is almost identical to the main class. As it already contains placeholder text, we'll jump back to our main index.ios.js class and add a declaration for the component.
  1. var WeatherView =require('./App/Views/WeatherView.js');
Then in the render method, we simply add:
  1. <WeatherView />


You will be asked to accept geolocation for the app
You will be asked to accept geolocation for the app

Upon restarting the simulator with 'cmd+R' , you should see 'TEST' displayed in the centre of the screen. You've now loaded your new component.

Adding icons

Now we're going to add icons to our Xcode project for each of the weather types (codes are provided here). In Xcode, open 'Images.xcassets' and drag all of the images from the 'weather_icons' folder.
To save a lot of typing, go into the GitHub repo, and replace your current 'WeatherView.js' with the one in Step 7. The new code you can see is an array, indexed by the weather icon code returned from the API. Before we can use it, we need to pass the weather data into this component.
In order to achieve this, we can use state variables again, and – thanks topropTypes – we can declare thedata-type we expect back. Add the following directly under theWeatherView class creation:
  1. propTypes: {
  2. weather: React.PropTypes.string,
  3. temperature: React.PropTypes.int,
  4. city: React.PropTypes.string,
  5. country: React.PropTypes.string
  6. },
Let's amend the markup returned fromWeatherView. The following code adds a weather image, plus text for the temperature and city and country. Notice how the tags reference theprops variables and, for the image, the variable for the key of the array, so the correct image shows.
  1. <View style={styles.centreContainer}>
  2. <Image source={weatherIconArray[this.props.weather]} style={styles.weatherIcon} />
  3. <Text style={styles.weatherText}>{this.props.temperature}&deg;</Text>
  4. <Text style={styles.weatherTextLight}>{this.props.city},</Text>
  5. <Text style={styles.weatherTextLight}>{this.props.country}</Text>
  6. </View>
The styles we need to add for this are:
  1. weatherIcon: {
  2. width: 132,
  3. height: 132,
  4. },
  5. weatherText: {
  6. fontSize: 62,
  7. fontWeight: "bold",
  8. color: "#FFFFFF",
  9. textAlign: "center"
  10. },
  11. weatherTextLight: {
  12. fontSize: 32,
  13. fontWeight: "100",
  14. color: "#FFFFFF",
  15. textAlign: "center"
  16. }
Here we specify the weather icons' width and height. The weatherTextstyle creates a large, heavy font for the temperature, andweatherTextLight creates a light font for the location fields.

Adding data

All that remains is to add some data. Head to your 'index.ios.js' and update the render method to:
  1. var city =this.state.weatherData.name.toUpperCase();
  2. var country =this.state.weatherData.sys.country.toUpperCase();
  3. var temp =parseInt(this.state.weatherData.main.temp).toFixed(0);
  4. var weather =this.state.weatherData.weather[0].icon.toString();
  5. return (
  6. <View style={[styles.container,{backgroundColor: this.state.backgroundColor}]}>
  7. <WeatherView
  8. weather={weather}
  9. temperature={temp}
  10. city={city}
  11. country={country} />
  12. </View>
  13. );
This parses the JSON response and takes the city, country and temperature data, and passes it to the component. Now if you 'cmd+R' to restart the simulator, you should see your final app.
This is the core of building a React Native application. It's that simple! I hope you enjoy working with it.
WordsAnton Mills
Anton Mills is a creative technologist who also specialises in game development. This article was originally published in issue 270 of net magazine.

1 comment:

olorunfemi otedola said...

you are welcome hellan...