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, such as SwiftMarkerProtocols, FoundationMarkerProtocols, QuartzCoreMarkerProtocols, AVFoundationMarkerProtocols, or CocoaMarkerProtocols. The MarkerProtocols umbrella is available when a target deliberately needs all of them.