A modern macOS library for getting selected text with multiple fallback strategies, smart volume management, and powerful pasteboard utilities.
It's a part of Easydict.
-
✅ Multiple Text Retrieval Strategies
- Accessibility: Get selected text via Accessibility API (AXUI)
- Menu Action: Get selected text by menu bar copy action
- Keyboard Shortcut: Get selected text by
Cmd+Cwith muted system volume - AppleScript: Get selected text from browsers using AppleScript
- Auto: Intelligent fallback with multiple methods
- Custom Strategy Arrays: Define your own combination of strategies
-
✅ Smart Fallback System
- Configurable strategy combinations
- Automatic retry with different methods
- Graceful error handling and recovery
-
✅ Pasteboard Protection
- Backup and restore pasteboard contents
- Execute temporary tasks without polluting user's pasteboard
- Volume management to prevent system beep sounds
-
✅ Cross-Language Support
- Modern Swift API with async/await
- Objective-C compatibility
-
✅ Clean Architecture
- Manager-based design
- Separate concerns (Text, Accessibility, Pasteboard)
- Extensible and maintainable code structure
Add the following to your Package.swift:
dependencies: [
.package(url: "https://github.com/tisfeng/SelectedTextKit.git", from: "2.0.0")
]Or add it through Xcode: File → Add Package Dependencies
import SelectedTextKit
private let textManager = SelectedTextManager.shared
func example() async {
do {
// Option 1: Use auto strategy (recommended for most cases)
if let selectedText = try await textManager.getSelectedText(strategy: .auto) {
print("Selected text: \(selectedText)")
}
// Option 2: Use custom strategy array with ordered fallbacks
let strategies: [TextStrategy] = [.accessibility, .menuAction, .shortcut]
if let text = try await textManager.getSelectedText(strategies: strategies) {
print("Text from custom strategies: \(text)")
}
// Option 3: Use specific strategies for browsers (order matters)
let browserStrategies: [TextStrategy] = [.appleScript, .accessibility]
if let text = try await textManager.getSelectedText(strategies: browserStrategies) {
print("Text from browser: \(text)")
}
// Option 4: Use individual strategy methods
if let text = try await textManager.getSelectedText(strategy: .menuAction) {
print("Text from menu copy: \(text)")
}
// Option 5: Use shortcut strategy with muted volume
if let text = try await textManager.getSelectedText(strategy: .shortcut) {
print("Text from shortcut copy: \(text)")
}
} catch {
print("Error: \(error)")
}
}// All available strategies
public enum TextStrategy {
case auto // Intelligent fallback (accessibility → menu action)
case accessibility // Get text via Accessibility API
case appleScript // Get text from browsers via AppleScript
case menuAction // Get text via menu bar copy action
case shortcut // Get text via Cmd+C (with muted volume)
}
// Create ordered strategy arrays (execution order matters!)
let browserStrategies: [TextStrategy] = [.appleScript, .accessibility, .menuAction, .shortcut]
let fallbackStrategies: [TextStrategy] = [.accessibility, .menuAction, .shortcut]getSelectedText(strategy: TextStrategy)- Get text using a specific strategygetSelectedText(strategies: [TextStrategy])- Get text using multiple strategies with ordered fallback
| Strategy | Description | Best For |
|---|---|---|
.auto |
Smart fallback (accessibility → menu action) | Recommended - Most reliable |
.accessibility |
Direct Accessibility API | Fast, lightweight access |
.appleScript |
Browser automation via AppleScript | Safari, Chrome, Firefox |
.menuAction |
System menu bar copy action | When accessibility is limited |
.shortcut |
Cmd+C with muted system volume | Universal compatibility |
- macOS 11.0+
- Swift 5.7+
MIT License - see LICENSE for details.