I have this code in ObjC/C:
AVCaptureFocusMode GetFocusModeWithString(NSString *mode) {
if ([mode isEqualToString:@"locked"]) {
return AVCaptureFocusModeLocked;
} else if ([mode isEqualToString:@"auto"]) {
return AVCaptureFocusModeAutoFocus;
} else {
@throw [NSError errorWithDomain: @"FocusError", code: 12];
}
}
It used to be working fine when calling from ObjC code. Now I am rewriting the caller side using swift. However, in swift, this code does not actually throw:
// does not work, swift thinks this function does not throw.
do {
try GetFocusModeWithString(@"auto")
}
Am I doing anything wrong here? Is the ObjC code bad? how can I improve the ObjC code to work nicely with swift?
2
Answers
Objective-C exceptions are not compatible with Swift. Here’s what Apple says:
Objective C does not have do/try/catch semantics the way that Swift does.
@throw
causes a runtime exception. This isn’t something you can catch in Swift.The way that you can integrate Cocoa error handling with Swift is described in the Swift Objective C interoperability documentation and this answer
First declare your Objective-C function to accept a pointer to an instance of
NSError
. Then you can flag that parameter with function with__attribute__((swift_error(nonnull_error)))
.This will cause a Swift exception if the error is non-null when the function returns
Now, in your Swift code you can call it with
Note that this will change your method signature in Objective-C; You will need to pass
&error
to the method and check its value on return.