Reputation: 1072
I'm trying to create a function which returns an NSDictionary, which on its turn needs to be returned from a closure.
I'm relatively new to Swift and I'm having problems figuring this one out. Any help would be greatly appreciated.
// Takes a String, needs to return a NSDictionary
func login(action: String) -> NSDictionary
{
let command = NSURL(string: "\(connectionType)://\(url)/includes/api.php?username=\(username)&password=\(password)&accesskey=\(apiKey)&action=\(action)&responsetype=json")
print(command!)
let session = NSURLSession.sharedSession()
// Get error here when changing Void > NSDictionary
let task = session.dataTaskWithURL(command!) {
(data, response, error) -> Void in
if error != nil {
print(error!.localizedDescription)
} else {
do {
let result = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as! NSDictionary
print(result) // Need this returned
} catch {
// handle error
print(error)
}
}
}
task.resume()
return result As! NSDictionary // returns empty, because of -> Void??
}
Upvotes: 1
Views: 748
Reputation: 13903
In your declaration of the closure's type
let task = session.dataTaskWithURL(command!) {
(data, response, error) -> Void in
/* closure body */
}
change the Void
to JSONObject
. But that's not all! You're trying to return something from a login function that makes an asynchronous call, and that's impossible. Instead, your login
function itself needs to take a closure, and that closure will be where you do something with the result NSDictionary
. So change your declaration of login
to
func login(action: String, completionHandler: (NSDictionary) -> ())
and implement the completionHandler
accordingly.
Upvotes: 2
Reputation: 11597
The problem is dataTaskWithURL
is an asynchronous function, therefore it hasnt got around to executing the block yet before it returns the function.
what you need to do is either setup a function that can be called on self
that will let self
know when the block has executed and can pass you the result, or setup a protocol with a delegate that you can call to notify of the result
also, the -> Void
inside the block is the return type of the block, you shouldnt really be returning anything inside that block anyway because nothing will actually happen with it since the parent function doesnt expect anything to be returned, hence why its Void
Upvotes: 2