保存网络请求的cookies,并存储到UserDefaults中
//保存COOKIES
static func saveCookies(for urlStr: String){
if let url = URL(string: urlStr){
if let cookies = HTTPCookieStorage.shared.cookies(for: url){
var JSESSIONID = ""
for cookie in cookies {
if cookie.name == "SESSION"{
JSESSIONID = cookie.value
break
}
}
if JSESSIONID.count > 0 {
let defaults = UserDefaults.standard
defaults.set(JSESSIONID, forKey: "SESSIONID")
defaults.synchronize()
}
}
}
}
//如果是登录成功一般还需要
func saveLoginCookie(_ urlStr: String){
let str = HOST_API + urlStr
if let url = URL(string: str) {
let cookies = HTTPCookieStorage.shared.cookies(for: url)
//将cookies转换成Data
let data = NSKeyedArchiver.archivedData(withRootObject: cookies as Any)
//将data存储到userDefaults中
UserDefaults.standard.set(data, forKey: HXQUserCookie)
}
}
发起网络请求时,获取已经保存的cookies
static func getCookies(){
let defaults = UserDefaults.standard
let JSESSIONID = defaults.value(forKey: "SESSIONID") as? String
var TOKEN = ""
//登录成功TOKEN
if let cookieData = defaults.value(forKey: HXQUserCookie) as? Data{
if cookieData.count > 0{
if let cookies = NSKeyedUnarchiver.unarchiveObject(with: cookieData) as? Array<HTTPCookie>{
for cookie in cookies {
if cookie.name == "TOKEN"{
TOKEN = cookie.value
break
}
}
}
}
}
if TOKEN.count > 0 && JSESSIONID != nil {
if let sessionCookie = HTTPCookie(properties: creatHTTPCookie("SESSIONID", vlaue: JSESSIONID!)) {
HTTPCookieStorage.shared.setCookie(sessionCookie)
}
if let tokenCookie = HTTPCookie(properties: creatHTTPCookie("TOKEN", vlaue: TOKEN)) {
HTTPCookieStorage.shared.setCookie(tokenCookie)
}
}
}
static func creatHTTPCookie(_ key: String, vlaue: String) -> [HTTPCookiePropertyKey : Any] {
// 定义一个可变字典存放cookie键值对
var properties: [HTTPCookiePropertyKey : Any] = [:]
properties[.name] = key
properties[.path] = "/"
properties[.value] = vlaue
properties[.secure] = true
#if DEBUG
let domain = "cs.hxquan.cn"
#else
let domain = "m.hxquan.cn"
#endif
properties[.domain] = domain
properties[.version] = 0
return properties
}
这里创建cookie的时候需要特别注意,swift中cookie创建 HTTPCookie(properties: [HTTPCookiePropertyKey : Any]),需要 [HTTPCookiePropertyKey : Any]这种格式的字典,不像oc中那么直接的键值对,cookie中的name,path,value,secure,domain,version等字段都必须要有,oc中不需要。
移除保存的cookies
static func removeCookies(){
if let cookies = HTTPCookieStorage.shared.cookies{
//移除cookies
for cookie in cookies {
HTTPCookieStorage.shared.deleteCookie(cookie)
}
}
//移除userDefaults数据
let defaults = UserDefaults.standard
defaults.removeObject(forKey: HXQUserCookie)
defaults.removeObject(forKey: "SESSIONID")
defaults.synchronize()
}
针对wkwebView的cookie的操作:
wkwebView在访问的时候如果需要记录用户的操作,也需要传入cookie,但是wkWebView不能直接通过HTTPCookieStorage来访问cookie,需要把cookie存放在WKUserScript中
lazy var webView: WKWebView = {[weak self] in
let config = WKWebViewConfiguration()
config.userContentController = WKUserContentController()
//允许内嵌video播放
config.allowsInlineMediaPlayback = true
config.userContentController.add(WeakScriptMessageDelegate(scriptDelegate: self!), name: HxqWebHandleName)
let defaults = UserDefaults.standard
var cookieDict = [String:String]()
if let SESSIONID = defaults.value(forKey: "SESSIONID") as? String{
cookieDict["SESSIONID"] = SESSIONID
}
if let cookiesData = defaults.value(forKey: HXQUserCookie) as? Data{
if let cookies = NSKeyedUnarchiver.unarchiveObject(with: cookiesData) as? Array<HTTPCookie> {
for cookie in cookies{
if cookie.name == "TOKEN"{
cookieDict["SESSIONID"] = cookie.value
break
}
}
}
}
if cookieDict.keys.count == 2{
let cookieScript = WKUserScript(source: "document.cookie = 'TOKEN=(cookieDict["TOKEN"]!);path=/';document.cookie = 'SESSIONID=(cookieDict["SESSIONID"]!);path=/'", injectionTime: .atDocumentStart, forMainFrameOnly: false)
config.userContentController.addUserScript(cookieScript)
}
let webView = WKWebView(frame: .zero, configuration: config)
webView.uiDelegate = self
webView.navigationDelegate = self
return webView
}()
这里也有一个地方需要注意的document.cookie = 'TOKEN=(cookieDict["TOKEN"]!);path=/'',这里的path=/一定要加上,当初调试的时候因为这个问题花了很长时间才找到原因