如何使用 Swift 从 NSURLSession 获取 cookie?
How to get cookie from a NSURLSession with Swift?
我有一个调用 dataTaskWithRequest 的 NSURLSession 以便以这种方式发送 POST 请求
func makeRequest(parameters: String, url:String){
var postData:NSData = parameters.dataUsingEncoding(NSASCIIStringEncoding)!
var postLength:NSString = String(postData.length )
var request = NSMutableURLRequest(URL: NSURL(string: url)!)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var error:NSError?
//request.HTTPBody = NSJSONSerialization.dataWithJSONObject(postData, options: nil, error: &error)
request.HTTPBody = postData
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
println("Response:\(response)")
// Other stuff goes here
})
响应等于:
<NSHTTPURLResponse: 0x7fcd205d0a00> { URL: http://XXX.XXX.XXX:0000/*** } { status code: 200, headers {
"Cache-Control" = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
Connection = close;
"Content-Length" = 16;
"Content-Type" = "application/json; charset=utf-8";
Date = "Mon, 13 Apr 2015 00:07:29 GMT";
Expires = "Thu, 19 Nov 1981 08:52:00 GMT";
Pragma = "no-cache";
Server = "Apache/2.2.15 (CentOS)";
"Set-Cookie" = "MYCOOKIEIS=12dsada342fdshsve4lorewcwd234; path=/";
"X-Powered-By" = "PHP/5.3.14 ZendServer/5.0";
} }
我的问题是我不知道如何获取 "Set-Cookie" 中名为 MYCOOKIEIS 的 cookie。
我会在用户登录时使用它,所以如果用户未登录 -> 登录(调用登录 api)否则转到主屏幕并调用其他 API。
有人可以帮我把饼干拿出来吗?
我找到了这个 answer 但它在 Objective-C 中,我不知道如何使用 Swift
Swift 再现可能类似于:
let task = session.dataTask(with: request) { data, response, error in
guard
let url = response?.url,
let httpResponse = response as? HTTPURLResponse,
let fields = httpResponse.allHeaderFields as? [String: String]
else { return }
let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields, for: url)
HTTPCookieStorage.shared.setCookies(cookies, for: url, mainDocumentURL: nil)
for cookie in cookies {
var cookieProperties = [HTTPCookiePropertyKey: Any]()
cookieProperties[.name] = cookie.name
cookieProperties[.value] = cookie.value
cookieProperties[.domain] = cookie.domain
cookieProperties[.path] = cookie.path
cookieProperties[.version] = cookie.version
cookieProperties[.expires] = Date().addingTimeInterval(31536000)
let newCookie = HTTPCookie(properties: cookieProperties)
HTTPCookieStorage.shared.setCookie(newCookie!)
print("name: \(cookie.name) value: \(cookie.value)")
}
}
task.resume()
我遇到了同样的问题:获取、设置或删除 cookie:
func showCookies() {
let cookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
//println("policy: \(cookieStorage.cookieAcceptPolicy.rawValue)")
let cookies = cookieStorage.cookies as! [NSHTTPCookie]
println("Cookies.count: \(cookies.count)")
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] = cookie.expiresDate
cookieProperties[NSHTTPCookieSecure] = cookie.secure
// Setting a Cookie
if let newCookie = NSHTTPCookie(properties: cookieProperties) {
// Made a copy of cookie (cookie can't be set)
println("Newcookie: \(newCookie)")
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(newCookie)
}
println("ORGcookie: \(cookie)")
}
}
func deleteCookies() {
let cookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
let cookies = cookieStorage.cookies as! [NSHTTPCookie]
println("Cookies.count: \(cookies.count)")
for cookie in cookies {
println("name: \(cookie.name) value: \(cookie.value)")
NSHTTPCookieStorage.sharedHTTPCookieStorage().deleteCookie(cookie)
}
//Create newCookie: You need all properties, because else newCookie will be nil (propertie are then invalid)
var cookieProperties = [String: AnyObject]()
cookieProperties[NSHTTPCookieName] = "locale"
cookieProperties[NSHTTPCookieValue] = "nl_NL"
cookieProperties[NSHTTPCookieDomain] = "www.digitaallogboek.nl"
cookieProperties[NSHTTPCookiePath] = "/"
cookieProperties[NSHTTPCookieVersion] = NSNumber(integer: 0)
cookieProperties[NSHTTPCookieExpires] = NSDate().dateByAddingTimeInterval(31536000)
var newCookie = NSHTTPCookie(properties: cookieProperties)
println("\(newCookie)")
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(newCookie!)
}
请参阅以上答案,但对于 Swift 3,您需要这样的答案:
var cookieProperties = [HTTPCookiePropertyKey:Any]()
cookieProperties[HTTPCookiePropertyKey.name] = "foo"
cookieProperties[HTTPCookiePropertyKey.value] = "bar"
cookieProperties[HTTPCookiePropertyKey.path] = "baz"
cookieProperties[HTTPCookiePropertyKey.domain] = ".example.com"
let cookie = HTTPCookie(properties: cookieProperties)
试试这个代码:
guard let realResponse = response as? HTTPURLResponse, realResponse.statusCode == 200 else {
print("Not a 200 response")
return
}
let fields = realResponse.allHeaderFields as? [String :String]
if let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields!, for: response!.url!) {
for cookie in cookies {
print("name: \(cookie.name) value: \(cookie.value)")
}
}
Swift 3/4,简明解法:
let cookieName = "MYCOOKIE"
if let cookie = HTTPCookieStorage.shared.cookies?.first(where: { [=10=].name == cookieName }) {
debugPrint("\(cookieName): \(cookie.value)")
}
我有一个调用 dataTaskWithRequest 的 NSURLSession 以便以这种方式发送 POST 请求
func makeRequest(parameters: String, url:String){
var postData:NSData = parameters.dataUsingEncoding(NSASCIIStringEncoding)!
var postLength:NSString = String(postData.length )
var request = NSMutableURLRequest(URL: NSURL(string: url)!)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var error:NSError?
//request.HTTPBody = NSJSONSerialization.dataWithJSONObject(postData, options: nil, error: &error)
request.HTTPBody = postData
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
println("Response:\(response)")
// Other stuff goes here
})
响应等于:
<NSHTTPURLResponse: 0x7fcd205d0a00> { URL: http://XXX.XXX.XXX:0000/*** } { status code: 200, headers {
"Cache-Control" = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
Connection = close;
"Content-Length" = 16;
"Content-Type" = "application/json; charset=utf-8";
Date = "Mon, 13 Apr 2015 00:07:29 GMT";
Expires = "Thu, 19 Nov 1981 08:52:00 GMT";
Pragma = "no-cache";
Server = "Apache/2.2.15 (CentOS)";
"Set-Cookie" = "MYCOOKIEIS=12dsada342fdshsve4lorewcwd234; path=/";
"X-Powered-By" = "PHP/5.3.14 ZendServer/5.0";
} }
我的问题是我不知道如何获取 "Set-Cookie" 中名为 MYCOOKIEIS 的 cookie。
我会在用户登录时使用它,所以如果用户未登录 -> 登录(调用登录 api)否则转到主屏幕并调用其他 API。
有人可以帮我把饼干拿出来吗?
我找到了这个 answer 但它在 Objective-C 中,我不知道如何使用 Swift
Swift 再现可能类似于:
let task = session.dataTask(with: request) { data, response, error in
guard
let url = response?.url,
let httpResponse = response as? HTTPURLResponse,
let fields = httpResponse.allHeaderFields as? [String: String]
else { return }
let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields, for: url)
HTTPCookieStorage.shared.setCookies(cookies, for: url, mainDocumentURL: nil)
for cookie in cookies {
var cookieProperties = [HTTPCookiePropertyKey: Any]()
cookieProperties[.name] = cookie.name
cookieProperties[.value] = cookie.value
cookieProperties[.domain] = cookie.domain
cookieProperties[.path] = cookie.path
cookieProperties[.version] = cookie.version
cookieProperties[.expires] = Date().addingTimeInterval(31536000)
let newCookie = HTTPCookie(properties: cookieProperties)
HTTPCookieStorage.shared.setCookie(newCookie!)
print("name: \(cookie.name) value: \(cookie.value)")
}
}
task.resume()
我遇到了同样的问题:获取、设置或删除 cookie:
func showCookies() {
let cookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
//println("policy: \(cookieStorage.cookieAcceptPolicy.rawValue)")
let cookies = cookieStorage.cookies as! [NSHTTPCookie]
println("Cookies.count: \(cookies.count)")
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] = cookie.expiresDate
cookieProperties[NSHTTPCookieSecure] = cookie.secure
// Setting a Cookie
if let newCookie = NSHTTPCookie(properties: cookieProperties) {
// Made a copy of cookie (cookie can't be set)
println("Newcookie: \(newCookie)")
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(newCookie)
}
println("ORGcookie: \(cookie)")
}
}
func deleteCookies() {
let cookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
let cookies = cookieStorage.cookies as! [NSHTTPCookie]
println("Cookies.count: \(cookies.count)")
for cookie in cookies {
println("name: \(cookie.name) value: \(cookie.value)")
NSHTTPCookieStorage.sharedHTTPCookieStorage().deleteCookie(cookie)
}
//Create newCookie: You need all properties, because else newCookie will be nil (propertie are then invalid)
var cookieProperties = [String: AnyObject]()
cookieProperties[NSHTTPCookieName] = "locale"
cookieProperties[NSHTTPCookieValue] = "nl_NL"
cookieProperties[NSHTTPCookieDomain] = "www.digitaallogboek.nl"
cookieProperties[NSHTTPCookiePath] = "/"
cookieProperties[NSHTTPCookieVersion] = NSNumber(integer: 0)
cookieProperties[NSHTTPCookieExpires] = NSDate().dateByAddingTimeInterval(31536000)
var newCookie = NSHTTPCookie(properties: cookieProperties)
println("\(newCookie)")
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(newCookie!)
}
请参阅以上答案,但对于 Swift 3,您需要这样的答案:
var cookieProperties = [HTTPCookiePropertyKey:Any]()
cookieProperties[HTTPCookiePropertyKey.name] = "foo"
cookieProperties[HTTPCookiePropertyKey.value] = "bar"
cookieProperties[HTTPCookiePropertyKey.path] = "baz"
cookieProperties[HTTPCookiePropertyKey.domain] = ".example.com"
let cookie = HTTPCookie(properties: cookieProperties)
试试这个代码:
guard let realResponse = response as? HTTPURLResponse, realResponse.statusCode == 200 else {
print("Not a 200 response")
return
}
let fields = realResponse.allHeaderFields as? [String :String]
if let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields!, for: response!.url!) {
for cookie in cookies {
print("name: \(cookie.name) value: \(cookie.value)")
}
}
Swift 3/4,简明解法:
let cookieName = "MYCOOKIE"
if let cookie = HTTPCookieStorage.shared.cookies?.first(where: { [=10=].name == cookieName }) {
debugPrint("\(cookieName): \(cookie.value)")
}