Any way to test for the presence of the Objective-C runtime?

Is there a proper way to test for the presence of the Objective-C runtime? Specifically, I need to know if Swift code can call NSDictionary.value(forKeyPath:). I can’t use #selector without the Objective-C runtime. I wasn't able to find a compiler control statement that would test for it, other than the imprecise check for being on the linux platform.

What's the best way to conditionally compile code that calls value(forKeyPath:)?

I believe #if canImport(ObjectiveC) should cover any Apple OS where the Objective-C runtime is available, without having to list them all explicitly or try to list the inverse set of platforms that don't support it.

2 Likes

Thank you, that appears to work. I thought it was all part of Foundation on the respective platforms, and didn’t think I’d be able to test against a module.

Since NSDictionary does exist on Linux, this feels like a less-than-optimal solution, but it solves the need to use Marshal in a “Swift-only” environment.

It can look that way since Foundation (and other frameworks) re-exports all the modules that it imports so it's possible to be loose with what you use, but the ObjectiveC module is defined by in $SDKROOT/usr/include/objc/module.modulemap in all of the Apple platform SDKs so it can be checked for explicitly.

(I suppose this could be defeated if, say, a Linux user had a copy of GNUStep and they created an equivalent module map for it and put it on their search path when compiling, but the likelihood of that is probably slim-to-none.)

2 Likes