ポエム - .NET MAUI はモダンな "Write Once, Run Anywhere" を確立してほしいという希望

こんにちは、エンジニアの庭山(@rkoubou_jp)です。

本記事は Synamon Advent Calendar 2022 19日目の記事になります。

去年の Synamon Advent Calendar 2021 で MAUI の記事を書いたのですが、2022年5月に MAUI が GA(正式版) リリースとなり、先日リリースされた .NET 7 にも対応となったので続編的な記事を書こうと思います。

技術的な記事というよりかは、ほぼ個人的な主観なのでご了承ください。

synamon.hatenablog.com

目次

TL;DR

  • Preview版ではビルドするのも一苦労だったけど、難なくビルドできた
  • 色々設計思想などがあるのだろうが目指しているのは恐らく "Write (Code per Platform & Construct SDKs) Once, Run Anywhere" (*この記事での造語)っぽい
    • 個人的に Java Swing フレームワークは "Write Once, Run Anywhere" を追い求め、体現していた良い設計思想だったと思う
      • → 自分は設計思想やGUIプログラミング全般における考え方をSwingで学んだつもり
    • マルチプラットフォーム対応のフレームワーク開発、というのは大変(過去の経験)

MAUI 正式版がリリースされていた!

前回記事を書いた時点ではPreview版で、想定以上に四苦八苦してしまいました。その後 2022年5月に MAUI が GA(正式版) リリースとなりました。

github.com

Preview版ではプロジェクト作成時に組み込まれているサンプルのビルドするだけでも一苦労でした。

この記事を書いた時の環境

Windows PC と MacBook Pro 2021 (M1) で環境を構築を行いました。

  • Windows 10 Pro (x64)

    • .NET 7.0
    • Visual Studio 2022
    • Android SDK
      • ANdroid Simulator
  • macOS Montery

    • .NET 7.0
    • Visual Studio for Mac 17.4.1
    • Xcode 14.1
      • iOS Simulator
    • Android SDK
      • Android Simulator

アプリのプロジェクトは Windows の Visual Studio 上で新規プロジェクト(.NET MAUI アプリ)を作成した直後の状態のファイルです。

前回からの再挑戦 - アプリのビルドが普通にできた!

「そりゃそうだろう」と思われるでしょうが、Preview版で手こずっていた過去があるのでこれだけでも嬉しかったですね。

デバイスを指定して実行ボタンをクリックするだけで

Android シミュレータ、あっさり起動しました。

Windows マシンから Mac にリモート接続して iOS ビルド(シミュレータ)

Microsoftのサイトに手順が載っていたのでその通りにやって、トラブルなくビルド・実行ができました。

learn.microsoft.com

Mac, Windows 版ビルド

それぞれのOS上のVisual Studio でビルド、実行ができました。

Windows

Mac

MAUI は "Write Once, Run Anywhere" に「近い路線」を目指している(と勝手に解釈している)

"Write Once, Run Anywhere" というワードは元々 Java が登場した頃のJava開発者のスローガンでした。

ja.wikipedia.org

Write once, run anywhere(WORA、「一度〔プログラムを〕書けば、どこでも実行できる」[要出典])または Write once, run everywhere (WORE) とは、Javaのプログラムがオペレーティングシステム (OS) などのプラットフォームに依存しないという意味の、サン・マイクロシステムズのJavaのスローガンである。

先発の Java Runtime でも完全に達成したわけではないですが、Swingフレームワーク(GUI)はかなり良い線を行っていたと思っています。 個人的に Swing フレームワークを初めて触ったマルチプラットフォーム対応のGUIプログラミング環境だったこともあり、思い入れが強く、一部MAUIとの比較対象にしています。

MAUIは "Write Once, Run Anywhere" そのものを目指しているわけではないけど、なるべくそれに近い設計思想なのだろうと感じています。

"Write (Code per Platform & Construct SDKs) Once, Run Anywhere"

改めて短時間ながら MAUI を触ってみた感想は

"Write (Code per Platform & Construct SDKs) Once, Run Anywhere" (*この記事内の造語です)

かな、という感触です。 比喩ではないです。極力プラットフォームの事情を剥き出しにしないよう Visual Studio 側でかなりプラットフォーム固有の部分をフォローしてるんだろうなぁと感じています。

Code per Platform

Microsoftのドキュメントでは #if#endif などで条件分岐でプラットフォーム固有のコードや クロスプラットフォーム API 作成のアプローチを示しています。

learn.microsoft.com

MAUIではネイティブの機能にアクセスも可能にするため、標準のAPI仕様では抽象化をほどほどにしてアプリケーション開発側で 実現したいことベースに抽象化をどうするかを委ねている のだろうな、と感じています。 現状の対応プラットフォームがPCのみではなくモバイルOSやWebなど幅が広いので MAUI のAPI仕様でカバーしようとするとどんどんMAUI本体が肥大化するのでそこは抱え込まないようにしたんだろうな、と思っています。絶妙なアーキテクチャのバランスだなー、と感心しています。

learn.microsoft.com

Java Swing では

比較対象の Java Swing の良かった点は、プラットフォーム固有の部分は抽象化し、標準のAPIを豊富に整備されていました。ランタイム実装側でJNIなどネイティブのAPIコールを駆使して踏ん張っていました。 アプリケーションのコードを書く側はプラットフォームが何であるかは意識する必要はありませんでした。そのかわり、APIやランタイム実装の仕様は最大公約数的な設計なので、OS固有の機能はあまり提供されていませんでした。(マルチプラットフォームの対応をするということの宿命ですね…)

Construct SDK(s)

MAUI の思想としては各プラットフォームのネイティブコード を出力する形をとっています。

今回の記事を書くにあたりMacではこのような構成を構築しました。(macOS, iOS, Androidビルドを想定)

  • macOS Montery
    • .NET 7.0
    • Visual Studio for Mac 17.4.1
    • Xcode 14.1
      • iOS Simulator
    • Android SDK
      • Android Simulator

.NET SDK に加えてビルド対象のプラットフォームのネイティブなSDKの構築も必要になります。

この考え方はある種の正解なんだろうなー、と思っています。 .NET Runtime (JITコンパイル)といった実装だとiOSではレギュレーション的に不可能であったり、PCほどスペックが高くないバッテリー駆動のモバイル端末ではより軽量に動かしたいという側面もあるのだろうと思います。

マルチプラットフォーム対応のフレームワーク開発、というのは大変

短時間ながらではありますが、MAUI は色々考えられているなー、と改めて思い知らされました。 とある環境向けでフルスクラッチ(提供されている標準APIのみ)でマルチプラットフォームのライブラリやフレームワークを作った経験があるので、何となくでもその大変さが伝わってくる気がしています。

おわりに

冒頭で書いた通り、ほぼ個人的なポエムでした。最後まで読んでいただきありがとうございます。 アドベントカレンダーで2年連続でMAUIを書いているので、1年後にまた記事を書くかもしれません。

趣味のコード書きなどGUI系はMAUIをメインにしていきたいのでスキマ時間で色々触っていければと思います。

宣伝

弊社ではUnityエンジニアを募集しています。興味がある方は是非以下のページを覗いてみてください

twitter.com

herp.careers