koogawa log

iOS、Android、foursquareに関する話題

React Native さわってみたメモ

今年のはじめにこんな記事がバズった。

b.hatena.ne.jp

批判的なコメントが多かったせいか、記事自体はもう消されてしまっている。

自分も数年前に Titanium を使ったことがあり、そんときは「Nativeで頑張ったほうが良さそう」と思って使うのをやめてしまった。ただ、その頃から状況も変わっているだろうし、この人の言っていることを無下に批判する気にはなれなかった。

そんなわけで、実際に自分の手で動かしてみることにした。以下はその時の作業メモ(自分用なので読みやすさは考慮してません)

動作環境

  • react-native: 0.41.1
  • Xcode 8.3
  • Android Studio 2.2.3
    • Build #AI-145.3537739, built on December 2, 2016
    • JRE: 1.8.0_112-release-b05 x86_64
    • JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o

作ったソースコード

https://github.com/koogawa/ReactNativeSample

インストール

Getting Started に従って、Node、Watchman、React Native CLI をインストール。

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

サンプルプロジェクトの作成

簡単なiOSアプリとAndroidアプリを作ってみる。

iOS

react-native init AwesomeProject
cd AwesomeProject

これだけで最低限の機能を備えたiOSアプリを生成してくれる。(言語はObjective-C

吐き出されたソース

react-native run-ios

を実行すれば iOS Simulator を起動してくれる。もしくは出力された xcodeproj を Xcode で開いて自分でビルドすることもできる。

ビルド自体は本当に簡単にできた。

cmd+d でデバッグメニューが出てくる。

出力されたコードを見てみる

デバッグメニューを出すのをどうやって実現しているのか気になったのでソースを追ってみると

    RCTKeyCommands *commands = [RCTKeyCommands sharedInstance];

    // Toggle debug menu
    [commands registerKeyCommandWithInput:@"d"
                            modifierFlags:UIKeyModifierCommand
                                   action:^(__unused UIKeyCommand *command) {
                                     [weakSelf toggle];
                                   }];

こんな感じでやっていた。cmdキーを検知できるの知らなかった。

AppDelegate も読んでみる。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSURL *jsCodeLocation;

  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"ReactNativeSample"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  return YES;
}

index.ios.js から RCTRootView を生成して self.window.rootViewController にセットしてる感じなのね。

ためしに index.ios.js に変更を加えて再度ビルドしてみたけど、AppDelegate に差分は出なかった。某クラスプラットフォームのように、単純に機械的なコードを吐き出してるわけでは無さそうだ。この辺はとてもシンプル。

Android

同じソースコードAndroidアプリも作ってみる。

SDK Manager を起動して、必要なパッケージをインストール。

このとき Android SDK Build-Tools 23.0.1 にチェックが入ってないとダメ。

環境変数 ANDROID_HOME にもパスをセットする必要がある。

export ANDROID_HOME=${HOME}/Library/Android/sdk
export PATH=${PATH}:${ANDROID_HOME}/tools
export PATH=${PATH}:${ANDROID_HOME}/platform-tools

最初、ここのパスを間違えて結構ハマった。

次に Android Studio から AVD Manager を起動して、エミュレータを起動しておくのがポイント。

f:id:koogawa:20170205073018p:plain

f:id:koogawa:20170205073232p:plain

AVD Managerは

android avd

のコマンドでも起動できる。

react-native run-android

でアプリを実行。

こんな感じで Android アプリもビルドできた。

タブバーを表示してみる

TabBarIOSの公式ドキュメント通り実装してみるが、何故かエラーが出る。。🤔

調べてみてわかったのだが、

var React = require('react');
var ReactNative = require('react-native');

みたいな書き方はすでに古くなっているらしい😩

Does React Native use require or import? - Stack Overflow

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

のような書き方に修正することで、なんとかビルドが通った。

f:id:koogawa:20170205075010p:plain

見てるドキュメントが間違ってるのかもしれないけど、公式ドキュメントが最新になってないのはちょっと焦った😞

TabBarIOS という名前なので、Androidの場合はどうするんだろう?という疑問が湧いたが、やはり同じことを考える人がすでにいた。

How to make Tab bar for Android like TabBarIOS in react native? - Stack Overflow

こうやってiOS用のコードとAndroid用のコードを別々に管理していくことになりそう。

所感

  • ホントに簡単にアプリを作り始められる
  • 公式ドキュメント通りやっても動かないことが多々ある
    • 正しい情報を探すことになり、ここに多くの時間を割くことになりそう
  • ビルドしてみないとエラーかどうかわからないのがつらい
  • コードの補完機能がないのが地味につらい
  • パフォーマンスとかはもうちょっと使ってみないとわからない
  • iOS/Android のバージョンが上がったときに追従してくれるか不安

お世話になったリンク