Reactを使用してクロスプラットフォームのモバイルアプリケーションを作成しようとしている場合は、 ReactNativeおよびExpoについて聞いたことがあるでしょう。

要約すると、Expoは、ネイティブデバイスの機能とカスタムUIへの簡単なアクセスを提供するライブラリとツールのセットと考えることができます。 この例としては、カメラ、ローカルストレージ、連絡先などがあります。

Expoを使用してネイティブロケーションAPIとインターフェイスする小さな天気アプリケーションを作成します。 これに加えて、他のユーザーが対話できるように、アプリケーションをexpo.ioで公開します。

開始するには、expo.ioでアカウントを作成してください。 これを使用して、将来のExpoプロジェクトを管理します。

ExpoCLIのインストール

ターミナルで次のコマンドを実行すると、ExpoCLIをインストールできます。

このコマンドを実行する前に、Node.jsiOS / AndroidSDKをインストールする必要があります。

$ npm install expo-cli -g

これにより、さまざまなコマンドにアクセスできるようになります。 次のように入力すると、説明付きのコマンドの完全なリストが表示されます。 expo 指図。 新しいプロジェクトを初期化するには、次のように入力する必要があります。

$ expo init my-project
> blank

$ cd my-project
$ code .

Expoは、次のようなものを含む新しいプロジェクトを作成します。 react, react-native そしてその expo SDK。 これは、ReactNativeを自分でインストールする必要がないことを意味します。

この時点で、Expoアカウントへのサインインを求められる場合もあります。 以前に作成した資格情報を使用してこれを行います。

プロジェクトの実行

ビルド済みのビルドを介して、iOSまたはAndroidのいずれかで空白のプロジェクトを実行できます npm スクリプト。 ダウンロードすることもできます Expo Google Play / Apple App Storeのアプリケーションを使用して、これを実際のデバイスですばやく簡単に実行できます。

どちらか(または両方!)を使用してエミュレーターでアプリケーションを実行することから始めましょう。

注:iOSシミュレーターでExpoアプリケーションを表示するには、macOSを実行しているコンピューターが必要です。

$ npm run ios
$ npm run android

これにより、Metroバンドラーが起動します。これは、基本的に、最新のJavaScript機能をターゲットにするためにBabelを使用してコードをコンパイルするHTTPサーバーです。 次に、適切なシミュレーターが開き、Expoアプリケーションがインストールされます。 アプリケーションが自動的に開かない場合は、シミュレーター内からExpoアプリケーションを開きます。

問題がなければ、画面に「App.jsを開いてアプリの作業を開始してください!」という単語が表示されます。 同じことをしましょう。ただし、これを物理デバイスに設定します。

  1. それぞれのアプリストアでExpoアプリケーションをダウンロードします。
  2. Expoアプリケーションを開き、Expoアカウントでログインします。
  3. カメラアプリケーション内から、実行時に開いたMetro Bundlerページ(またはターミナル)の左下にあるQRコードをスキャンします npm run ios.
  4. プロジェクトはExpoアプリで開く必要があります。

これが機能しない場合は、接続をトンネル/LAN/ローカルモードに切り替えてみてください。

あなたの最初のエキスポアプリ

これで、Expoアプリケーションに変更を加えることができます。 App.js. ユーザーの場所の天気を取得するアプリケーションを作成します。

まず、OpenWeatherMapAPIアカウントを作成することから始めましょう。 APIキーがメールで送信され、チュートリアル全体でこれを使用します。

名前の付いたファイルを作成することにより、特定の緯度と経度の天気を取得するAPIを作成できます。 Api.js の中に api/Api.js:

const APP_ID = 'YOUR_APP_ID';
const APP_URL = `http://api.openweathermap.org/data/2.5/weather`;

export const getWeather = async (lat, lon) => {
    const res = await fetch(`${APP_URL}?lat=${lat}&lon=${lon}&units=metric&APPID=${APP_ID}`);
    const weatherData = await res.json();
    return weatherData;
};

Expoを使用しているため、ユーザーの現在地を簡単に取得できます。 中にそれをしましょう App.js:

import { Location, Permissions } from 'expo';

// Omitted
async _getLocation () {
  const { status } = await Permissions.askAsync(Permissions.LOCATION);

  if (status !== 'granted') {
    this.setState({
      error: 'User denied access to location.'
    });
  }

  const location = await Location.getCurrentPositionAsync({});
  this.setState({ location });
}

この段階で、現在地をキャプチャしてその天気を取得できます latitudelongitude の中に componentWillMount:

import { getWeather } from './api/Api';

// Omitted
async componentWillMount () {
  this.setState({
    loading: true
  });

  await this._getLocation();

  const lat = this.state.location.coords.latitude;
  const lon = this.state.location.coords.longitude;

  const weatherData = await getWeather(lat, lon);

  this.setState({
    weatherData,
    loading: false
  });
}

それを私たちと組み合わせる render ビューは、内部に次のコンポーネントを提供します App.js:

import React from "react";
import { StyleSheet, Text, View, ImageBackground } from "react-native";
import { Location, Permissions } from "expo";

import { getWeather } from "./api/Api";

export default class App extends React.Component {
  state = {
    weatherData: [],
    loading: false
  };

  async componentWillMount() {
    this.setState({
      loading: true
    });

    await this._getLocation();

    const lat = this.state.location.coords.latitude;
    const lon = this.state.location.coords.longitude;

    const weatherData = await getWeather(lat, lon);

    this.setState({
      weatherData,
      loading: false
    });
  }

  async _getLocation() {
    const { status } = await Permissions.askAsync(Permissions.LOCATION);

    if (status !== "granted") {
      console.error("Not granted! Uh oh. :(");
    }

    const location = await Location.getCurrentPositionAsync({});
    this.setState({ location });
  }

  render() {
    const { weather, main } = this.state.weatherData;

    if (this.state.loading) {
      return (
        <ImageBackground
          style={styles.background}
          source={require("./assets/background.png")}
        >
          <View style={styles.container}>
            <Text style={styles.text}>Loading...</Text>
          </View>
        </ImageBackground>
      );
    } else {
      return (
        <ImageBackground
          style={styles.background}
          source={require("./assets/background.png")}
        >
          <View style={styles.container}>
            <View style={styles.weatherCard}>
              <Text style={styles.text}>{main.temp}°C</Text>
              <Text style={styles.text}>{weather[0].main}</Text>
            </View>
          </View>
        </ImageBackground>
      );
    }
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
    paddingLeft: 10,
    color: "white"
  },
  background: {
    width: "100%",
    height: "100%"
  },
  weatherCard: {
    width: 350,
    height: 120,
    borderRadius: 20,
    shadowOffset: { width: 0, height: 6 },
    shadowColor: "#000",
    shadowOpacity: 0.5,
    shadowRadius: 14,
    elevation: 13,
    padding: 10
  },
  text: {
    fontSize: 40,
    textAlign: "center",
    color: "white"
  }
});

プロジェクトを公開する

アプリケーションを公開する場合、ExpoCLIはターミナルからこれを実行できます。 以下を実行して、iOSおよびAndroid用にビルドします。

expo publish

[00:54:09] Unable to find an existing Expo CLI instance for this directory, starting a new one...
[00:54:22] Starting Metro Bundler on port 19001.
[00:54:24] Tunnel ready.
[00:54:24] Publishing to channel 'default'...
[00:54:26] Building iOS bundle
[00:54:55] Finished building JavaScript bundle in 28885ms.
[00:54:55] Building Android bundle
[00:55:20] Finished building JavaScript bundle in 24779ms.
[00:55:20] Analyzing assets
[00:55:23] Finished building JavaScript bundle in 3504ms.
[00:55:26] Finished building JavaScript bundle in 2951ms.
[00:55:26] Uploading assets
[00:55:27] Uploading /assets/background.png
[00:55:29] Processing asset bundle patterns:
[00:55:29] - /Users/paulhalliday/my-project/**/*
[00:55:29] Uploading JavaScript bundles
[00:55:41] Published
[00:55:41] Your URL is https://exp.host/@paulhalliday/my-project

URLを知っている人は誰でも、QRコードを取得して、Expoアプリ内でアプリケーションを開くことができます。 ぜひお試しください。

それぞれの.IPA/APKファイルなどを使用してより高度なビルドを実行したい場合は、Expoドキュメントの詳細ガイドを確認してください。