2015-07-16 20 views
9

Sto lavorando su un'applicazione di accesso. Dopo che la risposta di login ha avuto successo, torna con i dati dei cookie.
Come posso utilizzare/salvare questi dati per le mie future richieste?
Per cominciare sto cercando di salvarlo in NSHTTPCookieStorage. Ma anche questo non funziona.
metodo di login (parziale): MetodoSwift: Come ricordare i cookie per ulteriori richieste http

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() 

Salva 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())") 
      } 
     } 
    } 

Errore:

Cannot invoke 'cookiesWithResponseHeaderFields' with an argument list of type '([NSObject : AnyObject], forURL: NSURL)' 

risposta

15

Se ci si rende conto l'utilizzo del biscotto, la S erver deve inviare il set-cookie di intestazione in risposta alla richiesta del client.

https://en.wikipedia.org/wiki/HTTP_cookie#Setting_a_cookie

Se si utilizza NSURLSession e NSURLConfiguration con defaultConfiguration o backgroundSession, voi non è necessario apportare modifiche per salvare il cookie. Il sistema lo fa da solo.

Da NSURLSessionConfiguration, HTTPCookieStorage documentazione,

The cookie store for storing cookies within this session. This property determines the cookie storage object used by all tasks within sessions based on this configuration. To disable cookie storage, set this property to nil. For default and background sessions, the default value is the shared cookie storage object. For ephemeral sessions, the default value is a private cookie storage object that stores data in memory only, and is destroyed when you invalidate the session.

Così, ho fatto un piccolo esperimento per leggere il cookie di google.com e qui è come sembra,

private func setCookies(response: NSURLResponse) { 
     let cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookiesForURL(response.URL!) 
     print(cookies) 
    } 

    let request = NSURLRequest(URL: NSURL(string: "https://google.com")!) 

    configuration = NSURLSessionConfiguration.defaultSessionConfiguration() 

    session = NSURLSession(configuration: configuration) 

    let task = session.dataTaskWithRequest(request) { data, response, error -> Void in 
     if error == nil { 
      self.setCookies(response!) 
     } 
    } 
    task?.resume() 

Con che stampa il seguente,

Optional([<NSHTTPCookie version:0 name:"NID" value:"69=j740tX4kU9JCWniPgXmngbD9ANWpzntszGg7Becz8FXCImLiVc3FmoHKdV-iOdd_PSCQeuVecwK6cyNfMOEW0gSz96CMEthN5uPZrR0J03sUKFuoRg4fO5A2ybwY6U_K" expiresDate:2016-01-15 22:01:36 +0000 created:2015-07-16 22:01:36 +0000 sessionOnly:FALSE domain:".google.fi" path:"/" isSecure:FALSE>, <NSHTTPCookie version:0 name:"PREF" value:"ID=1111111111111111:FF=0:TM=1437084096:LM=1437084096:V=1:S=TOU92HOWgdBrA6yl" expiresDate:2017-07-15 22:01:36 +0000 created:2015-07-16 22:01:36 +0000 sessionOnly:FALSE domain:".google.fi" path:"/" isSecure:FALSE>]) 

NSURLSessionConfiguration dispone anche di un perty HTTPCookieAcceptPolicy, che cita quanto segue:

A policy constant that determines when cookies should be accepted. This property determines the cookie accept policy for all tasks within sessions based on this configuration. The default value is NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain. You can change it to any of the constants defined in the NSHTTPCookieAcceptPolicy enumerated type. If you want more direct control over what cookies are accepted, set this value to NSHTTPCookieAcceptPolicyNever and then use the allHeaderFields and cookiesWithResponseHeaderFields:forURL: methods to extract cookies from the URL response object yourself.

Quindi, si afferma che se vogliamo essere in grado di manipolare il cookie da noi stessi, dovremmo impostare il criterio per NSHTTPCookieAcceptPolicyNever e utilizzare le allHeaderFields metodo e cookiesWithResponseHeaderFields: forURL: per l'estrazione dei cookie e il salvataggio.

Ecco come lo faresti per questo esempio.

let request = NSURLRequest(URL: NSURL(string: "https://google.com")!) 

configuration = NSURLSessionConfiguration.defaultSessionConfiguration() 

configuration.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicy.Never 

session = NSURLSession(configuration: configuration) 

let task = session.dataTaskWithRequest(request) { data, response, error -> Void in 
    if error == nil { 
     self.setCookies(response!) 
    } 
} 
task?.resume() 

} 

private func setCookies(response: NSURLResponse) { 

    if let httpResponse = response as? NSHTTPURLResponse { 
     if let headerFields = httpResponse.allHeaderFields as? [String: String] { 
      let cookies = NSHTTPCookie.cookiesWithResponseHeaderFields(headerFields, forURL: response.URL!) 
      print(cookies) 
     } 
    } 
} 

Anche in questo caso, non è necessario impostare il cookie per l'archiviazione da soli. Si noti la documentazione di HTTPCookieStorage, si dice che l'utilizzo delle sessioni predefinite o in background utilizza sempre la memoria condivisa a meno che non si imposti nulla sulla proprietà HTTPCookieStorage o si imposti un altro spazio di archiviazione.

Quindi, se si accede semplicemente i biscotti di archiviazione di default, si ottengono tutti i cookie da sopra,

print(NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies) 

Sembra che è possibile definire il proprio stoccaggio di archiviazione personalizzato biscotto condiviso, che può essere utilizzato su estensioni e applicazioni con iOS 9.

Quindi, non penso sia davvero necessario impostare i cookie da soli poiché esiste già un meccanismo integrato per farlo, a meno che non sia necessario un controllo preciso sulle proprietà dei cookie.

+1

Posso solo invia la richiesta successiva con qualcosa come 'let request = NSURLRequest (URL: NSURL (stringa:" https://google.com/user ")!)'? –

1

class func cookiesWithResponseHeaderFields(_ headerFields: [String : String], forURL URL: NSURL) -> [NSHTTPCookie]

Nota che headerFields è [String: String] Dizionario e il compilatore si lamenta che si sta passando [NSObject: ANYOBJECT]

0

per il collegamento URLSession è possibile utilizzare questo (dopo aver ricevuto la prima risposta):

var cookies = URLSession.shared.configuration.httpCookieStorage?.cookies 

ed è possibile utilizzare questi cookie come questo:

var session = URLSession.self 
session.shared.configuration.httpCookieStorage?.setCookies(cookies, for: baseurl, mainDocumentURL: baseurl) 
    let task = session.shared.dataTask(with: url) 
Problemi correlati