Skip to content

Repository files navigation

ClipboardKit

Unified clipboard observation APIs for Apple platforms.

ClipboardKit provides a cross-platform abstraction over NSPasteboard (macOS) and UIPasteboard (iOS/visionOS) with a reactive, async/await-based observation interface.

Features

  • macOS: Silent clipboard monitoring via NSPasteboard.general.changeCount polling
  • iOS/visionOS: Privacy-aware two-phase clipboard detection (detect types silently, read on explicit user action)
  • Swift 6 with strict concurrency checking
  • AsyncStream-based observation for structured concurrency
  • Zero dependencies

Requirements

  • Swift 6.0+
  • macOS 14+ / iOS 17+ / watchOS 10+ / tvOS 17+ / visionOS 1+

Installation

Swift Package Manager

Add ClipboardKit to your Package.swift:

dependencies: [
    .package(url: "https://github.com/YOUR_ORG/ClipboardKit.git", from: "0.1.0")
]

Then add "ClipboardKit" to your target's dependencies.

Usage

macOS — Silent Clipboard Monitoring

import ClipboardKit

let observer = MacOSClipboardObserver()
for await item in observer.observe() {
    switch item {
    case .text(let string):
        print("Copied text: \(string)")
    case .url(let url):
        print("Copied URL: \(url)")
    case .image(let data):
        print("Copied image: \(data.count) bytes")
    case .rich(let rtf, let plain):
        print("Copied rich text: \(plain)")
    }
}

iOS — Privacy-Aware Clipboard Detection

On iOS 16+, reading clipboard content triggers a system paste permission dialog. ClipboardKit handles this with a two-phase approach:

import ClipboardKit

let observer = IOSClipboardObserver()

// Phase 1: Detect changes silently (no dialog)
for await event in observer.observeChanges() {
    switch event {
    case .changed(let types):
        if types.hasText {
            // Show "New clipboard content" UI indicator
            showPasteButton()
        }
    case .captured:
        break // Not emitted on iOS
    }
}

// Phase 2: Read content on explicit user action (triggers dialog)
if let item = await observer.readCurrentItem() {
    // Process the clipboard content
}

Platform Differences

Feature macOS iOS/visionOS
Silent content read Yes No (paste dialog)
Change detection changeCount polling changeCount polling
Type detection Read content directly hasStrings/hasURLs/hasImages
Observer protocol ClipboardObserving ClipboardChangeObserving
Poll interval default 250ms 1s

API Reference

Types

  • ClipItem — Content captured from the clipboard (text, URL, image, rich text)
  • ClipboardEvent — Platform-abstracted clipboard events
  • DetectedContentTypes — Available content types (for iOS silent detection)

Protocols

  • ClipboardObserving — Full content observation (macOS)
  • ClipboardChangeObserving — Change detection without content read (iOS)

Observers

  • MacOSClipboardObserver — macOS NSPasteboard polling observer
  • IOSClipboardObserver — iOS UIPasteboard privacy-aware observer

License

MIT License. See LICENSE for details.

About

Unified clipboard observation APIs for Apple platforms (macOS, iOS, visionOS)

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages