使用Swift发送HTTP请求时出现问题

时间:2016-11-30 02:21:46

标签: swift http

我对Swift或网络开发完全陌生。我正在尝试将一些简单的东西放在一起查询URL:

我正在尝试编写一个简单的程序,其中我有三个按钮,每次点击一个按钮,我都会将数据发送到data.sparkfun.com数据流存储服务,它将存储我的变量“test_value”

我需要查询此网址:

http://data.sparkfun.com/input/XGyzWVyDdEFKDE42W99r?private_key=KEYVALUE&test_value=1"

以下是我在阅读一些简单的教程后尝试使用的代码失败:

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

@IBAction func ColorTwoTapped(_ sender: Any) {
    print("Color 2")
}

@IBAction func ColorOneTapped(_ sender: Any) {
    print("Color 1")

    let scriptUrl = "http://data.sparkfun.com/input/XGyzWVyDdEFKDE42W99r"

    let urlWithParams = scriptUrl + "?private_key=KEYVALUE&test_value=1"

    let myUrl = NSURL(string: urlWithParams);


    let task = URLSession.sharedSession().dataTaskWithURL(myUrl!) {(data, response, error) in
        print(String(data: data!, encoding: NSUTF8StringEncoding))
    }

    task.resume()


}

@IBAction func ColorThreeTapped(_ sender: Any) {
    print("Color 3")
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

我得到的错误是

Cannot call value of non-function type 'URLSession'. 

感谢您的任何建议

2 个答案:

答案 0 :(得分:1)

看起来您选择的教程是为Swift 2.x编写的,而您显然使用的是Swift 3.

在Swift 3中,方法是:

@IBAction func colorOneTapped(_ sender: Any) {
    print("Color 1")

    let scriptUrl = "http://data.sparkfun.com/input/XGyzWVyDdEFKDE42W99r"

    let urlWithParams = scriptUrl + "?private_key=KEYVALUE&test_value=1"

    let myUrl = URL(string: urlWithParams)

    let task = URLSession.shared.dataTask(with: myUrl!) { data, response, error in
        guard let data = data, error == nil else {
            print("\(error)")
            return
        }

        let string = String(data: data, encoding: .utf8)
        print("\(string)")
    }

    task.resume()
}

注意,它是URL,而不是NSURL。它是shared,而不是sharedSession()。同样,dataTaskWithURL(_:completionHandler:)现在是dataTask(with:completionHandler:)。我还建议避免!强制解包并使用可选绑定(例如if letguard let)。

注意,如果您要发送要存储在服务器上的数据,通常会使用POST

@IBAction func colorOneTapped(_ sender: Any) {
    print("Color 1")

    let urlString = "http://data.sparkfun.com/input/XGyzWVyDdEFKDE42W99r"

    let url = URL(string: urlString)
    var request = URLRequest(url: url!)
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.httpBody = "private_key=KEYVALUE&test_value=1".data(using: .utf8)
    request.httpMethod = "POST"

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {
            print("\(error)")
            return
        }

        let string = String(data: data, encoding: .utf8)
        print("\(string)")
    }

    task.resume()
}

请注意,此处还有大量其他小细节,例如,如果您要发送除a - z以外的任何内容,则需要对密钥和值进行百分比转义, A - Z0 - 9-._~(无论是在GET请求的网址或POST请求的正文中)。并且您经常设置Accept标头,让服务器知道您期望响应的形式,然后编写代码来解析这种响应。同样,如果您使用NSAppTransportSecurity而不是Info.plist,则需要在http中设置https

如果您不想在所有这些细节中迷失方向,您可能还想考虑使用Alamofire这样的内容。

答案 1 :(得分:0)

将URLSession替换为NSURLSession。使用警卫来检查数据是否为零。

pip install pyinstaller