Swift:如何记住进一步的http请求的cookie

我正在开发一个login应用程序。 成功的login响应返回cookie数据。
我如何使用/保存这些数据用于将来的请求?
对于初学者,我试图将其保存在NSHTTPCookieStorage 。 但是这也不起作用。
login方法(部分):

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

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

错误:

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

如果您意识到使用cookie,服务器必须发送标头set-cookie来响应客户端请求。

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

如果您使用NSURLSession和NSURLConfiguration与defaultConfiguration或backgroundSession,您不必做任何更改保存cookie。 系统本身就是这样做的。

从NSURLSessionConfiguration,HTTPCookieStorage文档,

用于在此会话中存储Cookie的Cookie存储。 此属性基于此configuration确定会话中的所有任务所使用的Cookie存储对象。 要禁用cookie存储,请将此属性设置为nil。 对于默认和后台会话,默认值是共享cookie存储对象。 对于临时会话,默认值是一个私人cookie存储对象,仅将数据存储在内存中,并在会话失效时被销毁。

所以,我做了一个小实验,从google.com上读取cookie,看起来如何,

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

用它打印以下内容,

 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还有一个属性HTTPCookieAcceptPolicy,它引用了以下内容:

决定何时应该接受Cookie的策略常量。 此属性根据此configuration确定会话内所有任务的Cookie接受策略。 默认值是NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain。 您可以将其更改为NSHTTPCookieAcceptPolicy枚举types中定义的任何常量。 如果您希望更直接地控制接受哪些cookie,请将此值设置为NSHTTPCookieAcceptPolicyNever,然后使用allHeaderFields和cookiesWithResponseHeaderFields:forURL:方法自行从URL响应对象提取cookie。

因此,如果我们希望能够通过我们自己来操作cookie,我们应该将策略设置为NSHTTPCookieAcceptPolicyNever,并使用allHeaderFields和cookiesWithResponseHeaderFields的方法:forURL:提取cookie并保存。

这里是你如何做这个例子。

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

即使这样,您也不需要自行将cookie设置为存储空间。 请注意HTTPCookieStorage文档,它说使用默认或后台会话总是使用共享存储,除非您将nil设置为HTTPCookieStorage属性或设置其他存储。

所以,如果你只是logging默认的存储cookies,你将从上面得到所有的cookies,

 print(NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies) 

似乎有可能定义您自己的自定义存储共享cookie存储,这可以在iOS 9的扩展和应用程序中使用。

所以,我不认为真的有必要自己设置cookie,因为已经有内置的机制可以这样做,除非您真的需要对cookie属性进行精确的控制。

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

请注意,headerFields是[string:string]字典和编译器抱怨你正在传递[NSObject:AnyObject]