iOS app 与 Safari共享数据

2,561 阅读2分钟

公司要做 app 推广渠道统计,于是调研了一下几个方案

方案选择

1、使用SFSafariViewController(ios9 ~ ios10以下)、SFAuthenticationSession(ios11)、ASWebAuthenticationSession(ios12.0)来获取safari内的cookie,但SFAuthenticationSession是OC语言的一个管理类,不能去除弹框,不能改变打开的H5页面大小和禁止跳转页面

2、匹对IP、userAgent等设备信息 等数据来达到确认渠道方的这一方案,因为IP地址可能会变动所以在匹对数据上会有误差,

4、使用剪切板来匹对渠道源,当用户在下载APP包的过程中,用户拷贝和剪切了其他数据的情况下,是无法匹对渠道源的。而且只支持 iOS10+。iOS9 及一下js不支持。

测试 代码

swift 代码

import UIKit
import SafariServices
import AuthenticationServices // iOS 12+

class PopularizeUtil: NSObject {
    static private let URLString = ""
    private weak var rootVC: UIViewController?
    
    private func getPopularizeParmasBelowIOS10() {
        guard let url = URL(string: PopularizeUtil.URLString) else { return }
        //SFSafariViewController, 通过 open scheme 的方式回调,在UIApplicationDelegate 的 openUrl 里面
        let vc = SFSafariViewController(url: url)
        vc.modalPresentationStyle = .overCurrentContext
        vc.delegate = self
        vc.view.alpha = 0 // fot test
        let rootVC = UIApplication.shared.windows.first?.rootViewController
        rootVC?.present(vc, animated: true, completion: {
            
        })
        self.rootVC = rootVC
    }
    
    private var iOS11Auth: Any?
    @available(iOS 11.0, *)
    private func getPopularizeParmasWithIOS11() {
        guard let url = URL(string: PopularizeUtil.URLString) else { return }
        let auth = SFAuthenticationSession(url: url, callbackURLScheme: "aaaa") { (url, error) in
            print("@@@@@@@@@@@@@ SFAuthenticationSession callback\(String(describing: url)),\(String(describing: error))")
            if let u = url?.absoluteString {
                NHAlertView.showNHAlertTitle("SFAuthenticationSession get cookie", message: u)
            }
        }
        auth.start()
        iOS11Auth = auth
    }

    
    private var iOS12Auth: Any?
    @available(iOS 12.0, *)
    private func getPopularizeParmasUpIOS12() {
        guard let url = URL(string: PopularizeUtil.URLString) else { return }
        let auth = ASWebAuthenticationSession(url: url, callbackURLScheme: "aaaa") { (url, error) in
            print("!!!!!! ASWebAuthenticationSession callback\(String(describing: url)),\(String(describing: error))")
            if let u = url?.absoluteString {
                NHAlertView.showNHAlertTitle("ASWebAuthenticationSession get cookie", message: u)
            }
        }
        auth.start()
        iOS12Auth = auth
    }
    
    
    private func getPopularizeParamsFromPasteboard() {
        let pasteboard = UIPasteboard.general
        print("字符串数据\(String(describing: pasteboard.string))")
        print("字符串数组\(String(describing: pasteboard.strings))")
        print("URL数据\(String(describing: pasteboard.url))")
        print("URL数组\(String(describing: pasteboard.urls))")
        if let str = pasteboard.string {
            NHAlertView.showNHAlertTitle(" UIPasteboard get data", message: str)
        }
    }
    
    @objc func getPopularizeParmas() {
        // by cookie
        if #available(iOS 12.0, *) {
            getPopularizeParmasUpIOS12()
        } else if #available(iOS 11.0, *) {
            getPopularizeParmasWithIOS11()
        } else {
            getPopularizeParmasBelowIOS10()
        }
        
        // by clipboard
//        getPopularizeParamsFromPasteboard()
    }
}

extension PopularizeUtil: SFSafariViewControllerDelegate {
    
    // 开始加载
    func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL) {
        print(" SFSafariViewController initialLoadDidRedirectTo:\(URL)")
    }
    // 页面加载完成。只有初始URL加载完成时会调用。
    func safariViewController(_ controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool) {
        print(" SFSafariViewController didCompleteInitialLoad:\(didLoadSuccessfully)")
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
            self.rootVC?.dismiss(animated: true, completion: {

            })
        }
    }
    // 销毁controller
    func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
        print(" SFSafariViewController safariViewControllerDidFinish:\(controller)")
    }
}

共享 cookie

<<head>
  <meta name="viewport" content="width=device-width">
</head>

<body>
<script>

var c = document.cookie;
var m = c.match(/name=(\w+)/);
var name;

if (m) {
  document.writeln("You are " + m[1] + '.');
  name = m[1];
} else {
  document.writeln("You are anonymous.");
  name = "";
}


if (name) {
	alert(name);
	var Schemes = "aaaa"
    if (name.length > 0) {
        location.href = Schemes+"://testcookie/" + name;
    } else  {
        location.href = Schemes+"://";
    }
}

function saveName() {
    document.cookie = 'name=' + document.getElementById('name').value + ';max-age=3600';
    location.reload();
}

</script>

<input type="text" id="name">
<input type="submit" value="Save" onclick="saveName();">

</body>

测试 clipboard 代码

<head>
  <meta name="viewport" content="width=device-width">
</head>

<body>
<script>
function copyData() {
    var copy = function (e) {
        e.preventDefault();
        console.log('copy');
        var text = "blabla"
        if (e.clipboardData) {
          e.clipboardData.setData('text/plain', text);
        } else if (window.clipboardData) {
          window.clipboardData.setData('Text', text);
        }
    }
    window.addEventListener('copy', copy);
    document.execCommand('copy');
    window.removeEventListener('copy', copy);
}

function copyData2(text) {
  const input = document.createElement('input');
  input.setAttribute('readonly', 'readonly');
  input.setAttribute('value', text);
  document.body.appendChild(input);
  input.setSelectionRange(0, 9999);
  if (document.execCommand('copy')) {
    document.execCommand('copy');
    console.log('复制成功');
  }
    document.body.removeChild(input);
}

function saveName() {
  var text = document.getElementById('name').value
  copyData2(text);
}

</script>

<input type="text" id="name">
<input type="submit" value="Save" onclick="saveName();">

</body>

参考链接

blog.csdn.net/jiang314/ar… blog.csdn.net/u014410695/… www.jianshu.com/p/6cb411f04… www.jianshu.com/p/81150f7e6… www.jianshu.com/p/d2ce1d97b… stackoverflow.com/questions/3…

juejin.cn/post/684490… juejin.cn/post/684490…