【Swift】WebViewのCookieを永続的に保持しておきたい


2回目の投稿です。以前記事書いたときは正直これっきりかなと思っていたのですが、ちゃんとアウトプットしていくことによる学習効率の素晴らしさと、ひとからフィードバックをいただける喜びを切に感じ、もっと色々積極的に発信していくべきだな〜と思ったので、また記事を投稿させていただきました次第です。
少しでも気になる所がございましたら、ご指摘いただけると非常に嬉しいです。

本題です

例えば、ユーザログインが必要なウェブページでは、クッキーを利用することでログイン状態を保持しておくことができるようにしている場合が多いと思います。
しかし、アプリ内で用意したUIWebViewからログインページに飛んでログインを行った場合、アプリが終了されるまではクッキー情報は消えないためログイン状態を保持できますが、アプリがkillされてしまうなどするとクッキー情報が破棄されてしまうため、再度アプリを立ち上げた時には改めてログインし直さなければならなくなってしまいます。
ので、このような場合には永続的にクッキーを保存しておく方法が必要になってくるのですが、具体的にどのようにするのが一番良さそうかな...
っていうお話です。

こんな解決法を提案します

お手軽にデータを永続化する方法といえば、UserDefaultsという機能があります。
今回は素直にそれを利用します。
ただUserDefaultsは保存できるデータ型が決まっており、クッキーをそのまま保存することはできないのでその辺の工夫が必要です。
AppDelegateに以下のメソッドを用意してください。

AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    // UserDefaultにクッキーを保存するメソッド
    private func storeCookies() {
     // 現在保持されているクッキーを取り出します
        guard let cookies = HTTPCookieStorage.shared.cookies else { return }
     // UserDefaultsに保存できるデータ型に変換していきます
        var cookieDictionary = [String : AnyObject]()
        for cookie in cookies {
            cookieDictionary[cookie.name] = cookie.properties as AnyObject?
        }
     // UserDefaultsに保存します
        UserDefaults.standard.set(cookieDictionary, forKey: "cookie")
    }

    // UserDefaultからクッキーを取得するメソッド
    private func retrieveCookies() {
     // UserDefaultsに保存してあるクッキー情報を取り出します。(この時はまだ[String : AnyObject]型)
        guard let cookieDictionary = UserDefaults.standard.dictionary(forKey: "cookie") else { return }
     // HTTPCookie型に変換していきます
        for (_, cookieProperties) in cookieDictionary {
            if let cookieProperties = cookieProperties as? [HTTPCookiePropertyKey : Any] {
                if let cookie = HTTPCookie(properties: cookieProperties ) {
            // クッキーをメモリ内にセットします
                    HTTPCookieStorage.shared.setCookie(cookie)
                }
            }
        }
    }

// ~以下省略~

}

これで、クッキーを永続的に保存&取得する準備が整いました。(もう本題終わった感ある。)
次に、上記メソッドを適切なタイミングで呼び出していきます。
AppDelegate内にある以下のメソッド内に、先ほど用意したメソッドを以下のように記述します。

AppDelegate.swift
// 起動時
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
   // クッキー取得
     retrieveCookies()
     return true
}

// バックグラウンドに入った時
func applicationDidEnterBackground(_ application: UIApplication) {
     // クッキー保存
     storeCookies()
}

// アプリがkillされた時
func applicationWillTerminate(_ application: UIApplication) {
   // クッキー保存
     storeCookies()
}

これだけ。
applicationWillTerminateメソッドだけでなく、
applicationDidEnterBackgroundメソッド内でもstoreCookies()を呼んでいるのは、applicationWillTerminateはkillされた時に必ず呼ばれる訳ではないっぽいから。(applicationDidEnterBackgroundだけ記述しとけばいいかもしれない。。)
この辺はどういうことなのかあまりよくわかっていないので、詳しい方コメントで教えていただけると嬉しいです。

以上となります。今回の記事も幼稚な感じが否めませんが、だれかの役に立てれば幸いに思います。
どんな些細なことでもよろしいので、気になるところございましたらコメントよろしくお願いします。