I have tried the conversion tools to update these few lines of code, but unfortunately the process did not caught up these two errors.
Could you help me to understand if I need to introduce the do { and error handling? (I am new to swift!).
The error message I receive is the following: "Call can throw, but it is not marked with 'try' and the error is not handled"
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
query.findObjectsInBackgroundWithBlock {(result: [PFObject]?, error: NSError?) -> Void in
self.posts = result as? [Post] ?? []
// 1
for post in self.posts {
// 2
let data = post.imageFile?.getData() --> this is where I get the error message
// 3
post.image = UIImage(data: data!, scale:1.0)
}
self.tableview.reloadData()
}
Insted of this: let data = post.imageFile?.getData()
Use this instead:
do
{
try let data = post.imageFile?.getData()
}
catch
{
print("Error: \(error)")
//Handle the error instead of print probably
}
Related
In order to track server errors from a Restfull Api on an SwiftUI IOS App I am feeding the error message from NSData to the "reason" parameter of next NetworkErrors enum:
enum NetworkError: Error {
case domainError(reason:String)
case decodingError(reason:String)
case encodingError(reason:String)
}
The error reason is fed when decoding the NSURLSession response:
static func postRequest<T:Decodable, U:Codable>(_ endpoint:String, _ input:U?, completion: #escaping (Result<T,NetworkError>) -> Void) {
...
do {
let retval = try JSONDecoder().decode(T.self, from: data)
completion(.success(retval))
} catch let DecodingError.dataCorrupted(context) {
let responseData = String(data: data, encoding: String.Encoding.utf8)
completion(.failure(.decodingError(reason: responseData ?? "Data corrupted from response")))
} catch {
...
}
...
}
The error reason should be available on next code, but I'm only able to print the localizedDescription:
Button(action:{
self.postRequest(endpoint, self.value){ (result: Result<Bool,NetworkError>) in
switch result {
case .success:
print("value saved successfully")
case .failure(let error):
print("failure to save value")
print(error.localizedDescription)
}
}
}){
Image(systemName:"icloud.and.arrow.up")
}
In the failure case, we know that error is a NetworkError, so now disassemble that error with another switch:
switch error {
case .domainError(let reason): // do something
case .decodingError(let reason): // do something
case .encodingError(let reason): // do something
}
I'm new to swift and
I'm not understanding why I'm getting this error.
I've being reading similar questions and so far none of them solved this error or I have not found it:
Invalid conversion from throwing function of type '(_) throws -> ()'
to non-throwing function type '(Any) -> ()'
At the line:
self.ws.event.message = { message in
The piece of code with the error:
public var ws = WebSocket()
public func websocket(token: Any){
self.ws.open("ws://"+String(APIHOST)+":"+String(port)+"/ws?token="+String(describing: token))
self.ws.event.message = { message in
if let text = message as? String {
let json = try JSONSerialization.jsonObject(with: text, options: []) as? [String: Any]
print("recv: \(text)")
}
}
}
Thanks for any help
Try below piece of code
public var ws = WebSocket()
public func websocket(token: Any){
self.ws.open("ws://"+String(APIHOST)+":"+String(port)+"/ws?token="+String(describing: token))
self.ws.event.message = { message in
if let dataObj = message as? Data {
do {
let json = try JSONSerialization.jsonObject(with:dataObj, options: []) as? [String: Any]
print("recv: \(text)")
} catch error {
print("Unable to load data: \(error)")
}
}
}
}
If you have a function that throws something, it usually means there might be a chance of error when accessing that data in your case JSON.
If function throws you need to do {} catch {} to tell Swift you are going to handle an error.
I'm currently developing my first iOS app using Swift 2.0 and Xcode Beta 2. It reads an external JSON and generates a list in a table view with the data. However, I'm getting a strange little error that I can't seem to fix:
Extra argument 'error' in call
Here is a snippet of my code:
let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
print("Task completed")
if(error != nil){
print(error!.localizedDescription)
}
var err: NSError?
if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary{
if(err != nil){
print("JSON Error \(err!.localizedDescription)")
}
if let results: NSArray = jsonResult["results"] as? NSArray{
dispatch_async(dispatch_get_main_queue(), {
self.tableData = results
self.appsTableView!.reloadData()
})
}
}
})
The error is thrown at this line:
if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary{
Can someone please tell me what I'm doing wrong here?
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)
}
Things have changed in Swift 2, methods that accepted an error parameter were transformed into methods that throw that error instead of returning it via an inout parameter. By looking at the Apple documentation:
HANDLING ERRORS IN SWIFT:
In Swift, this method returns a nonoptional result and is marked with the throws keyword to indicate that it throws an error in cases of failure.
You call this method in a try expression and handle any errors in the catch clauses of a do statement, as described in Error Handling in The Swift Programming Language (Swift 2.1) and Error Handling in Using Swift with Cocoa and Objective-C (Swift 2.1).
The shortest solution would be to use try? which returns nil if an error occurs:
let message = try? NSJSONSerialization.JSONObjectWithData(receivedData, options:.AllowFragments)
if let dict = message as? NSDictionary {
// ... process the data
}
If you're also interested into the error, you can use a do/catch:
do {
let message = try NSJSONSerialization.JSONObjectWithData(receivedData, options:.AllowFragments)
if let dict = message as? NSDictionary {
// ... process the data
}
} catch let error as NSError {
print("An error occurred: \(error)")
}
This has been changed in Swift 3.0.
do{
if let responseObj = try JSONSerialization.jsonObject(with: results, options: .allowFragments) as? NSDictionary{
if JSONSerialization.isValidJSONObject(responseObj){
//Do your stuff here
}
else{
//Handle error
}
}
else{
//Do your stuff here
}
}
catch let error as NSError {
print("An error occurred: \(error)") }
I'm using the SODA Client for swift (Created by Socrata), I just updated to XCode 7 and swift 2 and found some troubles. The one I haven't been able to solve is the completion handler case when it finds an error, it's not accepting the line "syncCompletion(.Error (reqError))" that supposedly should get the error and return to main thread.
I've seen many errors with the same description here "Type of expression is ambiguous without more context", but not in completion handlers, I saw one using do - catch that is different. I'm don't know enough of swift to find out the way to change this.
Some answers suppose you should rewrite the code because some types could have change in swift 2, but I wouldn't know where to start rewriting.
Thanks in advance for your help.
var task = session.dataTaskWithRequest(request, completionHandler: { data, response, reqError in
// We sync the callback with the main thread to make UI programming easier
let syncCompletion = { res in NSOperationQueue.mainQueue().addOperationWithBlock { completionHandler (res) } }
// Give up if there was a net error
if reqError != nil {
syncCompletion(.Error (reqError))
return
}
// Try to parse the JSON
// println(NSString (data: data, encoding: NSUTF8StringEncoding))
var jsonError: NSError?
var jsonResult: AnyObject!
do {
jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
} catch var error as NSError {
jsonError = error
jsonResult = nil
} catch {
fatalError()
}
if let error = jsonError {
syncCompletion(.Error (error))
return
}
// Interpret the JSON
if let a = jsonResult as? [[String: AnyObject]] {
syncCompletion(.Dataset (a))
}
else if let d = jsonResult as? [String: AnyObject] {
if let e : AnyObject = d["error"] {
if let m : AnyObject = d["message"] {
syncCompletion(.Error (NSError(domain: "SODA", code: 0, userInfo: ["Error": m])))
return
}
}
syncCompletion(.Dataset ([d]))
}
else {
syncCompletion(.Error (NSError(domain: "SODA", code: 0, userInfo: nil)))
}
})
Solved, I replaced:
if reqError != nil
With
if let error = reqError
and:
syncCompletion(.Error (reqError))
with
syncCompletion(.Error (error))
I am working on a REST API Manager. It is giving an error and I am not able to fix it. The error I got is given below as highlighted.
import Foundation
import Alamofire
import SwiftyJSON
class RestApiManager {
var resources: JSON = [
"resources": [
"resourceA": []
]
]
let apiUrl: String
let apiUsername: String
let apiPassword: String
init(apiUrl: String, apiUsername: String, apiPassword: String) {
self.apiUrl = apiUrl
self.apiUsername = apiUsername
self.apiPassword = apiPassword
getApiResourceA() { responseObject, error in
let resourceA = JSON(responseObject!)
self.resources["resources"]["resourceA"] = resourceA
}
}
func collectDataFromApi(completionHandler: (responseObject: NSDictionary?, error: NSError?) -> ()) {
prepareHttpRequest(completionHandler)
}
func prepareHttpRequest(completionHandler: (responseObject: NSDictionary?, error: NSError?) -> ()) {
let alamofireRequest = Alamofire.request(.GET, "\(self.apiUrl)")
alamofireRequest.authenticate(user: self.apiUsername, password: self.apiPassword)
alamofireRequest.responseJSON { request, response, responseObject, error in
completionHandler(responseObject: responseObject as? NSDictionary, error: error)
}
}
func getAllResources() -> JSON {
return self.resources
}
func getApiResourceA(completion: (responseObject: NSDictionary?, error: NSError?) -> ()) {
collectDataFromApi() { responseObject, error in
completion(responseObject: responseObject, error: error)
}
}
}
And when I call this class to get the resources:
override func viewDidLoad() {
super.viewDidLoad()
if record != nil {
let url = record?.url
let username = record?.username
let password = record?.password
let restApiManager = RestApiManager(apiUrl: url!, apiUsername: username!, apiPassword: password!) // This line seems buggy
let delay = 10.0 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue()) {
let Resources = restApiManager.getAllResources()
let ResourceA = Resources["resources"]["resourceA"]
}
}
}
The line I commented prints:
Thread 1: breakpoint 2.1
I need suggestions for fix that error. Any suggestions are very much appreciated
You may have accidentally set a breakpoint without noticing.
Click and drag the blue tick representing the breakpoint outside of the gutter to erase it.
I was getting same error when I accidentally activated Breakpoint in my Xcode.
To resolve issue, simply unblock blue icon.