Swift package

swift-marker-protocols

Lightweight adapters that preserve concrete Self for framework base classes

Extend framework classes without erasing subclasses

Swift does not allow every use of Self in an extension on a non-final class. That makes otherwise reusable framework helpers fall back to the base type. Empty marker protocols move the extension onto a protocol, where Self remains the concrete conforming type.

extension AVCaptureDevice {
  func withExclusiveLock(
    perform operation: (AVCaptureDevice) async -> Void
  ) async throws {
    try lockForConfiguration()
    defer { unlockForConfiguration() }
    await operation(self)
  }
}
Before
extension _AVCaptureDeviceProtocol {
  func withExclusiveLock(
    perform operation: (Self) async -> Void
  ) async throws {
    try lockForConfiguration()
    defer { unlockForConfiguration() }
    await operation(self)
  }
}
After

The same technique enables generic properties such as LayoutProxy<Self> on Cocoa views and exposes an associated Wrapped type when constraining generic optionals.

extension _CocoaViewProtocol {
  var layoutProxy: LayoutProxy<Self> {
    .init(self)
  }
}
ProductMarker families
SwiftMarkerProtocols_OptionalProtocol, _AnyKeyPathProtocol
FoundationMarkerProtocols_NotificationCenterProtocol plus Swift markers
QuartzCoreMarkerProtocols_CALayerProtocol
AVFoundationMarkerProtocols_AVCaptureDeviceProtocol
CocoaMarkerProtocolsPlatform view and view-controller protocols
MarkerProtocolsUmbrella import for targets that intentionally need all families

Import the narrow product for the framework you extend – SwiftMarkerProtocols, FoundationMarkerProtocols, QuartzCoreMarkerProtocols, AVFoundationMarkerProtocols, or CocoaMarkerProtocols. The MarkerProtocols umbrella is available when a target deliberately needs all of them.