Swift package
Cross-platform Cocoa names for compatible UIKit and AppKit types
UIKit and AppKit often provide compatible types under different prefixes. CocoaAliases maps those pairs to stable Cocoa* names so shared extensions and infrastructure do not repeat the same declaration.
#if canImport(UIKit)
import UIKit
extension UIView {
@discardableResult
func hidden(_ isHidden: Bool) -> Self {
self.isHidden = isHidden
return self
}
}
#elseif canImport(AppKit)
import AppKit
extension NSView {
@discardableResult
func hidden(_ isHidden: Bool) -> Self {
self.isHidden = isHidden
return self
}
}
#endif
import CocoaAliases
extension CocoaView {
@discardableResult
func hidden(_ isHidden: Bool) -> Self {
self.isHidden = isHidden
return self
}
}
The public aliases cover much more than UIView and NSView:
| Area | Shared names |
|---|---|
| UI foundations | CocoaView, CocoaViewController, CocoaWindow, CocoaResponder |
| Visual values | CocoaColor, CocoaImage, CocoaFont, CocoaFontDescriptor |
| Controls | CocoaButton, CocoaTextField, CocoaSlider, CocoaStackView |
| Collections | CocoaCollectionView, CocoaTableView and diffable data-source aliases |
| Layout | CocoaLayoutGuide, CocoaLayoutPriority, CocoaDirectionalEdgeInsets |
| SwiftUI | CocoaHostingController, CocoaViewRepresentable, CocoaViewControllerRepresentable |
When a custom wrapper really needs a named representable type, conform once and implement the Cocoa-named lifecycle. The package forwards it to makeUIView / updateUIView on UIKit and makeNSView / updateNSView on AppKit.
import CocoaAliases
import SwiftUI
struct StatusView: CocoaViewRepresentable {
var isHidden: Bool
func makeCocoaView(context: Context) -> CocoaView {
CocoaView()
}
func updateCocoaView(
_ view: CocoaView,
context: Context
) {
view.isHidden = isHidden
}
}
For one-off bridges, CocoaComponent removes the representable declaration entirely. _CocoaViewProtocol and _CocoaViewControllerProtocol remain available for the narrower case where an extension must use a subclass’s concrete Self in a position a class extension cannot express.
Aliases remove type-name differences – not behavioral ones. Keep conditional compilation around APIs whose signatures or lifecycle differ, and compile every supported platform before exposing an alias from public API.