Swift NSURLSession NSURLRequest Cookies不被接受

时间:2015-07-12 15:34:26

标签: swift cookies login nsurlrequest nsurlsession

我是swift和OS X编程的新手。在我的第一步中,我想创建一个命令行工具,它将我登录到我的移动运营商的Web界面,然后显示我剩余的数据量。我开始围绕NSURLSession编写一个包装器,以便让我更轻松。

问题:我的程序不接受cookie。

我尝试了很多东西,还在会话对象上设置了cookie策略,但没有改变。如何让我的程序接受cookie以及如何在后续请求中使用它们?

HttpClient.swift:

import Foundation

class HttpClient {

    private var url: NSURL!
    private var session: NSURLSession

    internal init(url: String) {
        self.url = NSURL(string: url)
        self.session = NSURLSession.sharedSession()
        session.configuration.HTTPShouldSetCookies = true
        session.configuration.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicy.OnlyFromMainDocumentDomain
        session.configuration.HTTPCookieStorage?.cookieAcceptPolicy = NSHTTPCookieAcceptPolicy.OnlyFromMainDocumentDomain
    }

    internal func sendGet() -> String {
        var ready = false
        var content: String!
        var request = NSMutableURLRequest(URL: self.url)

        var task = session.dataTaskWithRequest(request) {
            (data, response, error) -> Void in
            content = NSString(data: data, encoding: NSASCIIStringEncoding) as! String
            ready = true
        }
        task.resume()
        while !ready {
            usleep(10)
        }
        if content != nil {
            return content
        } else {
            return ""
        }
    }

    internal func sendPost(params: String) -> String {
        var ready = false
        var content: String!
        var request = NSMutableURLRequest(URL: self.url)

        request.HTTPMethod = "POST"
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.HTTPBody = params.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)
        request.HTTPShouldHandleCookies = true

        var task = session.dataTaskWithRequest(request) {
            (data, response, error) -> Void in
            content = NSString(data: data, encoding: NSASCIIStringEncoding) as! String
            ready = true
        }
        task.resume()
        while !ready {
            usleep(10)
        }
        if content != nil {
            return content
        } else {
            return ""
        }
    }

    internal func setUrl(url: String) {
        self.url = NSURL(string: url)
    }
}

main.swift

import Foundation

let loginPage = "https://service.winsim.de/"
let dataPage = "https://service.winsim.de/mytariff/invoice/showGprsDataUsage"

var hc = HttpClient(url: loginPage)
println(hc.sendPost("usernameField=username&passwordfield=password"))
hc.setUrl(dataPage)
println(hc.sendGet())

1 个答案:

答案 0 :(得分:2)

问题已解决

事实上,上述代码接受cookie。我尝试登录到其他网站,但它确实有效。登录也持续存在。那么为什么它不能与我的运营商网站合作呢?

愚蠢的我,我的运营商有CSRF保护和其他隐藏的形式领域,我没有注意。因此,登录不起作用。现在我知道如何解决它。

对于任何有兴趣的人,我会发布我更新的HttpClient.swift文件,我希望它更整洁。

请随时评论我的代码并给我提示改进。

import Foundation

public class HttpClient {

    private var session: NSURLSession
    private var request: NSMutableURLRequest

    public init(url: String) {
        self.session = NSURLSession.sharedSession()
        session.configuration.HTTPShouldSetCookies = true
        session.configuration.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicy.OnlyFromMainDocumentDomain
        session.configuration.HTTPCookieStorage?.cookieAcceptPolicy = NSHTTPCookieAcceptPolicy.OnlyFromMainDocumentDomain
        self.request = NSMutableURLRequest(URL: NSURL(string: url)!)
    }

    public func send() -> String {
        var ready = false
        var content: String!

        var task = session.dataTaskWithRequest(self.request) {
            (data, response, error) -> Void in
            content = NSString(data: data, encoding: NSASCIIStringEncoding) as! String
            ready = true
        }
        task.resume()
        while !ready {
            usleep(10)
        }
        if content != nil {
            return content
        } else {
            return ""
        }
    }

    public func setUrl(url: String) -> HttpClient {
        self.request.URL = NSURL(string: url)
        return self
    }

    public func getMethod() -> String {
        return self.request.HTTPMethod
    }

    public func setMethod(method: String) -> HttpClient {
        self.request.HTTPMethod = method
        return self
    }

    public func addFormData(data: Dictionary<String, String>) -> HttpClient {
        var params: String = ""
        var ctHeader: String? = self.request.valueForHTTPHeaderField("Content-Type")
        let ctForm: String = "application/x-www-form-urlencoded"

        if(data.count > 0) {
            for(name, value) in data {
                params += name + "=" + value + "&"
            }

            params = params.substringToIndex(params.endIndex.predecessor())
            self.request.HTTPBody = params.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)

            if ctHeader != nil {
                self.request.setValue(ctForm, forHTTPHeaderField: "Content-Type")
            }
        }

        return self
    }

    public func removeFormData() -> HttpClient {
        self.request.setValue("text/html", forHTTPHeaderField: "Content-Type")
        self.request.HTTPBody = "".dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)

        return self
    }
}