はじめに
こんにちは、梅雨です。
2024/11/13に Expo SDK 52が公開されました。
今回の記事では、Expo SDK 52で新たに使用可能になった機能などについて解説してきいたいと思います。
New Architecture が利用可能に
The New Architecture is now enabled by default for all new projects. Starting with SDK 52, when you create a new project with npx create-expo-app, you will see that newArchEnabled is set to true in your app.json.
ドキュメントによると、SDK 52のリリースによってデフォルトで New Architecture が利用可能になるようです。
New Architecture とは、Meta によって開発が行われている React Native における新しい内部構造のことであり、React Native 0.68から試験的にオプトインされています。
Expo には SDK 51から試験的にオプトインされていましたが、今回の SDK 52からは公式に New Architecture の使用が推奨されます。
New Architecture の導入によって、アプリケーションの起動時間やメモリ使用量が大幅に削減されることが見込まれています。
また、SDK 52より前のバージョンで開発が行われていたプロジェクトに関しても、SDK 52へのアップデートによってNew Architectureの使用が可能になります。
app.json
の中で newArchEnabled
プロパティを false
にすることで明示的に不使用とすることもできます。
expo-video
正式リリース
SDK 51 から beta 版として公開されていた expo-video
ライブラリが正式に安定版としてリリースされました。
以前から提供されていたビデオコンポーネントである expo-av
からの移行が推奨されています。
$ npx expo install expo-video
{
"expo": {
"plugins": [
[
"expo-video",
{
"supportsBackgroundPlayback": true,
"supportsPictureInPicture": true
}
]
],
}
}
VideoView
という UI コンポーネントと useVideoPlayer
というフックが使用できます。
import { useEvent } from "expo";
import { useVideoPlayer, VideoView } from "expo-video";
import { StyleSheet, View, Button } from "react-native";
const videoSource =
"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4";
const VideoScreen = () => {
const player = useVideoPlayer(videoSource, (player) => {
player.loop = true;
player.play();
});
const { isPlaying } = useEvent(player, "playingChange", {
isPlaying: player.playing,
});
return (
<View style={styles.contentContainer}>
<VideoView
style={styles.video}
player={player}
allowsFullscreen
allowsPictureInPicture
/>
<View style={styles.controlsContainer}>
<Button
title={isPlaying ? "Pause" : "Play"}
onPress={() => {
if (isPlaying) {
player.pause();
} else {
player.play();
}
}}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
contentContainer: {
flex: 1,
padding: 10,
alignItems: "center",
justifyContent: "center",
paddingHorizontal: 50,
},
video: {
width: 350,
height: 275,
},
controlsContainer: {
padding: 10,
},
});
export default VideoScreen;
Picture-in-Picture (PiP) モード
Picture-in-Pictureモードは、動画を小さなウィンドウに縮小して、他のアプリやコンテンツを見ながら動画を視聴することを可能にする機能です。
ネイティブの機能であるためシミュレータでは使用できませんでしたが、実機で試したところ写真のように Picture-in-Picture モードで再生することができました。
Now Playing Notification への表示
コントロールセンターの表示に関しては以下のようにメタデータを指定することで実装できます。
const videoSource: VideoSource = {
uri: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
metadata: {
title: "Big Buck Bunny",
artwork:
"https://i.vimeocdn.com/video/20963649-f02817456fc48e7c317ef4c07ba259cd4b40a3649bd8eb50a4418b59ec3f5af5-d?mw=3000&mh=1245&q=70",
},
};
また、プレイヤーの showNowPlayingNotification
プロパティを true
にする必要があります。(これはデフォルトで true
にして欲しいような気もする。)
const player = useVideoPlayer(videoSource, (player) => {
+ player.showNowPlayingNotification = true;
player.loop = true;
player.play();
});
expo-audio
beta 版リリース
expo-audio
は、モバイルデバイス上で音声の録音、再生、音量やピッチの調整などを行うことができるライブラリです。
$ npx expo install expo-audio
{
"expo": {
"plugins": [
[
"expo-audio",
{
"microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone."
}
]
]
}
}
useAudioPlayer()
というフックが使用できます。
import { View, StyleSheet, Button } from "react-native";
import { useAudioPlayer } from "expo-audio";
const App = () => {
const player = useAudioPlayer({
uri: "./assets/songs/maou_inst_14_shining_star.mp3",
});
return (
<View style={styles.container}>
<Button
title="Play Sound"
onPress={() => {
player.play();
}}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
backgroundColor: "#ecf0f1",
padding: 10,
},
});
export default App;
しかし、残念ながら手元のデバイスで音楽の再生を行うことはできませんでした。何か実装に問題があるのか、バグなのかは分かりませんが、引き続き調査を続けてみようと思います。
何かわかった方はコメントで教えていただきたいです。
expo-file-system/next
beta 版リリース
expo-file-system/next
は既存の expo-file-system
ライブラリを使いやすく再構築したものであり、Expo 上でのファイル操作を簡単に行うことのできるライブラリです。
$ npx expo install expo-file-system
import { File, Paths } from "expo-file-system/next";
import { View } from "react-native";
const Home = () => {
try {
const file = new File(Paths.cache, "example.txt");
if (!file.exists) file.create();
file.write(new Date().toISOString());
console.log(file.text());
} catch (error) {
console.error(error);
}
return <View></View>;
};
export default Home;
カメラとデータベース関連ライブラリの改善
SDK 52では、expo-camera
および expo-sqlite
ライブラリが改善され、パフォーマンスや機能が向上しました。
expo-camera
SDK 51 でリリースされた expo-camera/next
が expo-camera
としてリリースされました。リアルタイムの画像処理や高解像度の写真撮影がより効率的に行えるようになります。
expo-sqlite
SQLite のデータベースを shared container に保存できるようになりました。これによって、ウィジェットなどからのデータアクセスが可能になります。
iOS 18に対応
iOS 18で新たに利用可能になったダークアイコンおよび色合い調アイコンがExpoでも使用可能になりました。
{
"expo": {
"ios": {
- "icon": "./assets/images/icon.png",
+ "icon": {
+ "light": "./assets/images/icon.png",
+ "dark": "./assets/images/icon-dark.png",
+ "tinted": "./assets/images/icon-tinted.png"
+ }
}
}
}
DOM Components
"use dom"
ディレクティブをファイルの先頭に記述することによって、DOM コンポーネントを使用できるようになりました。
"use dom";
const Home = () => {
return (
<div>
<p>Hello, world!</p>
</div>
);
};
export default Home;
DOMコンポーネントを使用することで、ウェブからネイティブへの段階的な移行が非常に簡単になります。
おわりに
以上が、Expo SDK 52 のリリースで加わった変更のうち、自分が特に注目した機能となります。
これ以外にもさまざまな機能が使えるようになっているため、気になる方是非リリースノートをご確認ください。
最後までお読みいただきありがとうございました。