Swift package
Lightweight adapters that preserve concrete Self for framework base classes
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)
}
}
extension _AVCaptureDeviceProtocol {
func withExclusiveLock(
perform operation: (Self) async -> Void
) async throws {
try lockForConfiguration()
defer { unlockForConfiguration() }
await operation(self)
}
}
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)
}
}
| Product | Marker families |
|---|---|
SwiftMarkerProtocols | _OptionalProtocol, _AnyKeyPathProtocol |
FoundationMarkerProtocols | _NotificationCenterProtocol plus Swift markers |
QuartzCoreMarkerProtocols | _CALayerProtocol |
AVFoundationMarkerProtocols | _AVCaptureDeviceProtocol |
CocoaMarkerProtocols | Platform view and view-controller protocols |
MarkerProtocols | Umbrella 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.