Package+Module visibility (for libraries)

Hi, I'm trying to build a Swift package which exposes certain functionality in a multi-platform way. Different platforms will have specific implementations of protocols defined at the core. I would like, however, that whoever is consuming my library - is able to use just ONE single import. I see that if I follow my structure, the user app would have to import my internal modules/targets independently, which is not desired.

I have:

  • Core Protocols and Structures ("CoreLib" target) - bottom layer

Then I define implementations that are platform-specific: middle layer

  • macOS + iOS implementations ("AppleLib" target)
  • Linux implementations ("LinuxLib" target)

Finally I have a top layer which depends on Core + (compile time conditional on platform Lib). This is my "LibX"

So, I expect that if my user app wants to consume these APIs, they should be able to just use

import LibX

rather than

import CoreLib // this should be an implementation detail
import LibX

The internal structure of my modules/targets should be an implementation detail that shouldn't be exposed to the consumers of the library. This would be very handy if in the future I refactor my library without breaking the APIs and signatures.

Is this supported or planned?

#if os(Linux)
#elseif os(macOS)
#else
#endif

I would suggest combining the "AppleLib" and "LinuxLib" targets into one "LibX" target which uses conditionals (e.g. #if os(Linux)). As long as clients don't need to directly call API of CoreLib which seems like they should not if it is truly an implementation detail, only import LibX will be needed in client code.

1 Like

Yes, that would work. The only "impractical" aspect of this approach is that I would have to add conditionals in many files.
I guess it's the lesser evil as I would have to "republish" certain types under LibX to make it work otherwise (probably via typealiases - that would be dirty...).

Thanks @taylorswift and @NeoNacho!

1 Like

@_exported import CoreLib from LibX should be sufficient. This doesn't prevent users from manually import CoreLib however.