We (@Tony_Parker @icharleshu and @jmschonfeld, please correct if I got anything wrong or missed any thing) have been talking about this, but unfortunately we've not been able to come up with a nice solution yet. Here are some ideas we've come up so far.
My understanding is that we want that, ultimately, one should be able to write this without platform guard
import FoundationEssentials
and the same code should builds on all platforms.
Option 1: Introduce a FoundationEssentials
module on Darwin for parity.
This would mean splitting Foundation.framework into FoundationEssentials
, FoundationInternationalization
, and another module for other Darwin-only code that will never make into Linux. For the sake of argument, let's call it FoundationDarwinSupport
.
This is challenging because while we want FoundationEssentials to be "the same" on Linux and on Darwin, that's not the current status, and I'm not sure if it's ever possible. Take FileManager
as an example. It is an Obj-C imported type, a subclass of NSObject
on Darwin, but not on Linux.
Now, what do we do with FileManager
?
Option 1.1: It remains available in FoundationEssentials
, but we modify it to look exactly like how it is on Linux (so, not a NSObject
)
But for Darwin compatibility, it has to be NSObject
when needed. Ideally we'd conditionally declare it as a NSObject
if FoundationDarwinSupport
is linked, or extend the type so it becomes a NSObject
subclass in FoundationDarwinSupport
. Unfortunately neither is possible now.
Option 1.2: Introduce a FileManager2
, reimplemented from bottom up and sharing the same source on two platforms.
This will indeed achieve what we want. However, it also means we'll have two types serving very similar functionality. This strategy doesn't scale well to all types we've been building with either.
Option 2: Annotation support
It's hard to know what's available in FoundationEssentials and what's not.
It's another point that @0xTim mentioned that, if addressed, would greatly improve the experience.
But what can we do now? For example, if we could add @available(linux)
to APIs that are available on Linux, and some compiler flag to specify what deployment targets to match against, you'd be able to get compile time check when building on MacOS.
Or, if there's a way to typealias/define your own import that effectively does this
#def EssentialsIfAvailable
#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
#end_def
// in your code
import EssentialsIfAvailable
But again, I'm not sure if it's possible to do something like this yet.
Short summary
While we haven't been able to reach any solution yet, we're definitely going to continue thinking about this. I'd like to hear if anyone has other ideas too.