How to bridge Objective-C initWithError: method into Swift
Asked Answered
S

1

6

I have a class defined in Objective-C, whose initializer is -initWithError: (the initializer can fail due to a dependence on an outside resource). I want this to bridge into Swift as init() throws. The regular initializer inherited from NSObject, -init, can be marked unavailable, as I don't want it to be used.

In Objective-C, I have:

@interface Foo : NSObject

- (instancetype _Nullable)initWithError:(NSError **)error;

@end

This works fine in Objective-C, of course.

In Swift, -initWithError gets bridged as init(error: ()) throws. This is presumably because removing withError: from the method name results in init() which conflicts with the inherited plain -init initializer. This can be called from Swift like so:

let foo = try Foo(error: ())

This is strange looking, as the error parameter is void. It would certainly be better if this were imported as init() throws. The obvious solution is to mark -init using NS_UNAVAILABLE in the Objective-C header. Unfortunately, this doesn't work. -initWithError: still gets bridged as init(error: ()), and trying to call try Foo() results in a compiler error saying that init() is unavailable in Swift.

Is there a more elegant solution to this so that try init() just works?

Shaitan answered 26/3, 2018 at 1:42 Comment(2)
You may be able to tackle this using NS_REFINED_FOR_SWIFT — look for that term on this page: developer.apple.com/library/content/documentation/Swift/…Requiescat
Thanks, Nate! That would probably work. In this case, this code is in a framework that I wanted to keep in pure ObjC if possible. Rob Napier's answer solves the problem.Shaitan
M
5

You can rename the function using NS_SWIFT_NAME. In this case:

- (instancetype _Nullable)initWithError:(NSError **)error NS_SWIFT_NAME(init());

That said, this feels like a compiler bug. I'd suggest opening a defect.

Maurinemaurise answered 26/3, 2018 at 1:53 Comment(1)
Thanks, Rob! Not sure why I didn't think of trying that. I'll file a bug against Swift too.Shaitan

© 2022 - 2024 — McMap. All rights reserved.