我试图让我的 Alamofire 管理器实例自动记住并设置 cookie,这是我不成功的尝试:
let cfg = NSURLSessionConfiguration.defaultSessionConfiguration()
let cooks = NSHTTPCookieStorage.sharedHTTPCookieStorage()
// makes no difference whether it's set or left at default
cfg.HTTPCookieStorage = cooks
cfg.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicy.Always
let mgr = Alamofire.Manager(configuration: cfg)
mgr.request(NSURLRequest(URL: NSURL(string: "http://httpbin.org/cookies/set?stack=overflow"))).responseString {
(_, _, response, _) in
var resp = response // { "cookies": { "stack": "overflow" } }
// becomes empty if cfg.HTTPCookieStorage set to nil
}
mgr.request(NSURLRequest(URL: NSURL(string: "http://httpbin.org/cookies"))).responseString {
(_, _, response, _) in
var resp = response // { "cookies": {} }
// always empty no matter what
}
cooks.cookiesForURL(NSURL(string: "http://httpbin.org/cookies")) // 0 elements
第一个 URL 发送一个 Set-Cookie : stack=overflow; Path=/
header ,然后重定向 (302) 到 /cookies
(相当于第二个 URL);这在我的浏览器中运行良好(一旦我点击第一个 URL,第二个 URL 总是显示该 cookie)所以我想用 Alamofire 复制这种行为。
最佳答案
您的代码工作正常 - 您只是没有考虑到您在发出请求时正在调用异步方法。执行该代码时,会发生以下情况——每次调用 mgr.request(...)
都会启动一个新的异步调用,该调用直到上述所有代码执行完毕后才会解析:
| configure mgr
|
| request /cookies/set?... ----
| \
| request /cookies ---- |
| \ |
| cookiesForUrl() | |
| | |
| [function returns] | |
| |
...time passes... | |
/ |
/cookies handler ---- |
|
...more time... |
/
/cookies/set? handler -------
(最后两个处理程序的顺序不确定 - 取决于服务器/流量/等)
所以您对“http://httpbin.org/cookies”的请求实际上并不包含任何 cookie,因为设置 cookie 的请求只是在一个指令之前发送的。要查看 cookie,您需要等到第一个调用返回以发送下一个请求。我将东西包装在 UIViewController
子类中:
class CookieViewController: UIViewController {
// mgr needs to still exist when the response handlers are called
var mgr: Alamofire.Manager!
let cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage()
func configureManager() -> Alamofire.Manager {
let cfg = NSURLSessionConfiguration.defaultSessionConfiguration()
cfg.HTTPCookieStorage = cookies
return Alamofire.Manager(configuration: cfg)
}
func setCookies() {
mgr.request(NSURLRequest(URL: NSURL(string: "http://httpbin.org/cookies/set?stack=overflow")!)).responseString {
(_, _, response, _) in
var resp = response // { "cookies": { "stack": "overflow" } }
println(resp)
// the cookies are now a part of the URLSession -
// we can inspect them and call the next URL
println(self.cookies.cookiesForURL(NSURL(string: "http://httpbin.org/cookies")!))
self.checkCookies()
}
}
func checkCookies() {
mgr.request(NSURLRequest(URL: NSURL(string: "http://httpbin.org/cookies")!)).responseString {
(_, _, response, _) in
var resp = response // { "cookies": { "stack": "overflow" } }
println(resp)
}
}
override func viewDidLoad() {
super.viewDidLoad()
mgr = configureManager()
setCookies()
}
}
关于swift - 用 Alamofire 记住 cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26537075/