Him*_*dav 17 cookies ios swift ios9
我正在开发一个登录应用程序.成功登录后,响应cookie数据.
如何使用/保存此数据以用于将来的请求?
对于初学者我试图保存它NSHTTPCookieStorage
.但这也行不通.
登录方式(部分):
let task = session.dataTaskWithRequest(request) { (data, responseData, error) -> Void in
if let response = responseData as? NSHTTPURLResponse {
statusCode = response.statusCode
print("Response code: \(statusCode)")
}
var json: NSDictionary?
do {
json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
} catch {
print(error)
err = error
}
if(statusCode != 200) {
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: '\(jsonStr)'")
}
else {
print("Everything Looks good: \(responseData)")
self.setCookies(responseData!)
self.shouldPerformSegueWithIdentifier("showHomeController", sender: self)
}
}
task?.resume()
Run Code Online (Sandbox Code Playgroud)
保存Cookie方法
private func setCookies(response: NSURLResponse) {
if let httpResponse = response as? NSHTTPURLResponse {
let cookies = NSHTTPCookie.cookiesWithResponseHeaderFields(httpResponse.allHeaderFields, forURL: response.URL!) as! [NSHTTPCookie]
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookies(cookies, forURL: response.URL!, mainDocumentURL: nil)
for cookie in cookies {
var cookieProperties = [String: AnyObject]()
cookieProperties[NSHTTPCookieName] = cookie.name
cookieProperties[NSHTTPCookieValue] = cookie.value()
cookieProperties[NSHTTPCookieDomain] = cookie.domain
cookieProperties[NSHTTPCookiePath] = cookie.path
cookieProperties[NSHTTPCookieVersion] = NSNumber(integer: cookie.version)
cookieProperties[NSHTTPCookieExpires] = NSDate().dateByAddingTimeInterval(31536000)
let newCookie = NSHTTPCookie(properties: cookieProperties)
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(newCookie!)
println("name: \(cookie.name) value: \(cookie.value())")
}
}
}
Run Code Online (Sandbox Code Playgroud)
错误:
Cannot invoke 'cookiesWithResponseHeaderFields' with an argument list of type '([NSObject : AnyObject], forURL: NSURL)'
Run Code Online (Sandbox Code Playgroud)
San*_*eep 25
如果您意识到cookie的使用,则服务器必须发送标头Set-Cookie
以响应客户端请求.只需检查标题作为响应,您将看到Set-Cookie
包含cookie的标题字段.
https://en.wikipedia.org/wiki/HTTP_cookie#Setting_a_cookie
如果您使用默认或背景的URLSession,则无需URLSessionConfiguration
进行任何更改以保存cookie.如果您查看默认文档URLSessionConfiguration
,它会像这样描述,
默认会话配置使用基于磁盘的持久缓存(除非将结果下载到文件中),并将凭据存储在用户的密钥链中.它还将cookie(默认情况下)存储在与NSURLConnection和NSURLDownload类相同的共享cookie存储库中.
此外,您可以在此处URLSessionConfiguration
的财产文档中进一步了解此httpCookieStorage
信息.
这是一小段代码,我将进一步用于测试cookie存储.
let sessionConfiguration = URLSessionConfiguration.ephemeral
sessionConfiguration.httpCookieAcceptPolicy = .never
let customSession = URLSession(configuration: sessionConfiguration)
enum Result {
case success(HTTPURLResponse, Data)
case failure(Error)
}
func readCookie(forURL url: URL) -> [HTTPCookie] {
let cookieStorage = HTTPCookieStorage.shared
let cookies = cookieStorage.cookies(for: url) ?? []
return cookies
}
func deleteCookies(forURL url: URL) {
let cookieStorage = HTTPCookieStorage.shared
for cookie in readCookie(forURL: url) {
cookieStorage.deleteCookie(cookie)
}
}
func storeCookies(_ cookies: [HTTPCookie], forURL url: URL) {
let cookieStorage = HTTPCookieStorage.shared
cookieStorage.setCookies(cookies,
for: url,
mainDocumentURL: nil)
}
func executeURLRequest(url: URL, inSession session: URLSession = .shared, completion: @escaping (Result) -> Void) {
let task = session.dataTask(with: url) { data, response, error in
if let response = response as? HTTPURLResponse,
let data = data {
completion(.success(response, data))
return
}
if let error = error {
completion(.failure(error))
return
}
let error = NSError(domain: "com.cookiesetting.test", code: 101, userInfo: [NSLocalizedDescriptionKey: "Unknown error occurred"])
completion(.failure(error))
}
task.resume()
}
Run Code Online (Sandbox Code Playgroud)
使用上面的代码段,我们首先测试默认会话保存cookie.
var cookies = readCookie(forURL: googleURL)
print("Cookies before request: ", cookies)
executeURLRequest(url: googleURL) { result in
if case .success (let data) = result {
cookies = readCookie(forURL: googleURL)
print("Cookies after request: ", cookies)
deleteCookies(forURL: googleURL)
cookies = readCookie(forURL: googleURL)
print("Cookies after deletion: ", cookies)
}
}
Run Code Online (Sandbox Code Playgroud)
而且,这是我们得到的,
Cookies before request: []
Cookies after request: [<NSHTTPCookie
version:0
name:1P_JAR
value:2018-09-26-15
expiresDate:'2018-10-26 15:39:46 +0000'
created:'2018-09-26 15:39:46 +0000'
sessionOnly:FALSE
domain:.google.com
partition:none
sameSite:none
path:/
isSecure:FALSE
path:"/" isSecure:FALSE>, <NSHTTPCookie
version:0
name:NID
value:139=E3g4bKNRGcYoeFuaECpfsx_Efp64xONmVwcJS7f7PuZe8LayS5ZkGuz3f7z6eq7zoBm2z-opTvzX8YPzn8v1ebjH6iyt5-6yDYm9RE6XhXwHCZWs98_j7nb11u2EPnHI
expiresDate:'2019-03-28 15:39:46 +0000'
created:'2018-09-26 15:39:46 +0000'
sessionOnly:FALSE
domain:.google.com
partition:none
sameSite:none
path:/
isSecure:FALSE
isHTTPOnly: YES
path:"/" isSecure:FALSE isHTTPOnly: YES>]
Cookies after deletion: []
Run Code Online (Sandbox Code Playgroud)
URLSessionConfiguration
还有一个属性httpCookieAcceptPolicy
,引用如下:
此属性根据此配置确定会话中所有任务的cookie接受策略.
默认值为HTTPCookie.AcceptPolicy.onlyFromMainDocumentDomain.您可以将其更改为HTTPCookie.AcceptPolicy枚举类型中定义的任何常量.
如果您想要更直接地控制接受哪些cookie,请将此值设置为HTTPCookie.AcceptPolicy.never,然后使用allHeaderFields和cookies(withResponseHeaderFields:for :)方法自行从URL响应对象中提取cookie.
因此,如果您希望自己操作cookie,可以设置httpCookieAcceptPolicy
为never
.
下面的代码显示,从不使用httpCookieAcceptPolicy时,不存储cookie
var cookies = readCookie(forURL: googleURL)
print("Cookies before request: ", cookies)
executeURLRequest(url: googleURL, inSession: customSession) { result in
if case .success (let data) = result {
cookies = readCookie(forURL: googleURL)
print("Cookies after request: ", cookies)
}
}
Run Code Online (Sandbox Code Playgroud)
记录以下内容;
Cookies before request: []
Cookies after request: []
Run Code Online (Sandbox Code Playgroud)
您可以看到使用.never for httpCookieStoragePolicy,系统不会将cookie存储到共享cookie存储.
你也可以自己存储cookie,看起来像这样,
自己存储cookie
deleteCookies(forURL: googleURL)
var cookies = readCookie(forURL: googleURL)
print("Cookies before request: ", cookies)
executeURLRequest(url: googleURL, inSession: customSession) { result in
if case let .success (response, data) = result {
guard let cookiesResponseHeader = response.allHeaderFields["Set-Cookie"] else {
return
}
cookies = readCookie(forURL: googleURL)
print("Cookies after request: ", cookies)
let responseCookies = HTTPCookie.cookies(withResponseHeaderFields: response.allHeaderFields as! [String: String], for: googleURL)
storeCookies(responseCookies, forURL: googleURL)
cookies = readCookie(forURL: googleURL)
print("Cookies after storing: ", cookies)
}
}
Run Code Online (Sandbox Code Playgroud)
而且,这是上面的代码打印到控制台,
Cookies before request: []
Cookies after request: []
Cookies after storing: [<NSHTTPCookie
version:0
name:1P_JAR
value:2018-09-26-18
expiresDate:'2018-10-26 18:35:23 +0000'
created:'2018-09-26 18:35:23 +0000'
sessionOnly:FALSE
domain:.google.com
partition:none
sameSite:none
path:/
isSecure:FALSE
path:"/" isSecure:FALSE>, <NSHTTPCookie
version:0
name:NID
value:139=D7GTUazWfeaB5Bcu1wN5I_Il2k6xALNiRZDX_DN9totQbnrP31gE0GzlsjCHDISUv8ulPq9G8Yu1p-GsZcVRw2fnrBROih-vtAVBic5UXFKUkG_ZbFQYKFprr4MPHDGS
expiresDate:'2019-03-28 18:35:23 +0000'
created:'2018-09-26 18:35:23 +0000'
sessionOnly:FALSE
domain:.google.com
partition:none
sameSite:none
path:/
isSecure:FALSE
isHTTPOnly: YES
path:"/" isSecure:FALSE isHTTPOnly: YES>]
Run Code Online (Sandbox Code Playgroud)
上面的代码使用.never
HTTPCookieAcceptPolicy来进行URLSessionConfiguration,但是我们从响应中创建cookie并将它们自己存储到cookie存储中.
归档时间: |
|
查看次数: |
25096 次 |
最近记录: |