I have a function in Objective C that returns a BOOL
and has a single errorOut
parameter. The swift bridge converts the errorOut
parameter into a throws
as expected but it also stops the BOOL
being returned.
I can see that usually the BOOL
is returned to indicate success/error but in this case the bool is actually wanted. What changes would I need to make to make sure the bool gets returned?
Objective C function signature
- (BOOL)hasAnyData:(NSError *__autoreleasing *)errorOut;
Thanks to @MartinR for linking to a similar question where I found this trick:
Changing the Objective C function declaration to
- (BOOL)hasAnyData:(NSError *__autoreleasing *)errorOut __attribute__((swift_error(nonnull_error)));
And then calling it from Swift like
let hasAnyData: Bool = try self.repo.hasAnyThings()
Does exactly what I wanted!
The swift_error
attribute is documented here: https://github.com/apple/swift-clang/blob/383859a9c4b964af3d127b5cc8abd0a8f11dd164/include/clang/Basic/AttrDocs.td#L1800-L1819
Original answer - doesn't fully solve the problem but may be useful to someone else looking at this question as it is useful in a similar situation.
I finally found this in the Swift docs:
Use the
NS_SWIFT_NOTHROW
macro on an Objective-C method declaration that produces an NSError to prevent it from being imported by Swift as a method that throws.
I have now added a NS_SWIFT_NOTHROW
annotation to my Objective C function declaration like
- (BOOL)hasAnyData:(NSError *__autoreleasing *)errorOut NS_SWIFT_NOTHROW;
And am having to pass in the NSError pointer
from Swift
var error: NSError?
let hasAnyData = self.repo.hasAnyData(&error)
This isn't the nicest because I can no longer handle the error in a swifty way (using do, try catch
and instead have to use the NSError
) but it's the best I could find.