iOS9のSFSafariViewControllerを使ってアプリ初回起動時のブラウザリダイレクトを卒業しよう

  • 122
    いいね
  • 0
    コメント

2017-07-25 追記

App Store審査ガイドラインにおいて下記の方法でユーザのトラッキングを行うことは明確にNGとされたようです。

また、SafariViewControllerを使用して、ユーザーの認知や同意なしにアプリケーションでユーザーの追跡を行わないでください。

https://developer.apple.com/app-store/review/guidelines/jp/#other-business-model-issues

######### 追記おわり ############

広告トラッキングのために、アプリ初回起動直後に自動的にSafariが開いて、再度アプリに戻ってくる・・っていうやつありますよね。うざいですよね。
Safariのcookieをアプリ側から取れないので、ああいうダサいことを各広告SDK提供会社は採用していたわけです。

で、iOS9のSFSafariViewControllerを使えば、このダサイ挙動は改善できるんじゃない?ってことを同僚と話していたので、実験してみました。

ViewController.swift
import UIKit
import SafariServices

let kSafariViewControllerCloseNotificationName = "safariViewControllerCloseNotificationName"

class ViewController: UIViewController {

    lazy var safariVC:SFSafariViewController! = {
        let url = NSURL(string: "http://kenmaz.net/tmp/ios9_sample.html")!
        let vc = SFSafariViewController(URL:url)
        vc.delegate = self
        return vc
    }()

    var tracked = false

    override func viewDidLoad() {
        super.viewDidLoad()

        NSNotificationCenter.defaultCenter().addObserverForName(
            kSafariViewControllerCloseNotificationName,
            object: nil,
            queue: NSOperationQueue.mainQueue()) { [unowned self] (notification) -> Void in

                self.tracked = true
                self.safariVC.dismissViewControllerAnimated(true, completion: nil)
        }
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        if !tracked {
            presentViewController(safariVC, animated: true, completion: nil)
        }
    }
}

extension ViewController: SFSafariViewControllerDelegate {

    func safariViewControllerDidFinish(controller: SFSafariViewController) {
        controller.dismissViewControllerAnimated(true, completion: nil)
    }
}
AppDelegate.swift
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, openURL url: NSURL,
        sourceApplication: String?, annotation: AnyObject) -> Bool {

            NSNotificationCenter.defaultCenter().postNotificationName(
                kSafariViewControllerCloseNotificationName,
                object: nil)

            return true
    }
}
ios9_sample.html
<h1>踏み台ページ</h1>

<script>
  setTimeout(function() {
    document.location = 'ios9-safarivc://close'
  }, 3000);
</script>

NDAがあるのでスクショは載せられませんがサンプルコードだけアップしときました。
https://github.com/kenmaz/iOS9_safariVCSample

一瞬safariViewControllerがチラっと表示されるのがダサいですが、cookieはちゃんと共有されてます。
他にもクールなやり方があるかもしれませんが、各広告SDK提供会社に期待しましょう。。。