I have an error that used to look like this in Objective-C
NSString * const JKConfigurationErrorDomain;
typedef NS_ENUM(NSInteger, JKConfigurationCode) {
JKConfigurationCodeUnknown,
JKConfigurationCodeSomethingBad,
JKConfigurationCodeParsing,
};
Now, this is ugly to use in Swift. But since Swift 4, we can use NSErrorDomain
and NS_ERROR_ENUM
to make the imported error much nicer in Swift:
NSErrorDomain const JKConfigurationErrorDomain;
typedef NS_ERROR_ENUM(JKConfigurationErrorDomain, JKConfigurationCode) {
JKConfigurationCodeUnknown,
JKConfigurationErrorSomethingBad,
JKConfigurationErrorParsing,
};
This means I can now do stuff in Swift like this:
if let myError = error as? JKConfigurationError, myError.code = .somethingBad {
// handle it
}
instead of having to cast error
to NSError
, then check its .domain
then look at the .code
which is an integer, etc.
So far, so good. But my library is called JKConfiguration
and there is already a JKConfiguration
object (the center piece of the library) in there and as soon as I start using JKConfiguration
anywhere in the library code I get an error:
'JKConfiguration' is ambiguous for type lookup in this context
I don't get it, why? What does NSErrorDomain
or NS_ERROR_ENUM
do such that the type lookup becomes ambiguous and how can I fix it?
What I tried already:
NS_SWIFT_NAME
on the NS_ERROR_ENUM
typedef and rename it to something else. Looking at the generated Swift header, the rename works, but doesn't solve the issueThe issue is not, as I initially thought, in the name of the error domain. Nor is it a problem with the library name. It’s a problem of the error enum‘s name, in the example above: JKConfigurationCode.
What the Compiler does for the enum cases of an NS_ERROR_ENUM is two-fold:
Code
remove that suffix.So that last part is the issue. It means that NS_ERROR_ENUM(AnyDomainName, JKConfigurationCode)
generates an enum in Swift to hold the error codes with the name JKConfiguration
(without the Code) prefix. But that type already exists in my example, which leads to the ambiguity.
So the solution is to change
NS_ERROR_ENUM(JKConfigurationErrorDomain, JKConfigurationCode)
to
NS_ERROR_ENUM(JKConfigurationErrorDomain, JKConfigurationSomethingCode)
Or similar. Don’t forget to update all the prefixes of your enum cases though, as it seems the compiler won’t find them if the prefixes don’t match the enum name.
Why doesn’t NS_SWIFT_NAME work to rename the enum? Best I can tell, NS_SWIFT_NAME causes the type to be renamed but not the cases. This leads to an empty type (Swift chooses a struct in that case) being generated for the error code as Swift doesn’t seem to find the cases. And the original container for the enum cases still has the offending name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With