
ネイティブアプリケーションの意味
プラットフォームによってはアプリケーションの実装技術には複数の方法があり、開発側の要件や制約、好み等に合わせて適した技術を選ぶことができます。例えばiOSアプリケーションの実装技術には、Appleが提供するCocoa Touch(およびUIKitやSwiftUIなどのフレームワーク群)がありますが、そのほかのベンダーから提供されている技術として、FlutterやReact Native, Titanium, Xamarinなどのフレームワークも存在します。
どのフレームワークが一番優れているのかを語ろうとすると宗教戦争に発展してしまいますので、そこは避けつつも「ネイティブとは何か」の解釈をはっきりさせておきたいと思いました。
どのようにして実装技術を選ぶのか
開発現場としては、大抵は次のような観点で実装技術を選ぶことになると思います。
・開発コスト、運用コスト重視
・開発スピード重視
・技術・経験の有無
・ネイティブ技術によるパフォーマンスとUXの重視
・UIの振る舞いとUXの重視
・技術者の好み
最後の「技術者の好み」はとても主観的なものですが、その他の観点は開発現場で実際にとれるであろう可能性をそれぞれ天秤にかけ、優先度を付けながら最終的に採用技術を決定します。
「本当ならネイティブUIによりもたらされるユーザー体験を一番に重視したいけれども、開発チームの中にネイティブのUIKitやSwiftの経験が豊富なエンジニアが不在なので、仕方なくXamarinでiOS appを開発することにしました。」
…そのような事情で採用技術を選ぶことも実際にあるのだと思います。
1Password 8の騒動から「ネイティブ」の意味を考えさせられる
ネイティブという言葉は実際のところとても曖昧に思えます。例えばReact Nativeは「ネイティブ」を謳っていますが、それで実装されたアプリケーションがネイティブであるのかについてはさまざまな意見が飛び交うことでしょう。
そもそも「ネイティブ」とは何なのか。私なりの解釈をまとめておきたいと思います。それに当たってまず1Password 8で起こった騒動をご紹介しておきましょう。
先日、1Password 8のリリース告知がありました。このとき、特に海外の往年の1Passwordユーザーからは批判的な声が多く上がり、ちょっとした騒動となりました。何が原因だったのかというと、1PasswordはMacでリリースされて以来ずっと「ネイティブ」のアプリケーションとして開発されてきたのですが、macOS版バージョン8はElectronベースの非ネイティブアプリケーションに置き換えられることが判明したためでした。このことが、macOSとの親和性を評価してきたMac版ユーザーたちから顰蹙を買ってしまったのでした。
ユーザーがイメージする「ネイティブ」と、AgileBits側が主張する「ネイティブ」が指す意味に食い違いがあり、更なる議論を呼んでいる、そのような状況にあるようでした。
用語の補足:
「Electron」とはChromiumベースのアプリケーション開発用フレームワークで、要はWeb技術を使ってクロスプラットフォームのデスクトップアプリケーションを作れる技術です。Slackなどで採用されており、プラットフォームを跨いだアプリケーション開発の現場ではコードを統一できるとしてデベロッパーの人気が高まっています。
一方で、プラットフォーム固有のUIの「ルックアンドフィール」が不揃いになるなどの懸念、UIにまつわるユーザー体験の悪化、メモリ消費量の問題、アプリケーション容量の問題、セキュリティ面での不安等が指摘されることが多く、特にネイティブ性を好むMacユーザーの中には嫌う人が多い技術でもあります。
AgileBitsとしては、
「macOS版1Password 8はRustでUIを構築しているが、その他にもSwiftコードも多く含んでいるし、“ネイティブ”が提供するWKWebView上にコンテンツを描画している。コンパイルされたコードはx86_64 / armに最適されているので、これは完全にネイティブである」
For the desktop app we have a thin UI layer powered by Rust, which is compiled to native platform code (x86_64, arm, etc) and we have plenty of Swift code for accessing native macOS apis. If we placed the UI code in a native WKWebView it’d be completely “native”. [2/2]
— Dave Teare (@dteare) August 11, 2021
という趣旨の主張のようです。
一方それに反論するユーザーの意見としては、多く挙がっている意見を総合すると、
「WKWebViewを使ったらそのアプリケーションはすべてネイティブと言えると考えているのですか? 実際にはWebアプリケーション(いわゆるガワネイティブ)では?」
「私たちがネイティブと呼んでいるのは、macOSのAppKitフレームワークによって表現される『ルックアンドフィール』であって、Electron等による実装はネイティブとは考えていません」
WKWebViews are NOT native. UIKit is the only thing that looks and feels right, and SwiftUI is good enough and getting better. Use that instead!
— Max Harris (@maxharris9) August 12, 2021
So, it’s no longer a native Mac app? Electron apps are not native Mac apps.
— Jordan Kay (@_Jordan) August 11, 2021
@dteare is it true that even the Mac version is now on Electron? As a 12 year user that has brought you to multiple companies and family members, that is incredibly disappointing and downright depressing. Thought I could always count on you to build good Mac software.
— Blake Gentry (@blakegentry) August 11, 2021
このような声が多く挙がっているようです。
もちろんネイティブの技術を採用すれば自動的にUIも良いものになるとは限りません。現在の1Password 7のUIは(私の評価としては)最高とは思いませんし、もう少し「標準的なmacOSらしく」振る舞って欲しいと思います。それでもネイティブであることはMacユーザーにとっては大きな価値でした。他のアプリケーションとのインタラクションであったり、OS全体を見渡した時の個々のUIの細かな振る舞い、ルックアンドフィールの一貫性は何より重要だと考えます。
その他にもElectronが抱えるメモリ消費やセキュリティ面での問題を指摘する声も多く、なぜ今までAppKitベースのネイティブだったものを「改悪」するのかが納得できない等の意見が挙がっています。
Electron?! Really. I have used and supported 1Password for years because it has been a native app. Ugh.
— Jeremy Beker (@gothmog) August 11, 2021
I’m really disappointed about this. I would suggest an AppKit rewrite with SwiftUI leaf views. I don’t want my RAM being used up by apps that aren’t even showing UI currently. RAM is precious on today’s M1 Macs.
— Patrick Smith (@concreteniche) August 11, 2021
I’d prefer native, even if it looked like Windows 95.
Kind, thoughtful feedback for the dev team from an early reviewer of 1Password 8 beta: “I think people ask for native apps, but what they're really asking for is apps that look and feel like the OS, follow standard conventions and behave a consistent way.” https://t.co/8sE14fBicC
— Mislav Marohnić (@mislav) August 13, 2021
Nobody is arguing that every native app is magically good. Of course not.
— Jeff Johnson (@lapcatsoftware) August 12, 2021
The point is that if consistency and conformance with Mac platform conventions is a top priority for a developer, then it doesn't make much sense to start anywhere except with AppKit.
そのほかの点で興味深かったのは、AgileBitsはmacOS版1Password 8を「SwiftUIベースの実装」と「Electronベースの実装」を同時に開発してきており、両者のパフォーマンスを比較した結果後者を選んだという話です。「ならばなぜ既存のAppKitベースの実装を捨てなければならないのか」との意見を納得させる回答は見つけられませんでしたが、現状のmacOSを取り巻く開発環境において、SwiftUIはまだ良い選択肢にはなり得ないことを示しているように思います。
(以下は1Passwordのエンジニアの方のツイート)
Wow, jumping to a conclusion so quickly. We have a large Apple dev team and had a parallel SwiftUI codebase being developed for about 6 months. It had some advantages but overall it underperformed on macOS and the UX was worse.
— Roustem Karimov (@roustem) August 11, 2021
I am certainly not happy with the additional Electron processes and memory usage. We hope to get things improved or maybe even replace the frontend completely at some point.
— Roustem Karimov (@roustem) August 11, 2021
At the same time, we had parallel Electron and SwiftUI builds for many months and I preferred the former.
本件についてはTwitterのほかRedditにも多くのコメントが集まっているので、もし興味があれば漁ってみるとよいと思います。
この騒動から、私自身が以前から抱いていた“違和感”がはっきりと見えるようになりました。それは「人によって『ネイティブ』の解釈が微妙に違っているのではないか」ということです。
・・・
ちなみになぜこうも騒動になっているのかというと、1Passwordは元々Macで始まり、特にMacユーザーの中には10年以上も使い続けている方が多くいます。(ちなみに私もその一人です)
そのようなユーザーは「ネイティブであること」を大きな価値として捉えていたので、今回のElectron化=非ネイティブ化には強く反発する人が出たのだと思います。彼らは“非ネイティブ”のUIには非常に敏感で、些細な違いにもすぐに気がつきます。「表現が少し違っていてもとりあえず機能する」と「表現が完全に合致していて美しく見え、機能する」は、全く異なります。「機能する」のみに着目すれば同じことなのですが、そこに至るまでどのように表現されているかがとても重要なのです。
Twitterコメントを漁る限りですと、AgileBitsは最近に大型資金調達をしたことと関連して、非Macプラットフォームへの展開を行う中で相対的にMac版の重要度が低下しているのではないかとの見方もあるようです。
Poked around around the bundle contents and it looks like 1PW has been rewritten using Electron. 😔
— Curtis Herbert (@parrots) August 11, 2021
This makes me sad. 1PW7 had some annoying UX regressions, and now this in 1PW8. Accepting VC money is proving detremental to the OG users that appreciated 1PW for its 👍 apps. https://t.co/O0VXcSIMFW
アプリケーションのネイティブ性の意味
アプリケーションの「ネイティブ」の指す言葉には複数の意味を含んでいます。
1. コードがCPUのアーキテクチャに適合しているか(コンパイルされているか)
2. プラットフォーム固有の技術を含んでいるか
3. UIのルックアンドフィールがプラットフォームのデザイン言語に適合しているか
エンジニアの方が指す「ネイティブ」とは、多くの場面で1や2です。AgileBitsの創業者の方のツイートでもこの意味で「ネイティブ」の語が使われていました。ですので、3の意味で「ネイティブ」と言っている人々からすると、『なんでUIが標準のものではないのに、これがネイティブだと言えるんだ』といった食い違いが生じるわけです。
For the desktop app we have a thin UI layer powered by Rust, which is compiled to native platform code (x86_64, arm, etc) and we have plenty of Swift code for accessing native macOS apis. If we placed the UI code in a native WKWebView it’d be completely “native”. [2/2]
— Dave Teare (@dteare) August 11, 2021
この食い違いを解消するには、「ネイティブ」を装飾する語句を前後に追加するか、別の表現で区別する必要があるように思います。共通言語がない中で「ネイティブ」の言葉が一人歩きする状況はあまり良いとは思いません。
私の提案としては、例えば以下のように言葉を言い換えてみるとこのような食い違いはいくらか解消に向かうように思います。
・コードのネイティブ性に関して… “ネイティブコード”
・WebView等の利用に関して… “WebViewベースapp” “Electronベースapp”
・UIのネイティブ性に関して… “ネイティブUI”
これらの言葉で区別すると、ネイティブコードを含んでいてもUIの事柄は別の論点にできますし、Electronベースのアプリケーションは「ネイティブUI」と区別できるようになります。
特にUIを考える立場の私としては、ネイティブUIとその他の議論は区別していきたいと思っています。
“ネイティブUI”
プラットフォームが定めるデザイン言語と、そのルックアンドフィールに適合したUI。コードのネイティブ性ではなく表現のネイティブ性を吟味することが大切。
私が考える「ネイティブUIをよく表現できているアプリケーション」の例としては次のようなものがあります(macOS限定)。
いずれもmacOSが定める「ルックアンドフィール」を尊重しながら、OSのコンポーネント(AppKitが提供するもの)を積極的に取り入れ、時には独自の解釈を施しながら“ネイティブUI”というものを作り上げているように感じられます。HIGやWWDCで示されるデザイン言語を取り入れることは当たり前で、そこに違和感のない形で独自のエッセンスを加えられると、とても美しいと感じられます。
macOSのネイティブUIと、そうでないUIの違いが現れやすいポイント
UIのルックアンドフィールでネイティブとそうでない実装で違いが現れやすい(ネイティブかどうかを区別しやすい)ポイントをいくつかご紹介しておきます。
♦︎ 環境設定はモードレスウインドウ
ネイティブUIかどうかの見極めポイントとしては、環境設定を観察する方法が有効です。なぜなら、“分かっている”アプリケーションならHIGやApple純正appに倣ってモードレスウインドウで環境設定を実装するのですが、Electronベースのアプリケーションではそうなっていないことが多いです。
ここで言うモードレスウインドウとは、ドキュメントとは別のウインドウで展開するが、ウインドウを閉じずにいつでも他のウインドウに移動することができる、モードレスウインドウ内の変更を即時反映できる、反映にあたって「保存」「破棄」のダイアログでわざわざ問われないものを指します。
また、モードレスであってもそれが個別のウインドウではなく別の表現になっているものも、ネイティブUI的には「違うもの」と見做されることがあります。macOSにおける環境設定のビジュアルは、Safariのようにツールバーベースのタブバーを備えているモードレスウインドウが推奨されます。
♦︎ ウインドウツールバー
AppKitベースのネイティブUIでは、ウインドウ上部に設置されるツールバーはNSToolbarによって表されます。特にBig Sur以降のツールバーはこれまでのスタイルと大きく変わった点がいくつかあり、ネイティブUIとして正しく実装していれば(大抵は)自動的にその変更が適用されます。
アイコンの見た目も含めて「らしさ」が強く現れている部分ですから、少しでも違った感じがするとそれは“ネイティブUI”のようには見えなくなってしまいます。
♦︎ UIのローカライズ/表記法
メニューバーの「環境設定...」「ウインドウ」「すべてを選択」などのアクション名は、ある程度決まったルールに基づいて命名されます。特に日本語においては “Windows” “Window” は「ウインドウ」が正しい表記で、「ウィンドウ」(小さい「ィ」表記)は誤りです。“Paste”は「ペースト」、“Cut”は「カット」が正しい表記なので、Windows OSの「貼り付け」「切り取り」に合わせると間違いになります。
このようなUIのラベリングなどは開発者がUIに意識を向けていないと起こりやすい“不適合”です。(しかもローカライズを伴うので余計に…)
クロスプラットフォーム系の技術を採用しているとUIの表現に対する意識も向かなくなってくることもあるので、例えばローカライズ処理の自動化コードがOS問わず一本化されていたりすると、macOSなのにWindowsっぽい表記とか、WindowsなのにmacOSっぽいキーボードショートカットとか、そのような問題が起きることも考えられます。
ユーザーにとってはUIがすべてですから、UIに関することは、なるべく開発の都合としてではなくUIデザインとして考えていきたいものです。
「『ウインドウ』が『ウィンドウ』になったぐらいで何か不都合があるのか、些細な違いではないか」と思われるかもしれませんが、些細なことでもそれは違和感として確実にユーザーの心の中に溜まっていくものです。例えば日本語のフォントが中国語っぽい見た目であること(俗に言う中華フォント)は、日本人ならばとても敏感になる問題です。しかし日本語ネイティブではない方や外国人からすると「日本語が表示できているからどうでもいいじゃないか」と片付けられてしまうものなのです。これがエスカレートしていくと、いずれ「わざわざ日本語対応しなくても、同じ漢字を使っているから中国語対応だけでもお前ら問題ないだろ」と、ローカライズ自体を諦められてしまうことも考えられます。
些細なことだとしても、UIとして適切だと考えられる形があるならば、まずはその形が成り立つように設計していくことが大切だと思います。私はUIデザイナーでもあるので、このことは信念として強く抱いています。
♦︎ ブラウザのようにUIのリロード処理(⌘R)が行えてしまう
Electron系アプリケーションでよく見られる光景ですが、あれ自体がChromiumベースのブラウザエンジンみたいなものですので、ウインドウに展開した内容をユーザーが直接リロードできてしまうことがあります。
それができて何か問題があるのかと思われる方もいるかもしれませんが、本来のネイティブUIならブラウザのように振る舞うことは基本ありません。ユーザーが自発的にUI全体を「リロードする」なんてことはないわけですから、それが出来てしまえること自体が一種の“ハリボテ”を演出してしまっているように思います。また、エラー等何かあった時のための避難用コマンドの位置付けだとしたならば、ネイティブUIならそもそも必要がないものですから、リロードの存在自体が非ネイティブUIのデメリットが強く現れているように思えます。
1Password 8の早期アクセス版でもこのことが指摘されていました。
It is 100% an Electron UI, I just did a simple test that no Electron app so far has bothered to make behave like a Mac app: open the app, hit Cmd + R, watch it "refresh" its UI.
— Blake Gentry (@blakegentry) August 11, 2021
If you think Electron on Mac was a good decision @dteare you should be more upfront about it. pic.twitter.com/nC3ZS3zzIK
♦︎ アプリケーションで使われているフレームワーク
アプリケーションに組み込まれているフレームワークを確認する方法があります。一番簡単な方法はFinderで目視することです。
Finderでアプリケーションを選択し、コンテクストメニューから「パッケージの内容を表示」を選びます。いくつか階層を掘って“Frameworks”フォルダを開いてみると、使われている外部フレームワークがわかります。この例ではSlackにはElectronが使われているとわかります。
macOSにおける5つのGUIアーキテクチャ
現在のmacOSには主に5つの種類のUIがあります。これを“Five GUIs”と呼ぶ動きがあるようです。
With its eclectic mix of AppKit, Catalyst, iOS, SwiftUI, and web apps, macOS should consider rebranding to “Five GUIs”
— Joe Groff (@jckarter) September 28, 2020
Five GUIs
・AppKit
・Mac Catalyst
・iOS(互換実行)
・SwiftUI
・Webベース(Electron等)
AppKitは元来ネイティブとされるUIフレームワークで、NeXTの時代から続く歴史あるGUIです。現在のmacOS環境では最も「らしいUI」というものを表現できる唯一の選択肢です。
Mac CatalystはiOS向けに開発したコードをMac向けに移植しやすくした「触媒」的な仕組みです。iOS由来のUIKitを使ってmacOSのUIを実装できますが、元来のAppKitベースの「らしいUI」とはルックアンドフィールが異なる感じになりやすいです。あくまで「iOS appをmacOSに移植しやすくする」位置付けの技術であり、完全なネイティブUIを実現するためのものではないように思えます。
iOS(互換実行)は、Apple SiliconベースのMacで実現可能なiOS appの実行環境です。Mac上でそのままiOS appが動作するので、UIのルックアンドフィールや操作性は完全に度外視した上で、とりあえずiOS appを動かしたい用途ではうまく機能します。
SwiftUIは最近登場した新しいGUIアーキテクチャです。まだ発展途上にあるので実用に耐え得る性能や表現は十分に実現できていませんが、中長期的には既存のAppKitやUIKitベースのUIを置き換えてくるものになるのかもしれません。現状としては、部分的にSwiftUIを採用しながら、主要な部分は既存のコードを維持する形を保つのが良さそうです。
WebベースのUIはElectronなどの3rdパーティ技術を使って実装したものの総称です。「ガワネイティブ」と呼ばれる類いもこれの一種です。最近はクロスプラットフォーム展開とワンソース化の需要や、Web技術の応用でアプリケーションを実装したい需要が高まっているので、この技術を選択するベンダーも増えています。
・・・
macOSアプリケーションがどのGUIで実装されているのかをサクッと検証できるアプリケーション“5 GUIs”を紹介して一旦ここは締めたいと思います。