<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>React-Native on 怠惰技術ブログ</title>
    <link>/tags/react-native/</link>
    <description>Recent content in React-Native on 怠惰技術ブログ</description>
    <generator>Hugo -- 0.147.7</generator>
    <language>ja</language>
    <lastBuildDate>Mon, 23 Feb 2026 21:30:00 +0900</lastBuildDate>
    <atom:link href="/tags/react-native/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>WSL2でExpo &#43; E2Eテスト（MaestroとDetox）を試みて完全に詰んだ話</title>
      <link>/posts/2026-02-23-fxxk-mobile-e2e-test/</link>
      <pubDate>Mon, 23 Feb 2026 21:30:00 +0900</pubDate>
      <guid>/posts/2026-02-23-fxxk-mobile-e2e-test/</guid>
      <description>&lt;h2 id=&#34;tldr&#34;&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;WSL2環境でExpo（React Native）のE2EテストをMaestroとDetoxで試みたが、どちらもWSL2とWindowsエミュレータの構造的な問題で動かなかった。&lt;/p&gt;
&lt;p&gt;かなり過言ではあるが、あえて感情的になるならば、Mobile開発においてMac以外は人権がない。というかあまりにもMac環境以外がだるすぎる。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;環境&#34;&gt;環境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;OS: Windows + WSL2（Ubuntu）&lt;/li&gt;
&lt;li&gt;Expo SDK 54 / React Native 0.81.5&lt;/li&gt;
&lt;li&gt;New Architecture有効&lt;/li&gt;
&lt;li&gt;Androidエミュレータ: Windows側で動作（Medium Phone API 36）&lt;/li&gt;
&lt;li&gt;ADB: Windows側のものをWSL2から参照&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;maestroを試みる&#34;&gt;Maestroを試みる&lt;/h2&gt;
&lt;h3 id=&#34;インストール&#34;&gt;インストール&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl -Ls &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://get.maestro.mobile.dev&amp;#34;&lt;/span&gt; | bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export PATH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$HOME&lt;span style=&#34;color:#e6db74&#34;&gt;/.maestro/bin:&lt;/span&gt;$PATH&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ここで最初の罠。&lt;code&gt;maestro --help&lt;/code&gt;を叩くとAI系の全く別のCLIツールが応答した。同名の別アプリが先にPATHに入っていたため。&lt;code&gt;$HOME/.maestro/bin&lt;/code&gt;をPATHの&lt;strong&gt;先頭&lt;/strong&gt;に置くことで解決。&lt;/p&gt;
&lt;h3 id=&#34;フローの準備&#34;&gt;フローの準備&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# .maestro/add_and_complete_task.yml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;appId&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;com.example.myapp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- &lt;span style=&#34;color:#ae81ff&#34;&gt;launchApp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- &lt;span style=&#34;color:#f92672&#34;&gt;tapOn&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;text&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;追加&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- &lt;span style=&#34;color:#f92672&#34;&gt;inputText&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;テストタスク&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- &lt;span style=&#34;color:#f92672&#34;&gt;tapOn&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;text&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;追加する&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- &lt;span style=&#34;color:#f92672&#34;&gt;assertVisible&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;text&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;NOW&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;実行して即死&#34;&gt;実行して即死&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;You have 0 devices connected, which is not enough to run 1 shards.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;エミュレータはWindows側で動いており、&lt;code&gt;adb devices&lt;/code&gt;には&lt;code&gt;emulator-5554&lt;/code&gt;が見えている。しかしMaestroはWSL2側でデバイスを探すため認識できない。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--udid=emulator-5554&lt;/code&gt;を指定しても：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Device emulator-5554 was requested, but it is not connected.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;maestro start-device --platform=android&lt;/code&gt;を試みると：&lt;/p&gt;</description>
    </item>
    <item>
      <title>react-native-pdf 6.7.7のiOS表示問題をpatch-packageで解決する</title>
      <link>/posts/2026-02-17-expo-react-native-pdf-patch/</link>
      <pubDate>Tue, 17 Feb 2026 14:30:00 +0900</pubDate>
      <guid>/posts/2026-02-17-expo-react-native-pdf-patch/</guid>
      <description>&lt;h2 id=&#34;はじめに&#34;&gt;はじめに&lt;/h2&gt;
&lt;p&gt;業務で&lt;code&gt;react-native-pdf&lt;/code&gt;を使用した際、AndroidではPDFが正常に表示されるのにiOSでは表示されないという問題に遭遇しました。&lt;/p&gt;
&lt;p&gt;この記事では、GitHubのissueで共有された解決策である&lt;code&gt;patch-package&lt;/code&gt;を使ったパッチ適用方法について解説します。&lt;/p&gt;
&lt;h2 id=&#34;問題の概要&#34;&gt;問題の概要&lt;/h2&gt;
&lt;h3 id=&#34;環境&#34;&gt;環境&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;react-native-pdf&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^6.7.7&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;react-native&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0.80.1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;react-native-blob-util&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^0.22.2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;症状&#34;&gt;症状&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Android: PDF表示が正常に動作&lt;/li&gt;
&lt;li&gt;iOS: PDFが表示されない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この問題は、React Native 0.80以降で&lt;code&gt;react-native-pdf&lt;/code&gt;を使用した際に発生することが確認されています。&lt;/p&gt;
&lt;p&gt;参考: &lt;a href=&#34;https://github.com/wonday/react-native-pdf/issues/966&#34;&gt;pdf is not displayed，Android is working fine, but there are problems with iOS #966&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;解決策-patch-packageを使う&#34;&gt;解決策: patch-packageを使う&lt;/h2&gt;
&lt;p&gt;GitHubのissueで&lt;a href=&#34;https://github.com/wonday/react-native-pdf/issues/966&#34;&gt;@anhnguyen123&lt;/a&gt;さんが共有してくれたパッチファイルを適用することで、この問題を解決できます。&lt;/p&gt;
&lt;h3 id=&#34;1-patch-packageのインストール&#34;&gt;1. patch-packageのインストール&lt;/h3&gt;
&lt;p&gt;まず、&lt;code&gt;patch-package&lt;/code&gt;と&lt;code&gt;postinstall-postinstall&lt;/code&gt;をdevDependenciesとしてインストールします。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# npmの場合&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;npm install --save-dev patch-package
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# yarnの場合&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;yarn add --dev patch-package postinstall-postinstall
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;参考: &lt;a href=&#34;https://www.npmjs.com/package/patch-package&#34;&gt;patch-package - npm&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;2-packagejsonにpostinstallスクリプトを追加&#34;&gt;2. package.jsonにpostinstallスクリプトを追加&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt;の&lt;code&gt;scripts&lt;/code&gt;セクションに、&lt;code&gt;postinstall&lt;/code&gt;スクリプトを追加します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;postinstall&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;patch-package&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このスクリプトにより、&lt;code&gt;npm install&lt;/code&gt;または&lt;code&gt;yarn install&lt;/code&gt;を実行するたびに、自動的にパッチが適用されます。&lt;/p&gt;
&lt;h3 id=&#34;3-パッチファイルの配置&#34;&gt;3. パッチファイルの配置&lt;/h3&gt;
&lt;p&gt;GitHubのissueからパッチファイル&lt;code&gt;react-native-pdf+6.7.7.patch&lt;/code&gt;をダウンロードし、プロジェクトルートに&lt;code&gt;patches&lt;/code&gt;ディレクトリを作成してそこに配置します。&lt;/p&gt;</description>
    </item>
    <item>
      <title>AsyncStorageって裏側何やってんの？ - 2.0と3.0の実装の違いを調べてみた</title>
      <link>/posts/2026-02-08-async-storage/</link>
      <pubDate>Sun, 08 Feb 2026 17:50:00 +0900</pubDate>
      <guid>/posts/2026-02-08-async-storage/</guid>
      <description>&lt;p&gt;私は普段React NativeでExpo触ってるので、AsyncStorageはよく使うんだけど、「そういえばAsyncStorageって裏側何やってんだろう？」って疑問が湧いてきたので調べてみることにした。&lt;/p&gt;
&lt;h2 id=&#34;asyncstorageの裏側&#34;&gt;AsyncStorageの裏側&lt;/h2&gt;
&lt;p&gt;AsyncStorageのバージョンによって実装が少し違う。&lt;/p&gt;
&lt;h3 id=&#34;asyncstorage-20の実装&#34;&gt;AsyncStorage 2.0の実装&lt;/h3&gt;
&lt;p&gt;iOS/Androidのみ調査。&lt;/p&gt;
&lt;p&gt;公式ドキュメント: &lt;a href=&#34;https://react-native-async-storage.github.io/2.0/advanced/Where-data-stored/&#34;&gt;Where your data is stored - Async Storage&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;ios-20&#34;&gt;iOS (2.0)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;manifest.json&lt;/code&gt;ファイルに保存される&lt;/li&gt;
&lt;li&gt;JSONファイル形式&lt;/li&gt;
&lt;li&gt;パス: &lt;code&gt;Documents/RCTAsyncLocalStorage_V1/manifest.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;詳細: 1024文字以下のデータは&lt;code&gt;manifest.json&lt;/code&gt;に、それより大きいデータは個別ファイル(MD5ハッシュ名)に保存される&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;android-20&#34;&gt;Android (2.0)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;SQLiteデータベースに保存される&lt;/li&gt;
&lt;li&gt;データベース名: &lt;code&gt;RKStorage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;パス: &lt;code&gt;/data/data/{package_name}/databases/RKStorage&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;asyncstorage-30-nextの実装&#34;&gt;AsyncStorage 3.0 (next)の実装&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;公式ドキュメント&lt;/strong&gt;: &lt;a href=&#34;https://react-native-async-storage.github.io/3.0-next/&#34;&gt;https://react-native-async-storage.github.io/3.0-next/&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&#34;対応プラットフォーム&#34;&gt;対応プラットフォーム&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Android (SQLite)&lt;/li&gt;
&lt;li&gt;iOS (SQLite) ✨&lt;/li&gt;
&lt;li&gt;macOS (SQLite)&lt;/li&gt;
&lt;li&gt;visionOS (legacy fallback, single database only)&lt;/li&gt;
&lt;li&gt;Web (IndexedDB backend)&lt;/li&gt;
&lt;li&gt;Windows (legacy fallback, single database only)&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;ios-30&#34;&gt;iOS (3.0)&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;SQLiteデータベースに変更された&lt;/li&gt;
&lt;li&gt;Androidと同じ実装に統一&lt;/li&gt;
&lt;li&gt;パフォーマンスと安定性が向上&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;android-30&#34;&gt;Android (3.0)&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;引き続きSQLite&lt;/li&gt;
&lt;li&gt;より洗練された実装&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3.0からはiOSもAndroidも両方SQLiteになって、実装が統一されるそうだ。&lt;/p&gt;
&lt;h5 id=&#34;互換性&#34;&gt;互換性&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;React Native 0.76以降が必要(iOS/Android)&lt;/li&gt;
&lt;li&gt;Kotlin 2.1.0&lt;/li&gt;
&lt;li&gt;iOS minimum target: 13&lt;/li&gt;
&lt;li&gt;Android minimum SDK: 24&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;なぜiosでmanifestjsonからsqliteに変更したのか&#34;&gt;なぜiOSでmanifest.jsonからSQLiteに変更したのか&lt;/h2&gt;
&lt;p&gt;あくまでも推測ではあるがやってみた。&lt;/p&gt;</description>
    </item>
    <item>
      <title>React NativeのTodoアプリで実装する相対時間ベースのプリセット機能</title>
      <link>/posts/2026-02-08-expo-presets/</link>
      <pubDate>Sun, 08 Feb 2026 10:50:00 +0900</pubDate>
      <guid>/posts/2026-02-08-expo-presets/</guid>
      <description>絶対時間ではなく相対時間（dueHoursOffset）で期限を管理することで、繰り返しタスクを効率化するプリセット機能の実装方法を解説</description>
    </item>
    <item>
      <title>三竦（さんすくみ）要件定義書</title>
      <link>/posts/2026-02-06-sansuku/</link>
      <pubDate>Fri, 06 Feb 2026 07:30:00 +0900</pubDate>
      <guid>/posts/2026-02-06-sansuku/</guid>
      <description>犬猿雉の三すくみを使った追跡型対戦ゲームの要件定義。リアルタイムアクション &#43; 戦略性を両立したシンプルなモバイルゲーム</description>
    </item>
    <item>
      <title>Gemini CLIでExpo Todoアプリを爆速開発した話</title>
      <link>/posts/2026-01-31-gemini-cli-expo/</link>
      <pubDate>Sat, 31 Jan 2026 19:00:00 +0900</pubDate>
      <guid>/posts/2026-01-31-gemini-cli-expo/</guid>
      <description>Gemini CLI を使って Expo の Todo アプリを開発した体験記。GEMINI.md でルールを管理し、段階的に機能を追加していく方法を紹介します。</description>
    </item>
    <item>
      <title>React NativeでTextInputの日本語入力が壊れる問題と解決方法</title>
      <link>/posts/2026-01-31-react-native-input-text-ime-bug/</link>
      <pubDate>Sat, 31 Jan 2026 18:30:00 +0900</pubDate>
      <guid>/posts/2026-01-31-react-native-input-text-ime-bug/</guid>
      <description>React NativeのTextInputで日本語入力時に変換候補が消える問題の原因と、autoComplete/autoCorrectによる解決方法を解説します。</description>
    </item>
  </channel>
</rss>
