Conditionally revealing symbols from a module only when SwiftUI is imported

TLDR; I'm trying to identify how the compiler is conditionally revealing some symbols when a certain module is imported alongside SwiftUI, and before giving up, I'd like to ask for your help / opinion on this.

What I try to solve is to evolve the approach I use for library development where instead of vending two modules, i.e. Library & LibraryUI, where LibraryUI imports Library, and exposes a set of UI views to be used in conjunction with the entities defined by Library, to expose a single module named LibraryKit, that when imported alongside SwiftUI is making the corresponding UI types available.

This approach is used by Apple with several proprietary frameworks like: AVKit, MapKit, SwiftData, etc.

When inspecting the generated modulemap for these frameworks, you can find a section labeled // MARK: - SwiftUI Additions, followed by some imports and another comment stating // Available when SwiftUI is imported with [AVKit|MapKit|SwiftData].

// ...
import SwiftUI
// ...

// MARK: - SwiftUI Additions

import AVFoundation
import Combine

// Available when SwiftUI is imported with AVKit
/// A view for showing the audiovisual contents of an `AVPlayer`
/// including system-provided playback controls and behaviors.
@available(iOS 14.0, macOS 11.0, watchOS 7.0, tvOS 14.0, *)
public struct VideoPlayer<VideoOverlay> : View where VideoOverlay : View {

    /// Creates a `VideoPlayer` with the specified parameters.
    ///
    /// - Parameters:
    /// 	- player: The AVPlayer whose contents will be rendered, or nil if
    ///		there is no player.
    /// 	- videoOverlay: A closure returning a VideoOverlay view to be placed atop the
    ///		player's content. This view is fully interactive, but is placed
    ///		below the system-provided playback controls and will only receive
    ///		unhandled events.
    public init(player: AVPlayer?, @ViewBuilder videoOverlay: () -> VideoOverlay)

From what I've found so far, it looks like for every framework where some SwiftUI additions are provided, there is another framework titled _FrameworkName_SwiftUI (i.e. _SwiftData_SwiftUI, _MapKit_SwiftUI, _AVKit_SwiftUI). These frameworks are importing the base framework, and defining correspondent SwiftUI types to be used in conjunction with the types found in the base framework.
So far this is identical to the approach of creating a dedicated LibraryUI module mentioned above.

What I can't figure out is how to forward / export the contents of these specialised frameworks from the base framework in the presence of SwiftUI import declaration.
Using @_exported import in the base framework won't work since you end up with a circular dependency between LibraryKit and _Library_SwiftUI.

If you want to inspect the generated module maps yourself, just drop these imports inside a swift file and command + click them. (I've also attached a screenshot for convenience)

import AVKit
import _AVKit_SwiftUI
import _MapKit_SwiftUI
import _SwiftData_SwiftUI

Is there any particular approach available that allows conditional export of symbols only if another's framework import definition is present?

Thank you!

D.

This is a private/prototype feature called cross-import overlays; it's not been formalized for public use.

4 Likes