WindowsでiOS向けFlutter開発環境を用意する
はじめに
Xamarinのサポート終了が発表されました。私の周辺では最近あまり話を聞かなくなりましたが、過去にWindowsマシンでiOS向けアプリケーションが開発できると聞いてワクワクした記憶があります。
Xamarinのサポートが終了する今、「Windows(or Linux)マシンしか持っていないけどiOSの開発がしたい」といった要望があった時のことを考え、Macを所持していなくてもFlutterを用いたiOS向けのアプリケーション開発ができる環境を検討しました。
ザックリ概要
- AWS EC2のM1 Macインスタンスを利用するためサービスクォータを引き上げます。
- AWS CDKを用いてAWS EC2のM1 Macインスタンスを立ち上げます。
- 立ち上げたMacインスタンスにXCodeとFlutterをインストールします。
- WindowsマシンからVSCodeを利用してiOS向けアプリを開発してみます。
注意事項及び前提条件
- us-east-1が使えるAWSアカウントを持っていること
- 数日の余裕があること
- 手順中に出てくるMac向け
Dedicated Hosts
は24時間解放できません - 最低でも15.6$はかかります
- VNCクライアントにUltraVNCを利用します
- VSCodeがインストールされていること
なお、東京リージョンでサポートされていないmac2を選んだ理由はただ単にmac1より安いからです。
手順
色々と注意事項があることを理解した上でやっていきましょう。
サービスクォータを引き上げる
まず、mac2を利用するにはDedicated Hosts
が必要です。
しかし、アカウントの初期状態ではmac2用のDedicated Hosts
の上限は0
に設定されています。
そのため、まずはService QuotasからRunning Dedicated mac2 Hosts
を1
にしてもらいます。
インスタンスを立ち上げる
サービスクォータの増枠要求が通ったらDedicated Hosts
とインスタンスを立ち上げます。
今回は簡単に作成できるようにAWS CDKのコードを用意しておきました。次のスタックを作成しデプロイします。何度か試す際にキーペアを変更したくなかったためkeyName
プロパティを固定化しています。CDK内で作成するなど適宜読み替えてください。
import { App, Stack, StackProps, Tags } from 'aws-cdk-lib';
import {
CfnHost,
Instance,
InstanceType,
OperatingSystemType,
Port,
SubnetType,
UserData,
Vpc,
} from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';
export class M1MacStack extends Stack {
get availabilityZones(): string[] {
return ['us-east-1b', 'us-east-1d'];
}
constructor(scope: Construct, id: string, props: StackProps = {}) {
super(scope, id, props);
const vpc = new Vpc(this, 'Vpc', {
natGateways: 0,
});
const m1MacHost = new CfnHost(this, 'M1MacHost', {
availabilityZone: 'us-east-1d',
instanceType: 'mac2.metal',
});
Tags.of(m1MacHost).add('Name', 'M1 Mac host');
const macInstance = new Instance(this, 'MacInstance', {
vpc,
availabilityZone: 'us-east-1d',
instanceType: new InstanceType('mac2.metal'),
machineImage: {
getImage: (_scope) => ({
imageId: 'ami-01a9da8de3d589094',
osType: OperatingSystemType.UNKNOWN,
userData: UserData.custom(''),
}),
},
vpcSubnets: {
subnetType: SubnetType.PUBLIC,
},
keyName: '<既存のキーペア名>',
});
macInstance.instance.tenancy = 'host';
macInstance.instance.hostId = m1MacHost.attrHostId;
macInstance.connections.allowFromAnyIpv4(Port.tcp(22));
}
}
const env = {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: 'us-east-1', // process.env.CDK_DEFAULT_REGION,
};
const app = new App();
new M1MacStack(app, 'M1MacStack', { env });
app.synth();
ソースコード全体はこちら
デプロイ後、ステータスチェックがパスするまで10分程度かかりますので待ちましょう。
補足
AMIについて
今回AMIに固定値を利用しました。個人的にSSMパラメータで最新版のAMIを利用することが望ましいのですが、調査したところまだ公開されていないようです。
リージョンについて
冒頭でも記載した通り東京リージョンではまだ利用できないためus-east-1
を指定しています。
アベイラビリティゾーンについて
例えmac2がサポートされているus-east-1
であっても全てのアベイラビリティゾーンでmac2が利用できるわけではないようです。
us-east-1f
を指定した時はエラーとなってDedicated Hosts
が確保できませんでした。そのためus-east-1d
を指定しています。us-east-1b
はアベイラビリティゾーンが2つ以上になるように含めていますが含めなくても問題ありません。
SSH接続
sshコマンドで接続してもいいのですが、VSCodeの拡張機能でSSH接続する予定のため今回はSSHのコンフィグに記述します。
HostNameとIdentityFileは実際の値に置き換えてください。
Host M1Mac
HostName ec2-***-***-***-***.compute-1.amazonaws.com
IdentityFile ~/.ssh/インスタンスに設定したキー名.pem
User ec2-user
LocalForward 5901 localhost:5900
VSCodeのRemote-SSH拡張機能でSSH接続します。
XCode等をGUIでインストールするためにすぐVNCを利用したいところですが、このままではVNC接続できないため先にリモートデスクトップを許可する設定をしていきます。
ec2-user
にパスワードを設定します。
sudo dscl . -passwd /Users/ec2-user 任意のパスワード
画面共有をONにします。
sudo defaults write /var/db/launchd.db/com.apple.launchd/overrides.plist com.apple.screensharing -dict Disabled -bool false
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.screensharing.plist
手元で利用していたUltraVNCは新しい認証方式に対応していないためレガシーパスワードモードを有効にします。
sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -clientopts -setvnclegacy -vnclegacy yes
VNCのパスワードを設定します。
sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -clientopts -setvncpw -vncpw 任意のパスワード
VNC接続
UltraVNCのVNC Viewerで接続します。
先ほど設定したパスワードを入力して接続します。
接続に成功しました。
XCodeインストール
App StoreでXCodeを検索しインストールします。
Intelベースのアプリケーションの実行にはRosetta
が必要らしく、このタイミングでインストールを促されます。インストールしましょう。
Welcome to XCodeが表示されればインストール完了です。
Flutterインストール
XCodeがインストールできたらVNC接続での操作は終了です。
ここからは公式の手順に沿ってSSH接続しているVSCodeのターミナルから操作していきます。
Flutter SDKをダウンロードします。
curl -Ol https://storage.googleapis.com/flutter_infra_release/releases/stable/macos/flutter_macos_arm64_3.0.5-stable.zip
ダウンロードしたFlutter SDKを展開し、VSCodeのFlutter拡張機能がインストール先を探せるように名前をflutter-sdk
に変更します。
unzip ./flutter_macos_arm64_3.0.5-stable.zip
mv flutter flutter-dk
VSCodeのFlutter拡張機能をSSH接続先にインストールします。
Flutterプロジェクト作成
インストールできたらCtrl + Shift + P
でコマンドパレットを開きFlutter: New Project
を実行します。
どのテンプレートを利用するか聞かれます。今回はApplication
にしました。
任意のフォルダを選択してテンプレートを展開します。
Project Name
を決定します。
テンプレートの展開されたフォルダが自動で開きます。
Flutterアプリの開発
今回はiOSのシミュレーターを利用します。次のコマンドでシミュレーターを見つけます。
open -a Simulator
VNC側の画面でシミュレーターが起動します。VSCodeの画面も右下にiPhone SE (3rd generation) (ios simulator)
との表示が増えました。
デバッグ実行してみます。VSCode側でF5
キーを押すことでアプリケーションのデバッグができます。
ポイント
VNC上でエディタを操作せずVSCodeのRemote-SSH
を利用して開発するのが今回のポイントとなります。VNC上ではなくローカルのVSCodeを操作していることによって次のメリットがあります。
- 基本的なエディタの操作がモッサリしません。
- 手元のVSCodeを利用できるため再度設定等をする必要がありません。
次のようにサジェストや情報の表示等はローカルで開発しているのと速度的に遜色ありません。これは嬉しいです。
さいごに
us-east-1
で利用してみましたが思っていたよりもスムーズに動いたのが予想外でした。東京リージョンに来るともっとスムーズになると予想されます。
ただし、コスト的な観点でみるとDedicated Hosts
の24時間制約がある都合、1時間単位レベルのスポットな利用方法が取れません。そのため、1か月を30日としてフルに利用したとすると0.65USD * 24h * 30d = 468$
となり、1$=130円換算で計算すると日本円で60,840円
になります。これは高い・・・。
(本格的に利用する場合は) 素直にMac買えよ
フラグも回収したところで今回の記事はここまでにします。24時間後にCDKのスタックを削除することをお忘れなく。
Discussion