swift - 用 Alamofire 记住 cookie

标签 swift alamofire

我试图让我的 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/

相关文章:

ios - UICollectionView numberOfItemsInSection 被调用两次

swift - 在 Alamofire 请求中使用 validate() 时如何处理错误?

ios - Alamofire 不会在 podfile 中使用 osx 而不是 ios

ios - GID didSignInFor 实际在哪里登录了用户?

arrays - 从字典数组中删除重复的字典

swift - 在使用断点 Swift 时查找变量的值

json - Swift:如何从 JSON 数据读取 JSON 数据

swift - 在 API 调用期间从服务器获取错误消息

iOS - Alamofire RequestRetrier 未被激发

swift - 在框架内创建框架