MacBook に接続した iPhone 実機で Flutter アプリをデバッグする
こんにちは、CX事業本部 Delivery部の若槻です。
iOS アプリケーションを開発する際には、アプリをシミュレートされたデバイス上でデバッグできる Simulator を使うと便利です。
Simulator は私も普段の iOS アプリ開発でよく使っており、また Tips を紹介するブログもいくつか投稿しています。
- FlutterアプリをGoogle Chrome/iOS Simulatorでデバッグする | DevelopersIO
- Flutterアプリを複数台のiOS Simulatorデバイスで同時に実行してみた | DevelopersIO
- flutter_nearby_connectionsによるP2P通信をiOS Simulatorのデバイス間で試してみた | DevelopersIO
しかし、アプリケーションが端末のカメラや通信機能などハードウェア機能を利用する場合は、Simulator ではなく実機(リアルデバイス)でのデバッグが必要となります。
今回は、MacBook に接続した iPhone 実機で Flutter アプリをデバッグしてみました。
やってみた
環境
Flutter、Dart
$ flutter --version Flutter 3.7.7 • channel stable • https://github.com/flutter/flutter.git Framework • revision 2ad6cd72c0 (6 months ago) • 2023-03-08 09:41:59 -0800 Engine • revision 1837b5be5f Tools • Dart 2.19.4 • DevTools 2.20.1
Xcode
$ /usr/bin/xcodebuild -version Xcode 14.3.1 Build version 14E300c
iPhone
- iOS 16.6.1
- iPhone 12 Pro
Flutter プロジェクト作成
flutter create my_flutter_app code my_flutter_app
Simulator で動作することを確認
Simulator で起動したデバイス上で Flutter アプリが動作することを確認します。
$ flutter devices 3 connected devices: iPhone SE (3rd generation) (mobile) • 8D9D7053-600D-4E16-ABB1-7317788FFCBE • ios • com.apple.CoreSimulator.SimRuntime.iOS-16-4 (simulator) macOS (desktop) • macos • darwin-arm64 • macOS 13.5.2 22G91 darwin-arm64 Chrome (web) • chrome • web-javascript • Google Chrome 117.0.5938.62 $ flutter run -d 8D9D7053-600D-4E16-ABB1-7317788FFCBEs
アプリが Simulator 上で動作することが確認できました。
デバイスを接続
iPhone デバイスと MacBook をケーブルで接続します。
Xcode で Window > Devices and Simulators を開きます。すると、接続したデバイスが表示されています。
flutter devices
コマンドでも接続されたデバイスを確認することができます。
$ flutter devices 3 connected devices: iPhone (4) (mobile) • 00008101-001661062280001E • ios • iOS 16.6.1 20G81 macOS (desktop) • macos • darwin-arm64 • macOS 13.5.2 22G91 darwin-arm64 Chrome (web) • chrome • web-javascript • Google Chrome 117.0.5938.62
iPhone 実機でアプリを実行(失敗)
しかし flutter run
コマンドでデバイスを指定して実行しようとすると、エラーが発生します。
$ flutter run -d 00008101-001661062280001E Launching lib/main.dart on iPhone (4) in debug mode... Automatically signing iOS for device deployment using specified development team in Xcode project: XXXXXXXX Running Xcode build... Xcode build done. 6.2s Failed to build iOS app Could not build the precompiled application for the device. Error (Xcode): No profiles for 'com.example.myFlutterApp' were found: Xcode couldn't find any iOS App Development provisioning profiles matching 'com.example.myFlutterApp'. Automatic signing is disabled and unable to generate a profile. To enable automatic signing, pass -allowProvisioningUpdates to xcodebuild. /Users/wakatsuki.ryuta/projects/cm-rwakatsuki/my_flutter_app/ios/Runner.xcodeproj It appears that there was a problem signing your application prior to installation on the device. Verify that the Bundle Identifier in your project is your signing id in Xcode open ios/Runner.xcworkspace Also try selecting 'Product > Build' to fix the problem. Error launching application on iPhone (4).
Xcode がアプリの署名に必要なプロビジョニングプロファイルを見つけられなかったためのようです。
プロビジョニングプロファイル(Provisioning profile)は、アプリケーション(App)が特定のアプリサービスを使用することを承認し、App を開発、アップロード、または配布する既知の開発者であることを保証するファイルのことです。
ios/Runner.xcworkspace
を Xcode で開くと、Runner の Targets で自動署名のチェックが入っています。
自動署名のチェックを外して無効にすると、プロビジョニングプロファイルの設定を求められるようになります。
プロビジョニングプロファイルをアプリケーションに設定する
前項で設定を求められたプロビジョニングプロファイルを作成し、アプリケーションに設定してみます。
証明書の作成、登録
まず Xcode で Settings > Accounts > Manage Certificates より証明書(development certificates)を作成します。(ただし、development certificates はすでに作成されているので、これは不要だったかも知れません。また App Store や TestFlight で配信する場合は distribution certificates 作成します)
作成されました。
作成された証明書は、Xcode でログインしている Apple Developer Web サイトの Certificates に自動的に登録されます。
App ID の登録
Apple Developer Web サイトにアクセスして App ID を登録します。プロビジョニングプロファイルでは App ID を使用して対象とする App を指定します。
Register a new identifierで、App IDs
を指定して、Continue をクリック。
Select a type で App
を選択して、Continue をクリック。
Register your App ID で各項目を指定します。Bundle ID
はリバースドメインなどを利用したユニークな値を指定します。(後ほど Xcode 上でもアプリに指定します。)今回はハードウェアの機能は使わないので Capability はここでは一旦指定はしません。Continue をクリック。
Confirm your App ID で指定した内容を確認して、Register をクリック。
この時、「An attribute in the provided entity has invalid value The attribute 'name' is invalid: ''」というエラーが出る場合は、Description で使用できない文字が含まれている可能性があります。私の場合は_
を含めるとエラーになったので-
に置き換えました。
情報に問題なければ App ID が登録されます。
プロビジョニングプロファイルの登録
Register a New Provisioning Profile で iOS App Development
を選択して、Continue をクリック。
Select an App ID で先ほど登録した App ID を選択して、Continue をクリック。
Select certificates で先ほど作成した証明書を選択して、Continue をクリック。
Select devices でデバッグに利用したいデバイスを選択して、Continue をクリック。(私の場合は登録済みでした。まだの場合は登録してください)
Name your profile でプロビジョニングプロファイルの名前を指定して、Generate をクリック。
登録できました。(このプロビジョニングプロファイルは後ほど Xcode から直接参照するので、ダウンロードする必要はありません)
Xcode でプロビジョニングプロファイルを設定する
Xcode に戻り、Bundle Identifier で先ほど App ID 登録時に指定した Bundle ID を指定します。Provisioning Profile で Download profile を選択して、先ほど登録したプロビジョニングプロファイルを選択します。
プロビジョニングプロファイル選択時にすべてのチェックが正常であることを確認します。(不正のチェックがある場合はプロビジョニングプロファイルの修正が必要です)
設定できました。
iPhone 実機でアプリを実行(成功)
再度 flutter run
コマンドで実機のデバイスを指定して実行してみます。
すると今度はアプリが実機上にインストールされました。
しかしコマンド実行はエラーとなりました。
$ flutter run -d 00008101-001661062280001E Launching lib/main.dart on iPhone (4) in debug mode... Automatically signing iOS for device deployment using specified development team in Xcode project: XXXXXXXX Running Xcode build... Xcode build done. 86.9s Installing and launching... (lldb) 2023-09-16 20:09:30.233918+0900 Runner[3902:1970164] Warning: Unable to create restoration in progress marker file fopen failed for data file: errno = 2 (No such file or directory) Errors found! Invalidating cache... fopen failed for data file: errno = 2 (No such file or directory) Errors found! Invalidating cache... Installing and launching... 16.4s Connecting to the VM Service is taking longer than expected... Still attempting to connect to the VM Service... If you do NOT see the Flutter application running, it might have crashed. The device logs (e.g. from adb or XCode) might have more details. If you do see the Flutter application running on the device, try re-running with --host-vmservice-port to use a specific port known to be available. Exception attempting to connect to the VM Service: SocketException: Connection refused (OS Error: Connection refused, errno = 61), address = 127.0.0.1, port = 56271 This was attempt #50. Will retry in 0:00:01.600000.
端末を見るとローカルネットワークの接続を求められているようです。許可します。
再度 flutter run
コマンドを実行すると、今度は成功しました。
$ flutter run -d 00008101-001661062280001E Downloading usbmuxd... 526ms Launching lib/main.dart on iPhone (4) in debug mode... Automatically signing iOS for device deployment using specified development team in Xcode project: XXXXXXXX Running Xcode build... Xcode build done. 12.4s Installing and launching... 13.0s Syncing files to device iPhone (4)... 73ms Flutter run key commands. r Hot reload. 🔥🔥🔥 R Hot restart. h List all available interactive commands. d Detach (terminate "flutter run" but leave application running). c Clear the screen q Quit (terminate the application on the device). 💪 Running with sound null safety 💪 An Observatory debugger and profiler on iPhone (4) is available at: http://127.0.0.1:56441/rPENpv38aFo=/ The Flutter DevTools debugger and profiler on iPhone (4) is available at: http://127.0.0.1:9101?uri=http://127.0.0.1:56441/rPENpv38aFo=/
実機上でアプリを動作させられるようになりました。
ソースコードを変更してコマンド実行を Reload すると、実機側のアプリでも変更が反映されます。デバッグも容易にできるようになっているようです。
また、Devices and Simulators にも実機に追加されたアプリを確認することができます。
おわりに
MacBook に接続した iPhone 実機で Flutter アプリをデバッグする方法を紹介しました。試したのは Flutter アプリですが、フレームワーク関係なく参考になる内容だと思います。
結構手順が多く、「実機でデバッグをしたいだけなのに」と思わなくもないですが、配信する際にも必要な手順なので、その予行演習としては良いのかも知れません。
参考
以上