Swift package
Reusable Cocoa bases, builders, bridges, and framework conveniences
CocoaExtensions is a broad Apple UI toolbox. Its value is not a new architecture; it is a set of small, reusable pieces for construction, menus, collections, SwiftUI bridging, and graphics.
Custom base classes centralize programmatic and coder-based initialization in one overridable hook.
@MainActor
final class StatusView: CustomCocoaView {
let label = CocoaTextField()
override func _init() {
super._init()
// Build hierarchy and constraints once.
}
}
Even a one-off platform view normally needs a complete UIViewRepresentable and NSViewRepresentable pair.
#if canImport(UIKit)
import SwiftUI
import UIKit
struct StatusComponent: UIViewRepresentable {
var isHidden: Bool
func makeUIView(context: Context) -> UIView {
UIView()
}
func updateUIView(_ view: UIView, context: Context) {
view.isHidden = isHidden
}
}
#elseif canImport(AppKit)
import AppKit
import SwiftUI
struct StatusComponent: NSViewRepresentable {
var isHidden: Bool
func makeNSView(context: Context) -> NSView {
NSView()
}
func updateNSView(_ view: NSView, context: Context) {
view.isHidden = isHidden
}
}
#endif
import CocoaExtensions
import SwiftUI
struct StatusComponent: View {
var isHidden: Bool
var body: some View {
CocoaComponent(CocoaView()) { view, _ in
view.isHidden = isHidden
}
}
}
CocoaComponent also accepts construction closures, coordinators, view controllers, and an optional sizeThatFits closure. Reach for CocoaViewRepresentable instead when the bridge deserves its own named type.
| Need | API |
|---|---|
| Shared initialization | CustomCocoaView, CustomCocoaViewController, _init() |
| Controller-owned content | @CustomView, @CustomWindow |
| SwiftUI bridge | CocoaComponent for views and view controllers |
| AppKit command UI | MenuItemsBuilder, CustomToolbar, closure-backed NSMenuItem |
| Collection infrastructure | Typed registration, dequeueing, supplementary views, layout erasure |
| Drawing and layout math | CATransform3D, CGAffineTransform, CGPath, and axis helpers |
Result builders make nested menus read like their visual structure while closure-backed items keep actions local.
let menu = NSMenu("Actions") {
NSMenuItem("Refresh") { refresh() }
NSMenu.Submenu("Export") {
NSMenuItem("JSON") { exportJSON() }
}
}
Import the narrow product that replaces concrete boilerplate, keep UI work on MainActor, and verify platform availability – AppKit and UIKit surfaces intentionally differ where the underlying frameworks differ.