SafariViewControllerとセッション

Tuesday, November 6, 2018

要確認。データを共有できるとあるがセッションも含むのだろうか。

SafariViewControllerとは

AppleはWebビューとしてUIWebView、WKWebViewを提供していますが、それとは別にSafariの機能を持つSafariViewControllerを提供しています。

SafariViewControllerは全画面で表示され、クッキーやウェブサイトのデータをSafariと共有します。アプリからオートフィルや閲覧履歴などのデータを取得することはできません。

上記の特製のほか、App Store Reviewガイドラインの5.1.1 データの収集および保存 (vii) に以下の記載があるため、ユーザーの情報を表示するWebページをアプリ内で表示する際はSafariViewControllerを使う必要があります。

(vii)ユーザーに情報を視覚的に提示する際は、必ずSafariViewControllerを使用する必要があります。SafariViewControllerを非表示にしたり、別のビューやレイヤーで隠したりすることは許可されません。また、SafariViewControllerを使用して、ユーザーの認知や同意なしにAppでユーザーの追跡を行うことは許可されません。

出典 App Store Reviewガイドライン - Apple Developer (5.1.1 データの収集および保存) より

SafariViewControllerと記述していますが、実装では SFSafariViewController というクラスを扱うことになります。

SFSafariViewControllerとは

Appleは SFSafariViewController をSafariとデータの共有に触れながら以下のように紹介しています。Safariの機能を持つビューコントローラーとありますが気になるのはセッション (Cookie) の部分です。

The view controller includes Safari features such as Reader, AutoFill, Fraudulent Website Detection, and content blocking. In iOS 9 and 10, it shares cookies and other website data with Safari. The user's activity and interaction with SFSafariViewController are not visible to your app, which cannot access AutoFill data, browsing history, or website data. You do not need to secure data between your app and Safari. If you would like to share data between your app and Safari in iOS 11 and later, so it is easier for a user to log in only one time, use SFAuthenticationSession instead.

iOS 9と10ではSafariViewControllerとSafariでCookieとそのほかのデータが共有でき (要確認) 、iOS 11以降の場合はログインが1回の方が易しいからということで SFAuthenticationSession の使用を勧めています。執筆当時では SFAuthenticationSession はDeprecatedになっており、 ASWebAuthenticationSession の利用を勧めています。ただし、このクラスはiOS 12以降から使用できます。

ここまでの内容を下表に整理しました。

iOS ver. 説明
iOS 9 SafariとCookieをそのまま共有できる。(SFAuthenticationSessionの概要より)
iOS 10 SafariとCookieをそのまま共有できる。(SFAuthenticationSessionの概要より)
iOS 11 Safariとデータを共有したい場合はSFAuthenticationSessionを使う。ただし、Deprecatedです。
iOS 12 Safariとデータを共有したい場合はASWebAuthenticationSessionを使う。

つまり、アプリ要件によってはSafariとセッション (Cookie) を共有するには3パターンの対応が必要です。

iOS 9 iOS 10 iOS 11 iOS 12
何もせず素のママで良い y y n/a n/a
SFAuthenticationSession n/a n/a y y
ASWebAuthenticationSession n/a n/a n/a y

例としてGmailでログインして見たいと思います。

iOS 9

  • パターンA

    • Mobile Safariでログイン

    • アプリのSafariViewControllerを開く (ログインしている)

    • アプリのSafariViewControllerでログアウト

    • Mobile SafariでGmailを開くとログアウトしている

  • パターンB

    • アプリのSafariViewControllerでGmailにログイン

    • Mobile SafariでGmailにアクセス (ログインしている)

    • Mobile SafariでGmailからログアウト

    • アプリのSafariViewControllerでGmailを開くとログアウトしている

iOS 10も上記と同様

iOS 11はだめ

SFAuthenticationSession とは

SFAuthenticationSession を使った実装

参考資料

iOSSwift認証Webビュー

BlenderのソースコードをEmacsで読む

Background fetch