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アカウントへのサインインを求められる場合もあります。 以前に作成した資格情報を使用してこれを行います。
プロジェクトの実行
ビルド済みのビルドを介して、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を開いてアプリの作業を開始してください!」という単語が表示されます。 同じことをしましょう。ただし、これを物理デバイスに設定します。
- それぞれのアプリストアでExpoアプリケーションをダウンロードします。
- Expoアプリケーションを開き、Expoアカウントでログインします。
- カメラアプリケーション内から、実行時に開いたMetro Bundlerページ(またはターミナル)の左下にあるQRコードをスキャンします
npm run ios
. - プロジェクトは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 });
}
この段階で、現在地をキャプチャしてその天気を取得できます latitude
と longitude
の中に 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ドキュメントの詳細ガイドを確認してください。