0

I would like to do something like:

try {
    SomeObjectiveClass.someMethod()
catch Error {
    print("Recovered objc crash from Swift!")
}

I'm building an app where I type some visual constraints and I get the result or a message about any mistake.

Now, every time I type wrong constraints the app crashes, but I'd like to display a dialog with the error and let the user try again.

In my situation I don't have the "NSError-to-throws" automatic translation.

6
  • 1
    Yes, if someMethod takes an NSError ** parameter, when you call that from Swift 2, that behaves like a method that throws an error. Commented Nov 29, 2015 at 0:28
  • Thanks Rob. Only in those cases? What about a wrong constraint that makes my layout code crash. Could I catch that? Commented Nov 29, 2015 at 0:32
  • No, that's an exception, which is a different issue. You should generally resolve exceptions in the development process (e.g. fix the source of your constraints-based exception), rather than trying to catch them. The do-try-catch mechanism in Swift is for catching errors, not exception handling. Commented Nov 29, 2015 at 1:05
  • I know, Rob, but I want to catch them because I'm building a program where I type some visual constraints and I get the result or a message about any mistake. It's not a "normal" application where you should never have wrong constraints. Commented Nov 29, 2015 at 9:30
  • 1
    Then, as the documentation says, "Any exception handling behavior must be implemented in Objective-C code used by Swift." Commented Nov 29, 2015 at 13:17

1 Answer 1

1

Consider this class:

@implementation SomeObjectiveClass

+ (BOOL)someClassMethodWithError:(NSError **)error {
    // some something that 

    if (everythingOk) {
        return true;
    } else {
        if (error) {
            *error = [NSError errorWithDomain:kMyDomain code:kSomeErrorCode userInfo:@{NSLocalizedDescriptionKey : @"Some error message"}];
        }
        return false;
    }
}

- (BOOL)someInstanceMethodWithError:(NSError **)error {
    // some something that 

    if (everythingOk) {
        return true;
    } else {
        if (error) {
            *error = [NSError errorWithDomain:kMyDomain code:kSomeOtherErrorCode userInfo:@{NSLocalizedDescriptionKey : @"Some error message"}];
        }
        return false;
    }
}

@end

You can then catch those errors like so:

do {
    try SomeObjectiveClass.someClassMethod()

    // or

    let object = SomeObjectiveClass()
    try object.someInstanceMethod()
} catch {
    print("Recovered \(error) from Swift!")
}

Note, this catching of errors should not be confused with exception handling which we used to be able to do in Objective-C. Exceptions should be eliminated during the development process. The above is for legitimate runtime errors (e.g. failed network request or some other error that might occur due to conditions outside of the programmer's control).

To quote from Using Swift with Cocoa and Objective-C:

Although Swift error handling resembles exception handling in Objective-C, it is entirely separate functionality. If an Objective-C method throws an exception during runtime, Swift triggers a runtime error. There is no way to recover from Objective-C exceptions directly in Swift. Any exception handling behavior must be implemented in Objective-C code used by Swift.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.