Updating to 2.0 with Xcode 7 Beta 4
I have this code block
do
{
try AVAudioSession.sharedInstance().setActive(true)
} catch let err as NSError
{
println("Dim background error")
}
And its giving me the error (on the try line)
Errors thrown from here are not handled.
Is this a compiler error or is there something I am missing in my syntax?
I checked the docs and my code 'looks' correct.
What types of errors can AVAudioSession.sharedInstance().setActive(true) throw?
If it can only throw NSErrors, then there's no need of specifying this when catching the error. You could simply write:
do {
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print("Dim background error")
}
If you want to use the error in your catch-scope, you can still access it. Swift automatically binds the thrown error to error, which can be used:
catch {
// do something with `error`
}
If the method throws multiple types of errors, and you only want to deal with the ones that are NSErrors, you can conditionally bind them:
catch let specialError as NSError {
// do something with `specialError`
}
You must ensure though, that every thrown error is handled. So assuming that the method can also throw a RandomError (which I just made up now), you would have to write:
catch let randomError as RandomError {
// do something with `randomError`
}
...in addition to the catch of the NSError.
Or you could of course use the general case:
catch {
// do something with `error`
}
So I assume your problem can be solved by removing let err as NSError, from your catch-statement.
May be a compiler bug. Anyway try removing let err as NSError ; catch alone is enough if you want to catch all errors.
Also, with Swift 2 you should use print, not println.
The following code compiles without errors with XCode 7 Beta 4:
import AVFoundation
class X {
func y() {
do {
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print("Dim background error \(error)")
}
}
}
check this code that will you get idea on try/catch :
enum ErrorMessages :ErrorType {
case ErrorDescription
}
do
{
try AVAudioSession.sharedInstance().setActive(true)
} catch ErrorMessages.ErrorDescription
{
println("Present the error description here")
}
Related
If I option click on withUnsafeBytes in my code, the declaration states that the function throws:
func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R
When I put in do try catch in my code (see below) I get a warning for the try:
No calls to throwing functions occur within 'try' expression
and a matching warning for the catch:
'catch' block is unreachable because no errors are thrown in 'do' block
Is my code incorrect or is this a problem with Xcode?
func getIntValue(data:Data)->Int
{
var d = -1
do {
d = try data.withUnsafeBytes {
$0.load(as: Int.self)
}
} catch {
return d
}
return d
}
Your input is appreciated.
The throws -> rethrows syntax does the following:
If the code in the closure body contains a throwing function the error is rethrown and you have to add try
If there is no throwing function nothing happens and you must not use try.
In your example the second case occurs so remove try and the do - catch block
In most programming languages, there is a finally block that can be placed after try or catch block like this :
try {
sensitiveFunction();
} catch (Exception e) {
executedWhenFailed();
} finally {
alwaysExecuted();
}
But we can execute the same code without finally block like that :
try {
sensitiveFunction();
} catch (Exception e) {
executedWhenFailed();
}
alwaysExecuted();
So, why does finally block exist? Anyone have an example that finally block is required ?
Thanks
Even these examples aren't equivalent: if sensitiveFunction() throws something which doesn't extend Exception but Error instead, alwaysExecuted won't be executed without finally (please don't try to "fix" this by catching Throwable).
Or say executedWhenFailed() itself throws an exception: it's quite common to rethrow an exception from a catch block after adding some information. Again, alwaysExecuted() won't be executed in the second snippet.
Or suppose you have return sensitiveFunction(); instead of just a call. Etc. etc.
finally exists so that code can always be run, without regard to if you caught the exception or not.
Sometimes you want to just use try and finally together:
allocate()
try:
do_something_with_allocated()
finally:
deallocate()
In the above example, it lets you 100% confidently clean up a resource that was opened above without regard for any exceptions that may be propagating up.
If you throw a new exception in your catch block, you will eventually (after that exception has been handled) end up in your finally block. But not in the line after your catch.
Just throw an exception in executedWhenFailed, in your first example alwaysExecuted will be executed, in the second it wil not.
The finally block is executed even if there is a return statement in the catch() block.
(Example in JavaScript)
function foo() {
try {
throw "first"
} catch(err){
console.log(err)
return "third"
} finally {
console.log("second") // Called before return in catch block
}
return "Never reached"
}
console.log(foo())
I got the follow error when attempting to build a parse.com project via Xcode 7.0/Swift 2.0:
Is there a work around for this?
What's the Swift 2.0 equiv.?
You can either:
user.signUpInBackgroundWithBlock { (succeeded: ObjCBool, error: NSError?) -> Void in
// do something
}
Or
user.signUpInBackgroundWithBlock { succeeded, error in
// do something
}
--
Note, Xcode can show you the appropriate types. For example, if I start to type and then let code completion show me the method, I see something like:
If I then hit enter and select the block: PFBooleanResultBlock? and hit enter again, I'll see:
That shows me precisely what types those two parameters are.
user.signUpInBackgroundWithBlock {success, error in
if error == nil {
//
}
else{
//
}
}
Above works fine with no errors.
Is this usage not correct? why? The file name I use is correct!
on the right side of the playground I would aspect to see the content of the txt file.
In terms of why this failed, you'd have to look at the error object and examine why it failed. You're catching the error, so look at it:
func read(path: String) throws {
do {
try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding)
} catch {
print("cannot read: \(error)")
}
}
That will tell you why it failed.
Having said all of that, this doesn't quite make sense: First, you're reading the contents of the path into the NSString, but discarding it. You presumably want to return this string or do something with it.
Second, read has been declared in such a way as to say that it throws error, but it doesn't really. It catches any error that might happen itself, but doesn't throw anything. You have to decide whether read will throw any errors it generates, or whether it will handle them without throwing any error, or both.
Assuming the caller was going to handle the error, you might just forego any do-try-catch construct in read altogether:
func read(path: String) throws -> NSString? {
return try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding)
}
Then you can let the caller catch any error that NSString threw. For example, you might catch the "not found" error:
do {
let string = try read(path)
// do something with string
} catch let error as NSError where error.domain == NSCocoaErrorDomain && error.code == NSCocoaError.FileReadNoSuchFileError.rawValue {
// not found handling here
} catch {
print(error)
}
If you really wanted read to not only catch the error, but also make sure it throws one as well, then you'd need to have to explicitly throw an error from its catch block. You can use this pattern using either your own ErrorType or just throwing the original error you just caught:
func read(path: String) throws -> NSString? {
var string: NSString?
do {
string = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding)
} catch {
// do whatever special handling you want here
// but also throw error so caller is informed that there was an issue
throw error
}
return string
}
Frankly, I think the pattern outlined above is simpler, but given your code snippet, I thought I'd also illustrate this latter pattern, too, in case you needed something like that.
I am also learning, so I wrote a little demo. Hope it helps.
I'm trying to update my project to work with Xcode 7.0 and after updating my Swift projects I'm getting an error that I don't understand on this line.
let jsonData:NSDictionary = NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary
The error is
"Call can throw, but it is not marked with 'try' and the error is not handled"
I'm also getting these two errors in my project files...
"linker command failed with exit code 1 (use -v to see invocation)"
and
"error: cannot parse the debug map for "/Users/MattFiler/Library/Developer/Xcode/DerivedData/ePlanner-cqwzlxqgpwaloubjgnzdlomjkfea/Build/Intermediates/SwiftMigration/ePlanner/Products/Debug-iphonesimulator/ePlannerTests.xctest/ePlannerTests": No such file or directory"
Try this code:
do {
let jsonData = try NSJSONSerialization.JSONObjectWithData(urlData!, options: .MutableContainers ) as! NSDictionary
// Use jsonData here
} catch {
print("Well something happened: \(error)")
}
You'll need the try keyword as NSJSONSerialization.JSONObjectWithData now throws an error if something failed since Swift 2. Throwing functions need to be marked with try or try!.
Also you'll need the do { ... } catch to catch any errors that may occur. This will catch the error and handle it.
You might want to read up on the changes in Swift 2 to understand why this happened. Also the WWDC videos will be very helpful.
You need to try and catch if it throws an error.
do {
let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary
//...
}
catch {
}