Call can throw, but it is not marked with 'try' and the error is not handled
SwiftyJSON's JSON(data:)
can throw an exception so you have to mark it with try
.
Strict solution:
.map { (data) in
do {
return try JSON(data: data)
}
catch {
fatalError("unable to convert data to JSON")
}
}
Loose solution:
.compactMap { try? JSON(data: $0) }
swiftyjson - Call can throw, but it is marked with 'try' and the error is not handled
You should wrap it into a do-catch
block. In your case:
do {
let session = URLSession.shared.dataTask(with: url) {
(data, response, error) in
guard let data = data else {
print ("data was nil?")
return
}
let json = JSON(data: data)
print(json)
}
} catch let error as NSError {
// error
}
IOS: Call can throw, but is not marked with 'try' and the error is not handled
What you want to do is the following.
var json: [AnyHashable:Any]?
do {
json = try JSON(data: data)
} catch _ {
json = nil
}
What xcode is trying to say is that calling the JSON(data: data)
can throw an error and you should put it inside a try-catch
Call can throw, but it is not marked with 'try' and the error is not handled / Initializer for conditional binding must have Optional type, not 'JSON'
It would seem that the JSON
initialiser throws
, so the compiler is telling you you need to handle this.
You are also trying to access local variables declare in the .success
code block outside of that block, so they are unknown. You also have the wrong name for the id
variable.
AF.request(URL_USER_ADD, method: .post, parameters: body, encoding: JSONEncoding.default, headers: header).responseJSON { (response) in
switch response.result {
case .success(let result):
if let json = result as? Data {
guard let data = response.data else { return }
do {
let json = try JSON(data: data)
let id = json["_id"].stringValue
let color = json["avatarColor"].stringValue
let avatarName = json["avatarName"].stringValue
let email = json["email"].stringValue
let name = json["name"].stringValue
UserDataService.instance.setUserData(id: id, color: avatarColor, avatarName: avatarName, email: email, name: name)
completion(true)
} catch {
print(error)
completion(false)
}
}
case .failure(let result):
completion(false)
debugPrint(response.result as Any)
}
}
}
}
As a point of style, a completion handler that simply returns true
or false
isn't particularly useful as it doesn't provide any information on what went wrong when false
is returned, but since you mention a lesson, I will assume that this isn't your design choice.
Error Call can throw, but is not marked with 'try' and the error is not handled
Swift 2.0 introduces error handling. The error indicates that logInWithUsername:password:
can potentially throw an error, and you must do something with that error. You have one of a few options:
Mark your checkUserCredentials()
functional as throws
and propagate the error to the caller:
func checkUserCredentials() throws -> Bool {
try PFUser.logInWithUsername(userName!, password: password!)
if (PFUser.currentUser() != nil) {
return true
}
return false
}
Use do
/catch
syntax to catch the potential error:
func checkUserCredentials() -> Bool {
do {
try PFUser.logInWithUsername(userName!, password: password!)
}
catch _ {
// Error handling
}
if (PFUser.currentUser() != nil) {
return true
}
return false
}
Use the try!
keyword to have the program trap if an error is thrown, this is only appropriate if you know for a fact the function will never throw given the current circumstances - similar to using !
to force unwrap an optional (seems unlikely given the method name):
func checkUserCredentials() -> Bool {
try! PFUser.logInWithUsername(userName!, password: password!)
if (PFUser.currentUser() != nil) {
return true
}
return false
}
Swift 2: Call can throw, but it is not marked with 'try' and the error is not handled
You have to catch the error just as you're already doing for your save()
call and since you're handling multiple errors here, you can try
multiple calls sequentially in a single do-catch block, like so:
func deleteAccountDetail() {
let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
let request = NSFetchRequest()
request.entity = entityDescription
do {
let fetchedEntities = try self.Context!.executeFetchRequest(request) as! [AccountDetail]
for entity in fetchedEntities {
self.Context!.deleteObject(entity)
}
try self.Context!.save()
} catch {
print(error)
}
}
Or as @bames53 pointed out in the comments below, it is often better practice not to catch the error where it was thrown. You can mark the method as throws
then try
to call the method. For example:
func deleteAccountDetail() throws {
let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
let request = NSFetchRequest()
request.entity = entityDescription
let fetchedEntities = try Context.executeFetchRequest(request) as! [AccountDetail]
for entity in fetchedEntities {
self.Context!.deleteObject(entity)
}
try self.Context!.save()
}
Swift Call can throw, but it is not marked with 'try' and the error is not handled
In order to use the copyItemAtURL
function, you can do one of three things.
1) Try/catch
do {
try NSFileManager.defaultManager.copyItemAtURL(sourceSqliteURLs[index], toURL: destSqliteURLs[index])
} catch {
print(error)
}
This is the standard error handling method. All your code would go inside the do
block, including your try
statement, and any errors would be handled in the catch
block.
2) try!
try! NSFileManager.defaultManager()...
If an error is thrown with try!
it will cause a runtime crash.
3) try?
try? NSFileManager.defaultManager()...
Either the call will succeed or the result of the call will be nil. No errors thrown, no crash.
I would recommend you read the documentation, it's quite explicit about all this.
Swift: Extra argument 'error' in call
With Swift 2, the signature for NSJSONSerialization
has changed, to conform to the new error handling system.
Here's an example of how to use it:
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary {
print(jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}
With Swift 3, the name of NSJSONSerialization
and its methods have changed, according to the Swift API Design Guidelines.
Here's the same example:
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data, options: []) as? [String:AnyObject] {
print(jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}
Related Topics
Cannot Invoke 'Join' with an Argument List of Type (String, [String]) in Swift 2.0
How to Cache Images Using Urlsession in Swift
Higher Order Function: "Cannot Invoke 'Map' with an Argument List of Type '((_) -> _)'"
Initialize Lazy Instance Variable with Value That Depends on Other Instance Variables
Swift - Firebase Search in Database
Swiftui Hide Tabbar in Subview
Write and Read a Plist in Swift with Simple Data
What's the Equivalent to String.Localizedstringwithformat(_:_:) for Swiftui's Localizedstringkey
iOS 8 Beta Today Extension Widget Not Showing in a Swift App
What Determines Whether a Swift 5.5 Task Initializer Runs on the Main Thread
Can't Hook Up an Outlet Collection in Xcode 6 Using Storyboard
Unexpectedly Large Realm File Size
How to Rewrite Swift ++ Operator in : Ternary Operator
Coreplot with Swift: There Is No Yaxis.Majorintervallength
Swift Uialertcontroller with Pickerview Button Action Stay Up