1

I'm entirely new to development in Swift or networking. I'm trying to throw something simple together that query a URL:

I'm trying to write a simple program, where I have three buttons, and each time a button is tapped, I send data to the data.sparkfun.com data stream storing service where it will store my variable "test_value"

I need to query this URL:

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

Here is the code I'm trying to work with unsuccessfully after reading some simple tutorials:

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

The error I get is

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

Thanks for any advice

1
  • try NSURLSession? Commented Nov 30, 2016 at 2:25

2 Answers 2

1

It looks like the tutorial that you've selected was written for Swift 2.x, whereas you are apparently using Swift 3.

In Swift 3, the method would be:

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

Note, it's URL, not NSURL. And it's shared, not sharedSession(). Likewise dataTaskWithURL(_:completionHandler:) is now dataTask(with:completionHandler:). I'd also suggest avoiding ! forced unwrapping and use optional binding (e.g. if let or guard let).


Note, if you sending data to be stored on the server, you'd generally use 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()
}

Note, there are tons of other little details here, too, such as needing to percent-escape the keys and values if you'll be sending anything other than a-z, A-Z, 0-9 and -, ., _, or ~ (whether in the URL of GET request or in the body of the POST request). And you'd often set the Accept header to let the server know in what form you're expecting the response and then write the code to parse that sort of response. Likewise, you need to set the NSAppTransportSecurity in the Info.plist if you're using http rather than https.


You might also want to consider using something like Alamofire if you don't want to get too lost in all of these details.

Sign up to request clarification or add additional context in comments.

Comments

0

Replace URLSession with NSURLSession. use a guard to check if data is nil.

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

task.resume()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.