Nwht0xn1

React NativeでamakanのiPhone用アプリをつくってみるCreated on 2016-08-23 by r7kamura

突然ですが本日は、https://amakan.net/ 用のiOSアプリを、React Nativeを使って作っていく様子を紹介したいと思います。

React Native準備

https://facebook.github.io/react-native/ が公式サイトです。Macで開発するので、インストールに必要な以下のコマンドを
入力します。ところでNode.jsのバージョンはv6.1.0を使いました。v0.12とかではまるで歯が立たないので気を付けましょう。

brew install node
brew install watchman
npm install -g react-native-cli

amakaniプロジェクト作成

プロジェクト名はamakaniということにします。amakan + iOS でamakaniです。蟹です。自分はソースコードの管理に https://github.com/motemen/ghq を利用しているので、~/src 以下にGitHubのレポジトリを置いています。amakanには https://github.com/amakan というGitHub Organizationがあるので、amakaniもOSS化してこのOrganizationの配下に置くことにします。

cd /Users/r7kamura/src/github.com/amakan
react-native init amakani

このコマンドでamakaniプロジェクトがつくられるようですが、これは5分ぐらい掛かります。

起動

以下のコマンドでiOSシミュレーターが立ち上がり、空っぽのアプリが起動するようです。

react-native run-ios

死亡

起動しましたがアプリが一瞬で死亡しました。

image

image

気を取り直して再実行。

image

ターミナル.app の表示が変わりました。nvm経由でNode.js v6.1.0を利用しているので、ターミナル.appで何かをするときにシステムのNode.js v0.12.2が使われているようです。

nvm alias default v6.1.0

このコマンドでデフォルトでv6.1.0を使うようにしたので更に react-native run-ios を再実行。

image

アプリ起動。何か読み込んでいる様子。

image

雛形的な表示が完了。

image

Command+Dで便利そうなのが登場。

image

トップページを編集

とりあえずデフォルトのトップページを編集してバナナでも置いてみます。公式サイトの https://facebook.github.io/react-native/docs/props.html を見る限り、ImageとTextのcomponentがreact-nativeで提供されているようなんで、これを使ってやっていきます。できることだけやる。react-nativeで大事なことのような気がしてきました。

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from "react";
import {
  AppRegistry,
  Image,
  StyleSheet,
  Text,
  View,
} from "react-native";

class amakani extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Image
          source={{ uri: "https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg" }}
          style={{ width: 193, height: 110 }}
        />
        <Text style={styles.welcome}>
          さまざまなバナナ
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#F5FCFF",
  },
  welcome: {
    fontSize: 20,
    textAlign: "center",
    margin: 10,
  },
  instructions: {
    textAlign: "center",
    color: "#333333",
    marginBottom: 5,
  },
});

AppRegistry.registerComponent("amakani", () => amakani);

リロード

iOS SimulatorでCommand+Rを押したら即座にリロードできるっぽくて便利。これで画像が表示できました。amakanでは本の表紙画像とテキスト、あとは別のページに移動するボタンがあればいいんで、ほぼ完成に近づいていると言えます。

image

TabBarIOS

Twitterアプリの下部などに表示されているような、iOS用のタブバーを表示してみます。https://facebook.github.io/react-native/docs/tabbarios.html を見るとTabBarIOSというComponentが用意されているようなので、これが利用できそうです。詳細は説明見れば分かるはずなんで、試しに書いてみたコードはこういう感じ。

import React, { Component } from "react";
import {
  AppRegistry,
  TabBarIOS,
  Text,
  View,
} from "react-native";

class Home extends Component {
  render() {
    return(
      <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
        <Text>
          ホーム
        </Text>
      </View>
    );
  }
}

class MyPage extends Component {
  render() {
    return(
      <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
        <Text>
          マイページ
        </Text>
      </View>
    );
  }
}

class Settings extends Component {
  render() {
    return(
      <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
        <Text>
          設定
        </Text>
      </View>
    );
  }
}

class amakani extends Component {
  constructor(...args) {
    super(...args);
    this.state = {
      selectedTab: "home",
    };
  }

  render() {
    return (
      <TabBarIOS>
        <TabBarIOS.Item
          title="ホーム"
          icon={require("./images/home.png")}
          selected={this.state.selectedTab === "home"}
          onPress={() => {
            this.setState({ selectedTab: "home" });
          }}
        >
          <Home/>
        </TabBarIOS.Item>
        <TabBarIOS.Item
          title="マイページ"
          icon={require("./images/user.png")}
          selected={this.state.selectedTab === "my-page"}
          onPress={() => {
            this.setState({ selectedTab: "my-page" });
          }}
        >
          <MyPage/>
        </TabBarIOS.Item>
        <TabBarIOS.Item
          title="設定"
          icon={require("./images/cog.png")}
          selected={this.state.selectedTab === "settings"}
          onPress={() => {
            this.setState({ selectedTab: "settings" });
          }}
        >
          <Settings/>
        </TabBarIOS.Item>
      </TabBarIOS>
    );
  }
}

AppRegistry.registerComponent("amakani", () => amakani);

これでこういう風な画面が出来上がります。

image

TabBarIOS.Itemにはアイコン画像が必要ですが、これはプロジェクトに配置したものを require で参照できます。他にもNavigationBarなど、OS標準のUIを扱うComponentもそこそこ提供されているので、これらを組み合わせていけばそれなりの見栄えのものが出来ると思います。

WebView

WebViewというcomponentも存在していて、簡単なWebサービスのiOSアプリ化ならこれで済む場合もあるかもしれません。amakanで試してみた例がこちら。アプリ側にヘッダが存在するので、アプリからアクセスした場合はヘッダ部分を一部省略してみています。

image

今回はここまで

続きの活動は amakan/amakani: amakan mobile apps for Android and iPhone. で行われています。