I am having some issues migrating from Swift 1.2 to 2.0 particularly understanding error handling when calling methods from objective-c API. For example, I can't implement the method checkResourceIsReachableAndReturnError correctly. According to the Swift documentation for this method it will return a Bool. I want to check if a folder (self.baseURL) exists and tried the two following approaches:
let folderExists: Bool
do{
try folderExists = self.baseURL!.checkResourceIsReachableAndReturnError(){
} catch let error as NSError {
}
}
And:
let folderExists: Bool
var error: NSError?
do{
try folderExists = self.baseURL!.checkResourceIsReachableAndReturnError(&error){
} catch error as NSError {
}
}
But neither approaches work. I also thought that the Swift implementation of error throwing functions with the word AndReturnError would be shortened to checkResourceIsReachable but that does not seem to be the case.
I am sure I am doing something fundamentally wrong here and if someone has a suggestion for where to look I would appreciate that.
This method indeed returns a bool, it hasn't been modified to follow the new do try catch mechanism of Swift 2: it doesn't throw.
So you just use it like this, without do try catch:
var error:NSError?
let folderExists = self.baseURL!.checkResourceIsReachableAndReturnError(&error)
Related
I have a Win32 DLL I am trying to convert to be usable from UWP. I need to replace file handling code (CreateFile, ReadFile, etc.) to the WinRT safe equivalents (Windows::Storage::StorageFile). I have the code converted and compiling, but when I run the app I get this exception calling get on the returned async operations and I am not sure how to resolve this.
Ok, took a bit to figure out what I was doing wrong but the correct way to handle this in my case is to wrap my code in a co_routine and then call it using PPL.
IAsyncOperation<int> DoWork()
{
co_await winrt::resume_background();
…
return someValue;
}
int Foo()
{
return create_task([]{
return DoWork().get();
}).get();
}
as you can guess, this is an issue regarding swift's whole API renovation. I've read the documentation extensively but can't seem to lay my finger on a proper workaround.
I am receiving the error
Value of type 'Error' has no member 'userInfo'
on the following line:
else if let secondMessage = error?.userInfo["error"] as? String
of this block:
let query = PFQuery(className: "Images")
query.whereKey("Subject", equalTo: self.subjectName)
query.findObjectsInBackground { (objects, error) -> Void in
if error == nil {
// do something
}else if let secondMessage = error?.userInfo["error"] as? String {
// do something
}
Any suggestions? feel's like I'm missing something painstakingly obvious... dev block i guess :(
I just converted my app to Swift 2, and of course, am getting one error message:
"Call can throw, but it is not marked with 'try' and the eror is not handled"
I did search here for how to fix this, but the answers are even more confusing to me than the error itself. LOL.
My application worked perfectly until I converted it into Swift 2. Wonderful...
var myPlayer = AVAudioPlayer()
var yourSound1 = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("RemSound_01", ofType: "wav")!)
func initYourSound() {
myPlayer = AVAudioPlayer(contentsOfURL: yourSound1, fileTypeHint: nil)
myPlayer.prepareToPlay()
myPlayer.volume = 1.0 // < for setting initial volume, still not perfected.
}
The error throws in the following line:
myPlayer = AVAudioPlayer(contentsOfURL: yourSound1, fileTypeHint: nil)
How am I supposed to fix this? I understand that Swift is trying to "universalize" error handling, but doing so by breaking even the simplest of code seems silly to me.
Thank you for your help.
Here is the pattern you are looking for.
<throwing function> // compiler error in Swift 2
do { try <throwing function> } catch { }
In catch you usually get an error that you can handle further.
This works in Swift 2.0, put it in your viewDidLoad method ...
do {
try AudioPlayer = AVAudioPlayer(contentsOfURL: ButtonAudioURL, fileTypeHint: nil)
} catch {
print("errorin do-try-catch")
}
where ButtonAudioURL is
var ButtonAudioURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Besides", ofType: "mp3")!)
Each guide I find on swift 2.0 error handling shows handling errors on a custom class. I know how to do, try, catch but what I don't know is what to catch. I know I'm testing for certain enum to indicate the error but where or how do i find these error enums if i did not create the class?
Im using
class func JSONObjectWithData(_ data: NSData,
options opt: NSJSONReadingOptions) throws -> AnyObject
so it says it throws and I would like to handle that but what does it throw? how do I know what enums to catch in the catch block? No doubt I'm missing something obvious but you know what it's like when you just can't spot it?
thanks
For methods in the Apple frameworks look into the documentation and compare the method signature with its Objective-C equivalent.
In this specific case the Objective-C equivalent is
+ (id)JSONObjectWithData:(NSData *)data
options:(NSJSONReadingOptions)opt
error:(NSError * _Nullable *)error
so the object in the catch statement is an NSError object
do {
let jsonData = try JSONObjectWithData(someData, options:NSJSONReadingOptions())
} catch let error as NSError {
print(error)
}
And, if you guaranty it should returns object then you could use below code:
let jsonDataObject = try! JSONObjectWithData(someData, options:NSJSONReadingOptions())
Here, advantage is we can avoid to use "do { }" scope of syntax
Excuses to my silly question, i wish to use a catch for specific exception, NSInvalidArgumentException, so, i have the next code in my OSX project:
#try
{
...
}
#catch(NSInvalidArgumentException* exception )
{
...
}
but xcode say me: "unknown type name 'NSInvalidArgumentException'", so i i was importing
import "Foundation/Foundation.h" or
import "Foundation/NSException.h"
but nothing happen, somebody known in what package or library is NSInvalidArgumentException? or which is my error? or is strictly necessary catch all exception using the superclass NSException? in the developer documentation do not show that so be it.
best regards.
NSInvalidArgumentException is not an exception type. It is a string that will be returned in the name property for an exception. So, you should catch your exception, and the name property does not match, you can re-#throw the exceptions you're not going to handle, e.g.:
#try {
// code that generates exception
}
#catch (NSException *exception) {
if ([exception.name isEqualToString:NSInvalidArgumentException])
{
// handle it
}
else
{
#throw;
}
}
See the Exception Programming Topics for more information.
I must confess that I share CodaFi's concern that this is not an appropriate use of exceptions. It's much better to program defensively, validate your parameters before you call Cocoa methods, and simply ensure that you don't generate exceptions in the first place. If you refer to the Dealing with Errors section of the Programming with Objective-C guide, exceptions are intended for "programmer errors" and they say:
You should not use a try-catch block in place of standard programming checks for Objective-C methods.
somebody known in what package or library is NSInvalidArgumentException?
It is declared in the Foundation Framework, in NSException.h. As CodaFi wrote in the comment, it is not a type, it is a string constant, declared as FOUNDATION_EXPORT NSString * const NSInvalidArgumentException;
So importing more headers won't fix your problem, because #catch(NSInvalidArgumentException* exception ) is like writing #catch(#"A string constant"* exception ), you have an object, where a type is expected.
Having said that, don't use exceptions for flow control. Have a look at the last part of this answer on SO