【问题标题】:How to get cookie from a NSURLSession with Swift?如何使用 Swift 从 NSURLSession 获取 cookie?
【发布时间】:2015-06-18 05:24:18
【问题描述】:

我有一个 NSURLSession 调用 dataTaskWithRequest 以便以这种方式发送 POST 请求

func makeRequest(parameters: String, url:String){
    var postData:NSData = parameters.dataUsingEncoding(NSASCIIStringEncoding)!
    var postLength:NSString = String(postData.length )
    var request = NSMutableURLRequest(URL: NSURL(string: url)!)
    var session = NSURLSession.sharedSession()
    request.HTTPMethod = "POST"

    var error:NSError?
    //request.HTTPBody = NSJSONSerialization.dataWithJSONObject(postData, options: nil, error: &error)
    request.HTTPBody = postData
    request.setValue(postLength, forHTTPHeaderField: "Content-Length")
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json", forHTTPHeaderField: "Accept")

    var task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in

        println("Response:\(response)")

        // Other stuff goes here

})

响应等于:

<NSHTTPURLResponse: 0x7fcd205d0a00> { URL: http://XXX.XXX.XXX:0000/*** } { status code: 200, headers {
    "Cache-Control" = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
    Connection = close;
    "Content-Length" = 16;
    "Content-Type" = "application/json; charset=utf-8";
    Date = "Mon, 13 Apr 2015 00:07:29 GMT";
    Expires = "Thu, 19 Nov 1981 08:52:00 GMT";
    Pragma = "no-cache";
    Server = "Apache/2.2.15 (CentOS)";
    "Set-Cookie" = "MYCOOKIEIS=12dsada342fdshsve4lorewcwd234; path=/";
    "X-Powered-By" = "PHP/5.3.14 ZendServer/5.0";
} }

我的问题是我不知道如何获取“Set-Cookie”中名为 MYCOOKIEIS 的 cookie。

我将在用户登录时使用它,所以如果用户未登录 -> 登录(调用登录 api)否则转到主屏幕并调用其他 API。

有人可以帮我把 cookie 拿出来吗?

我找到了这个answer,但它是在 Objective-C 中的,我不知道如何使用 Swift 来实现

【问题讨论】:

    标签: json swift cookies nsurlsession setcookie


    【解决方案1】:

    Swift 版本可能类似于:

    let task = session.dataTask(with: request) { data, response, error in
        guard
            let url = response?.url,
            let httpResponse = response as? HTTPURLResponse,
            let fields = httpResponse.allHeaderFields as? [String: String]
        else { return }
    
        let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields, for: url)
        HTTPCookieStorage.shared.setCookies(cookies, for: url, mainDocumentURL: nil)
        for cookie in cookies {
            var cookieProperties = [HTTPCookiePropertyKey: Any]()
            cookieProperties[.name] = cookie.name
            cookieProperties[.value] = cookie.value
            cookieProperties[.domain] = cookie.domain
            cookieProperties[.path] = cookie.path
            cookieProperties[.version] = cookie.version
            cookieProperties[.expires] = Date().addingTimeInterval(31536000)
    
            let newCookie = HTTPCookie(properties: cookieProperties)
            HTTPCookieStorage.shared.setCookie(newCookie!)
    
            print("name: \(cookie.name) value: \(cookie.value)")
        }
    }
    task.resume()
    

    【讨论】:

    • 在执行某种“注销”时不要忘记删除 cookie。检查下面的@Mellian 回复
    • 请记住,有些 cookie 不会出现在 httpResponse.allHeaderFields 下。您将不得不使用 iOS 提供的共享 cookie 存储。
    • 我明白了,但是如果我想在运行任务之前设置一个 cookie 值,例如 JSESSIONID,该怎么办?
    • 拯救了我的一周。非常感谢
    【解决方案2】:

    我遇到了同样的问题:这会获取、设置或删除 cookie:

    func showCookies() {
    
        let cookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
        //println("policy: \(cookieStorage.cookieAcceptPolicy.rawValue)")
    
        let cookies = cookieStorage.cookies as! [NSHTTPCookie]
        println("Cookies.count: \(cookies.count)")
        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] = cookie.expiresDate
            cookieProperties[NSHTTPCookieSecure] = cookie.secure
    
            // Setting a Cookie
            if let newCookie = NSHTTPCookie(properties: cookieProperties) {
                // Made a copy of cookie (cookie can't be set)
                println("Newcookie: \(newCookie)")
                NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(newCookie)
            }
            println("ORGcookie: \(cookie)")
        }
    }
    
    func deleteCookies() {
    
        let cookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
        let cookies = cookieStorage.cookies as! [NSHTTPCookie]
        println("Cookies.count: \(cookies.count)")
        for cookie in cookies {
            println("name: \(cookie.name) value: \(cookie.value)")
            NSHTTPCookieStorage.sharedHTTPCookieStorage().deleteCookie(cookie)
        }
    
        //Create newCookie: You need all properties, because else newCookie will be nil (propertie are then invalid)
        var cookieProperties = [String: AnyObject]()
        cookieProperties[NSHTTPCookieName] = "locale"
        cookieProperties[NSHTTPCookieValue] = "nl_NL"
        cookieProperties[NSHTTPCookieDomain] = "www.digitaallogboek.nl"
        cookieProperties[NSHTTPCookiePath] = "/"
        cookieProperties[NSHTTPCookieVersion] = NSNumber(integer: 0)
        cookieProperties[NSHTTPCookieExpires] = NSDate().dateByAddingTimeInterval(31536000)
        var newCookie = NSHTTPCookie(properties: cookieProperties)
        println("\(newCookie)")
        NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(newCookie!)
    }
    

    【讨论】:

      【解决方案3】:

      请参阅上面的答案,但对于 Swift 3,您需要这样的内容:

          var cookieProperties = [HTTPCookiePropertyKey:Any]()
      
          cookieProperties[HTTPCookiePropertyKey.name] = "foo"
          cookieProperties[HTTPCookiePropertyKey.value] = "bar"
          cookieProperties[HTTPCookiePropertyKey.path] = "baz"
          cookieProperties[HTTPCookiePropertyKey.domain] = ".example.com"
      
          let cookie = HTTPCookie(properties: cookieProperties)
      

      【讨论】:

        【解决方案4】:

        试试这个代码:

        guard let realResponse = response as? HTTPURLResponse, realResponse.statusCode == 200 else {
            print("Not a 200 response")
            return
        }
        
        let fields = realResponse.allHeaderFields as? [String :String]
        
        if let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields!, for: response!.url!) {
            for cookie in cookies {
                print("name: \(cookie.name) value: \(cookie.value)")
            }
        }
        

        【讨论】:

          【解决方案5】:

          Swift 3/4,简洁的解决方案:

          let cookieName = "MYCOOKIE"
          if let cookie = HTTPCookieStorage.shared.cookies?.first(where: { $0.name == cookieName }) {
              debugPrint("\(cookieName): \(cookie.value)")
          }
          

          【讨论】:

          • 谢谢,简单易行!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-06
          • 1970-01-01
          • 1970-01-01
          • 2015-10-26
          • 1970-01-01
          • 2018-07-01
          相关资源
          最近更新 更多