Reputation: 41
I am new at Swift programming and I am getting an error on a "let task = URLSession. I have researched and found some of those errors but none of the answers worked for me. Here is my code and line 44 throws this error
import UIKit
class loginViewController: UIViewController {
@IBOutlet weak var userLoginTextField: UITextField!
@IBOutlet weak var userPasswordTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func loginButtonTapped(_ sender: Any) {
let user_login = userLoginTextField.text;
let user_passwd = userPasswordTextField.text;
if((user_passwd?.isEmpty)! || (user_passwd?.isEmpty)!) { return; }
//Send user data to server
let myUrl = NSURL(string: "https://www.pcpusa.net/legacy/iOS/userLogin.php");
var request = URLRequest(url: myUrl! as URL);
request.httpMethod = "POST";
let postString = "login=\(String(describing: user_login))&password=\(String(describing: user_passwd))";
request.httpBody = postString.data(using: String.Encoding.utf8);
**let task = URLSession.shared.dataTask(with: request){**
data,response,error in
if error != nil {
print("error=\(String(describing: error))")
return
}
var err: NSError?
var json = try JSONSerialization.JSONObjectWithData(data, options: .mutableContainers, error: &err) as? NSDictionary
if let parseJSON = json {
var resultValue:String = parseJSON["status"] as String!;
print("result: \(resultValue)")
if(resultValue=="Success")
{
//Login is successful
NSUserDefaults.standardUserDefaults().setBool(true, value(forKey: "isUserLoggedIn"));
NSUserDefaults.standardUserDefaults().synchronize();
self.dismissViewControllerAnimated(true, completion:nil);
}
}
}
task.resume()
}
}
Upvotes: 1
Views: 1604
Reputation: 56635
URLSession.dataTask
expects a non-throwing completion handler and you are passing it a closure that throws. Because of this it fails to infer the method (in other words: it can’t find a method with that name that accepts a closure that throws).
To solve this you should catch and handle the errors that can happen when you decode the JSON.
Upvotes: 3
Reputation: 911
The key to that error message is "throwing function type". In Swift, whether or not a function can throw an error is part of its method signature. URLSession
is expecting a closure/function that will not throw an error.
Therefore, if you throw an error, you must catch it.
So, you basically have two options here:
try
in a do-try-catch
block.Example of option 1:
var json: [String: Any]!
do {
json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String: Any]
} catch let error { // `let error` is optional. It is the default.
// Handle error here
}
Example of option 2:
(Also, I suggest using the guard
statement for situations like this. This is my preferred method most of the time, and is considered by many to be more "Swifty")
let task = URLSession.shared.dataTask(with: request) {
data,response,error in
guard error != nil else {
print("error=\(String(describing: error))")
return
}
guard
let data = data,
let jsonObject = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers),
let json = jsonObject as? [String: Any]
else {
print("Could not parse JSON")
return
}
if let status = json["status"] as? String {
print(status)
}
}
EDIT: Adds surrounding context to option 2.
More on guard
. It basically acts as an inside-out if-else
statement.
You can use guard
to test regular booleans. Or, like if
, you can combine it with let
to make a guard-let
statement.
The difference between the two is:
if-let
when you say, "If this exists, I'll do something with it. Then I'll continue."guard-let
when you say, "If I don't have this thing, then I can't continue".Because of this, you must stop your function in its else
statement, usually by returning or throwing an error (which you can't do here).
Upvotes: 1
Reputation: 1826
The problem is you try
to decode (which can throw). Since you don't catch anywhere URLSession.dataTask
complains because it doesn't expect that closure to throw. (If a method or closure can throw it will be marked with the throws
keyword, this is an Apple provided method that does not have that keyword)
You just need to wrap in a do
catch
like so:
let task = URLSession.shared.dataTask(with: request){ (data,response,error) in
if error != nil {
print("error=\(String(describing: error))")
return
}
var err: NSError?
do {
var json = try JSONSerialization.JSONObjectWithData(data, options: .mutableContainers, error: &err) as? NSDictionary
if let parseJSON = json {
var resultValue:String = parseJSON["status"] as String!;
print("result: \(resultValue)")
...
} catch {
//print("Error: unable to serialize data: \(err)")
}
}
Upvotes: 0