1

I have done some reading and there was recommendation in a similar post (Swift closure with Alamofire) and tried to do the same to my code but I can't find the way to call the function now?

I get an error of: Cannot convert the expression's type '(response: @lvalue String)' to type '((response: String) -> ()) -> ()'

import UIKit

class myClass101: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    var api_error: String = ""

    activityInd.startAnimating()

    call_api_function(response: api_error)

    activityInd.stopAnimating()

    if (api_error != "") {
        let alertController = UIAlertController(title: "Server Alert", message: "Could not connect to API!", preferredStyle: UIAlertControllerStyle.Alert)
        alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default,handler: nil))
        self.presentViewController(alertController, animated: true, completion: nil)
    }
  }
}

the function is as follows:

func call_api_function(completion: (response: String) -> ()) {

    let api_url_path: String = "http://\(str_api_server_ip):\(str_api_server_port)"
    let api_url = NSURL(string: api_url_path + "/devices.xml")!

    Alamofire.request(.GET, api_url)
        .authenticate(user: str_api_username, password: str_api_password)
        .validate(statusCode: 200..<300)
        .response { (request, response, data, error) in

            var senderror: String = error!.localizedDescription
            completion(response: senderror )

            if (error != nil) {

                println(senderror)
            }

            // do other tasks here

    }

}

Thanks!

Kostas

Community
  • 1
  • 1
Kostas
  • 367
  • 1
  • 3
  • 17

1 Answers1

2

Given your definition of call_api_function, you would call it like so:

call_api_function() { response in

    activityInd.stopAnimating()

    // now use `response` here
}

I'd suggest you do a little research on trailing closures in the The Swift Programming Language: Closures.


But, having said that, your call_api_function has problems of its own.

  • You're doing a forced unwrapping of the error optional. What if there was no error? Then, the forced unwrapping of the nil optional would fail and the code would crash.

  • If the request succeeded, you're not doing anything with the data that is returned. Presumably you did the request because you wanted to do something with the returned data.

    Unfortunately, you don't provide information about the nature of the XML response you're expecting, but presumably you would instantiate a NSXMLParser instance to parse it and then implement the NSXMLParserDelegate methods and call the parse method.

  • Following up on the prior points, rather than a closure with a single non-optional parameter, I'd expect to see a closure with two optional parameters, an optional with the parsed data (which would be set if the request and parsing was successful) and an optional with a NSError (which would be set only if there was an error).

  • A very minor point, but you might want to adopt a Cocoa naming conventions (e.g. camelCase convention of callApiFunction).

Community
  • 1
  • 1
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • By the way, [the answer to your other question](http://stackoverflow.com/a/27089820/1271826) shows an example of a closure with two parameters. Clearly, given that you're dealing with XML, you might want to parse it, too, but that other answer illustrates the idea of passing two parameters via the closure. – Rob Nov 23 '14 at 23:06