技術と趣味の亜空間

主にゲームプログラミングとその周辺に関する記事を不定期で上げていきます

AppleStoreリジェクト対策 - 外部ブラウザの起動厳禁

概要

ゲームアプリをAppleStoreの審査に提出したところ、以下のような内容でリジェクトされた。

Guideline 4.0 - Design
We noticed that the user is taken to Safari to sign in with Twitter account, which provides a poor user experience.
Next Steps
To resolve this issue, please revise your app to enable users to sign in or register for an account in the app.
We recommend implementing the Safari View Controller API to display web content within your app. The Safari View Controller allows the display of a URL and inspection of the certificate from an embedded browser in an app so that customers can verify the webpage URL and SSL certificate to confirm they are entering their sign in credentials into a legitimate page.
Resources
For additional information on the Safari View Controller API, please review the What's New in Safari webpage.

要約すると、ゲームアプリ内からSafariを立ち上げるのはユーザー体験として良くないので変えて下さい、というもの。
これはTwitter連携によるアカウントの引き継ぎが外部ブラウザ経由でログイン認証をしているのだが、その際にApplication.OpenURL​() でブラウザを起動していたのが原因。

対策

WebViewをUnity上に埋め込むことで、アプリ内でブラウザを表示・処理できるように変更した。
WebViewをUnityで実装するためにはプラグインを利用する必要があるが、自分の知る限りメジャーなものが2つ存在する。

1. gree/unity-webview

1つ目は gree/unity-webview

github.com

オープンソースなので、無料で導入が可能。
ただしドキュメント等はなく、複雑なことをしようとするとソースコードをよく調査したり、GithubのIssuesで聞いたりが必要。
また、Unityのバージョンによっては特殊な対応も必要になり、ちゃんとやろうとすると自分でメンテナンスやカスタマイズが必須のため、扱いが難しいという印象。
単純にゲーム内で特定のサイトページを表示するだけという利用目的なら問題ないと思う。

2. UniWebView

2つ目は UniWebView

docs.uniwebview.com

こちらは有料のアセットだが、ドキュメントも豊富に用意されているので分かりやすく、カスタマイズしやすい。
アップデートもしっかり行われているのも安心。

この2つを検討した結果、

  1. 認証サイトから認証結果を受け取る必要がある
  2. 上記も容易に実装可能であること
  3. 開発時間も限られているため安全に対応できる

という観点からUniWebViewを採用。

変更対応

WebViewに変更したので、ディープリンクデータの受け取る方法も変更になる。
UniWebViewの場合、URLスキーマで受け取ったデータは OnMessageReceived で購読すれば取得可能。
ブラウザアプリ経由時と同じデータが UniWebViewMessage.RawMessage に格納されている。

private UniWebView _webview;

_webview.OnMessageReceived += (view, message) =>
{
     Debug.Log($"RawMessage: {message.RawMessage}");
};

その他注意点として、ページの読み込みがサイトによっては1秒以上かかったりするので、その際にフリーズと思われないようにロード中のUI表示をすると良い。
OnPageStartedOnPageFinished で読み込み中の処理が挟めるのでそこで対応する。

private GameObject _loadingUI;

_webview.OnPageStarted += (view, url) =>
{
     _loadingUI.SetActive(true);
};
_webview.OnPageFinished += (webView, statusCode, url) =>
{
     _loadingUI.SetActive(false);
};

また、OnKeyCodeReceivedAndroidのバックキー対策、OnShouldCloseをfalseにしてdeviceで自動でCloseしないように登録も忘れずに。

// Android専用イベント
_webview.OnKeyCodeReceived += (UniWebView webView, int keyCode) =>
{
     // BackButton : 4 (Android API for keycode)
     if (keyCode == 4) Debug.Log("ここで戻る対応とか");
};

// UniWebviewからdeviceで自動でCloseしないように登録
_webview.OnShouldClose += (UniWebView webView) => false;