2014-10-23 5 views
8

Я пытаюсь сделать мой экземпляр менеджера Alamofire автоматически запоминает & набор печенья, вот моя неудачная попытка:Помня печенье с Alamofire

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=/ заголовок, а затем перенаправляет (302) в /cookies (эквивалент второго URL); это отлично работает в моем браузере (как только я ударил первый URL, второй URL-адрес всегда отображает этот файл cookie), поэтому я хотел бы воспроизвести это поведение с помощью Alamofire.

+1

Пробовали ли вы предоставление печенье самостоятельно, используя 'HTTPAdditionalHeaders'and добавления заголовка Cookie в' NSURLSessionConfiguration'? – Pintouch

+0

@Pintouch Я уверен, что это сработает, но я бы хотел использовать уже существующие функции хранения файлов cookie, а не отслеживать файлы cookie и вручную настраивать заголовок. –

+1

Да, я понимаю, но ваш код выглядит хорошо для меня. Попробуйте открыть проблему в решении проблемы с AlamoFire GitHub – Pintouch

ответ

18

Ваш код работает нормально - вы просто не принимаете во внимание, что вы вызываете асинхронные методы при выполнении запроса. Когда этот код выполняется, это то, что происходит - каждый вызов 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() 
    } 
} 
+0

Сохраняет ли Almofire и отправляет файлы cookie автоматически сейчас? –

Смежные вопросы