Expoの簡単な紹介
Reactを使用してクロスプラットフォームのモバイルアプリケーションを作成しようとしている場合は、 ReactNativeおよびExpoについて聞いたことがあるでしょう。
要約すると、Expoは、ネイティブデバイスの機能とカスタムUIへの簡単なアクセスを提供するライブラリとツールのセットと考えることができます。 この例としては、カメラ、ローカルストレージ、連絡先などがあります。
Expoを使用してネイティブロケーションAPIとインターフェイスする小さな天気アプリケーションを作成します。 これに加えて、他のユーザーが対話できるように、アプリケーションをexpo.ioで公開します。
開始するには、expo.ioでアカウントを作成してください。 これを使用して、将来のExpoプロジェクトを管理します。
ExpoCLIのインストール
ターミナルで次のコマンドを実行すると、ExpoCLIをインストールできます。
$ npm install expo-cli -g
これにより、さまざまなコマンドにアクセスできるようになります。 expo
コマンドを入力すると、説明付きのコマンドの完全なリストが表示されます。 新しいプロジェクトを初期化するには、次のように入力する必要があります。
$ expo init my-project > blank $ cd my-project $ code .
Expoは、react
、react-native
、expo
SDKなどを含む新しいプロジェクトを作成します。 これは、ReactNativeを自分でインストールする必要がないことを意味します。
この時点で、Expoアカウントへのサインインを求められる場合もあります。 以前に作成した資格情報を使用してこれを行います。
プロジェクトの実行
ビルド済みのnpm
スクリプトを使用して、iOSまたはAndroidのいずれかで空のプロジェクトを実行できます。 Expo
アプリケーションをGooglePlay/ Apple App Storeからダウンロードして、実際のデバイスですばやく簡単に実行することもできます。
どちらか(または両方!)を使用してエミュレーターでアプリケーションを実行することから始めましょう。
注:iOSシミュレーターでExpoアプリケーションを表示するには、macOSを実行しているコンピューターが必要です。
$ npm run ios $ npm run android
これにより、Metroバンドラーが起動します。これは、基本的に、最新のJavaScript機能をターゲットにするためにBabelを使用してコードをコンパイルするHTTPサーバーです。 次に、適切なシミュレーターが開き、Expoアプリケーションがインストールされます。 アプリケーションが自動的に開かない場合は、シミュレーター内からExpoアプリケーションを開きます。
問題がなければ、画面に「App.jsを開いてアプリの作業を開始してください!」という単語が表示されます。 同じことをしましょう。ただし、これを物理デバイスに設定します。
- それぞれのアプリストアでExpoアプリケーションをダウンロードします。
- Expoアプリケーションを開き、Expoアカウントでログインします。
- カメラアプリケーション内から、
npm run ios
を実行したときに開いたMetroBundlerページ(または端末)の左下にあるQRコードをスキャンします。 - プロジェクトはExpoアプリで開く必要があります。
これが機能しない場合は、接続をトンネル/LAN/ローカルモードに切り替えてみてください。
あなたの最初のエキスポアプリ
これで、App.js
から始めて、Expoアプリケーションに変更を加えることができます。 ユーザーの場所の天気を取得するアプリケーションを作成します。
まず、OpenWeatherMapAPIでアカウントを作成することから始めましょう。 APIキーがメールで送信され、チュートリアル全体でこれを使用します。
api/Api.js
内にApi.js
という名前のファイルを作成することで、特定の緯度と経度の天気を取得するAPIを作成できます。
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 }); }
この段階で、現在の場所とをキャプチャして、componentWillMount
内のlatitude
とlongitude
の天気を取得できます。
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ドキュメントの詳細ガイドを確認してください。