问题
I need to implement a try-catch structure in Objective-C to handle Swift thrown NSErrors.
I've written an NetService manager with Swift code and I am implementing it on an already existent Objective-C UI.
However, whenever I throw an error from my Swift class, the try-catch structure fails to catch the error and proceeds to the finally block.
Swift error definition:
enum NEONetServiceErrors: Int
{
case requestMadeWithoutIp
}
struct NEONetServiceErrorStrings
{
let requestMadeWithoutIp = ["NEONetService Error: Request made without IP": NEONetServiceErrors.requestMadeWithoutIp]
}
Swift error throwing:
@objc func requestHelloPage() throws
{
if serviceiPAddress != nil
{
makeHelloRequest()
}
else
{
throw NSError(domain: errorStrings.domain, code: NEONetServiceErrors.requestMadeWithoutIp.rawValue, userInfo:errorStrings.requestMadeWithoutIp)
}
}
Objective-C properties:
@property NEONetServiceManager* netServiceManager;
@property NSError* _Nullable __autoreleasing * _Nullable netServiceError;
Objective-C error handling:
- (IBAction)pressUpdateButton:(id)sender
{
@try
{
[self.netServiceManager requestHelloPageAndReturnError: self.netServiceError];
}
@catch (NSException *exception)
{
NSLog(@"Throwing");
}
@finally
{
NSLog(@"Finally");
}
}
Output:
2019-10-18 14:47:03.289268-0300 NEOFirmUpdate[16533:2389800] Start
2019-10-18 14:47:03.292696-0300 NEOFirmUpdate[16533:2389800] Finally
Could you help me figure out what I am doing wrong with my error-handling?
回答1:
The problem is that a Swift Error / Objective-C NSError is not an NSException. You are configured to catch NSExceptions but that is irrelevant.
The way to "catch" an NSError in Objective-C when Swift throws an Error is by indirection with the NSError**
parameter, just as it always has been.
NSError* err = nil;
BOOL ok = [self.netServiceManager requestHelloPageAndReturnError:&err];
if (ok) {
// proceed normally
} else {
// you got an error, it is sitting in `err`
}
(Notice how Swift supplies a BOOL result exactly so you can implement the correct pattern.)
回答2:
That's because you're using objective-c exceptions there, and not actually checking for an error. To check for errors in objective-c, you pass a reference to your pointer and your function will fill that error out if there was an issue.
NSError *serviceError = nil;
[self.netServiceManager requestHelloPageAndReturnError:&serviceError];
if (serviceError) {
// there was a problem
}
If this is an asynchronous call, you'll need to do this in a closure instead:
NSError *serviceError = nil;
[self.netServiceManager requestHelloPage:^(NSError *error) {
if (error) {
// there was a problem
}
}];
回答3:
In your Objective-C code you are Catching and NSException, not an NSError
Swift automatically bridges between the Error type and the NSError class. Objective-C methods that produce errors are imported as Swift methods that throw, and Swift methods that throw are imported as Objective-C methods that produce errors, according to Objective-C error conventions.
for more information you can click here
来源:https://stackoverflow.com/questions/58455883/how-can-i-throw-an-nserror-from-a-swift-class-and-catch-it-in-an-objective-c-cla