読者です 読者をやめる 読者になる 読者になる

Makopy'5 La6

スマホアプリ開発とかその周辺のこととか関係ないこと。または恋は言ってみりゃボディー・ブロー

(Xamarin.Forms)アプリを終了させる

スマホアプリにおけるアプリ終了

基本的にあまりしたくないことではありますが…。
実戦のアプリ開発では、
「アプリを終了させたい 」
というシーンや要求に出くわすことがあります。

iOSの場合

可能かどうかと問われれば、可能です。
exit()をコールすればアプリは終了します。
しかしながらiOSにおいて、
プログラミングによりアプリ終了をしてよいかどうか?
については、諸説あります。

iOS Human Interface Guidelines」に下記の記載があります。

iOSアプリケーションをプログラム的に強制終了させることは避ける。  
単にクラッシュしたものと受け取られる可能性があります。  
何らかの原因でアプリケーションが意図通り機能しない場合は、その状況を伝え、何ができるかを説明しなければなりません。

iOSヒューマンインターフェイスガイドライン: 起動と停止

iOSの公式のドキュメントで上記のように言及されていることもあり、
iOSではアプリを終了してはいけない」
という論調が多く見られます。
しかしながら、
「いきなり終わって、不正終了みたくなるのがよくない」
と言っているわけであって、
「理由を表示した上でアプリを終了するならよい」
という解釈もあり、筆者はこちら派です。
どちらが真に正しいかは判断しかねますが、実際にexit()をしているアプリも見かけます。
exit()そのものがリジェクトに直結するわけではないと考えられます。

上述のような経緯から、
iOSでアプリ終了に持ち込みたい場合、

  • 何かしらメッセージを表示した上でexit()する
  • 再起動を促すメッセージを表示した上で、ユーザーが何もできない状態にする
    • ユーザーは再起動以外できることがない

という2つの選択肢があります。

Androidの場合

Androidについては、
「プログラミングによりアプリ終了をしてよいかどうか? 」
に関する議論はあまり見たことがない気がします。

アプリ終了の具体的な実現方法については、いくつかあります。
下記の記事が詳しくまとめてくれています。
www.ecoop.net

Xamarin.Formsにおけるアプリ終了

System.Diagnostics.Process.GetCurrentProcess().CloseMainWindow()

ググってみると、

System.Diagnostics.Process.GetCurrentProcess().CloseMainWindow()
を使えばよさそうなことが分かりました。 しかしながら共通実装部からは使えません。
使うためにはNuGetパッケージを追加しなければならないのですが、 共通実装部ではパッケージの追加もできません。

(補足)
この点については環境を含めた筆者の認識・理解不足があるかもしれません。  
少なくとも手持ちの環境(Mac OS上のXamarin Studio)ではパッケージ追加できませんでした。  
また、System.Diagnostics.Processとは、本来共通実装部で使用すべきでない/できないものなのかもしれません。  
気持ち悪いですが、ここでは深追いせずに、手持ちで出来る範囲で実現した方法を記載しておきます。  

さて、共通実装部ではできなくても、
各ネイティブ(.Droid/.iOS)にはパッケージを追加して、利用することができます。
ので、今回はDependencyServiceとして実装することにしました。

Xamarin.Formsでアプリ終了を実現するコード

DependencyServiceにより実現

  • 共通実装部
  • .Droid

全く同じメソッドを呼んで同じ処理をするのにDependencyServiceにするのはちょっと納得いかないですが…。
強いて言えば、Androidでのアプリ終了はいくつかの方法があるので、実情に応じて別の実装に置き換えてもいいと思います。
例えば、

  • .Droid

とすることもできます。

今回実験をしたサンプルコードはこちら。
github.com

相変わらず実験用の適当なコードです…。