开发基于Pasteboard的应用:如何检查复制文本的来源应用?
Hey there! Great question—tracking clipboard source apps is totally feasible on Apple platforms, though the approach differs a bit between macOS and iOS/iPadOS. Let’s walk through practical, actionable steps for each:
macOS 实现方案(10.13+)
macOS provides direct API access to the clipboard’s source application, making this straightforward.
步骤1:监听剪贴板变化
First, set up a listener for when the clipboard content changes using NSPasteboard.general's changeCount property or notifications:
import AppKit class ClipboardMonitor { private var lastChangeCount = 0 init() { startMonitoring() } func startMonitoring() { lastChangeCount = NSPasteboard.general.changeCount // Use a timer to check for changes, or observe the NSPasteboardChangedNotification Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] _ in self?.checkClipboard() } } private func checkClipboard() { let currentCount = NSPasteboard.general.changeCount guard currentCount != lastChangeCount else { return } lastChangeCount = currentCount // Get source app bundle ID if let sourceBundleID = NSPasteboard.general.sourceApplication { checkIfFromNonSpecifiedApp(sourceBundleID: sourceBundleID) } } }
步骤2:验证来源应用是否为指定运行应用
Next, check if the source app is your target app, and confirm that app is actually running:
private func checkIfFromNonSpecifiedApp(sourceBundleID: String) { let targetBundleID = "com.yourcompany.YourSpecifiedApp" // Replace with your app's bundle ID // Check if target app is running let isTargetAppRunning = NSWorkspace.shared.runningApplications.contains { app in app.bundleIdentifier == targetBundleID } // If target app is running AND clipboard source is NOT it, you've got your case if isTargetAppRunning && sourceBundleID != targetBundleID { print("Clipboard content came from a non-specified running app!") // Do your logic here } }
iOS/iPadOS 实现方案(14.0+)
iOS has stricter sandbox rules, but starting from iOS 14, Apple added sourceBundleID to UIPasteboardItem, letting you get the source app's bundle ID.
步骤1:请求剪贴板权限
First, add the NSClipboardUsageDescription key to your Info.plist to explain why you need clipboard access (required for iOS 14+):
<key>NSClipboardUsageDescription</key> <string>We need to check where your copied content comes from to improve your experience.</string>
步骤2:监听剪贴板变化并获取来源
Set up a listener for clipboard changes and retrieve the source bundle ID:
import UIKit class ClipboardMonitor { private var lastChangeCount = 0 init() { startMonitoring() // Observe UIPasteboardChangedNotification for immediate updates NotificationCenter.default.addObserver(self, selector: #selector(clipboardChanged), name: UIPasteboard.changedNotification, object: nil) } func startMonitoring() { lastChangeCount = UIPasteboard.general.changeCount } @objc private func clipboardChanged() { let currentCount = UIPasteboard.general.changeCount guard currentCount != lastChangeCount else { return } lastChangeCount = currentCount // Get source bundle ID from pasteboard items if let firstItem = UIPasteboard.general.items.first, let sourceBundleID = firstItem.sourceBundleID { checkIfFromNonSpecifiedApp(sourceBundleID: sourceBundleID) } } }
步骤3:验证来源(注意iOS沙盒限制)
On iOS, you can’t directly check if a third-party app is running due to sandbox restrictions. If your "specified app" is your own app, you can simply compare the source bundle ID to your app's ID:
private func checkIfFromNonSpecifiedApp(sourceBundleID: String) { let targetBundleID = Bundle.main.bundleIdentifier! // Your app's ID // If clipboard source is NOT your app, that's your case if sourceBundleID != targetBundleID { print("Clipboard content came from outside your app!") // Do your logic here } // For third-party specified apps: // You can't verify if they're running directly, but you can check if the source ID matches their bundle ID // Example: let thirdPartyTargetID = "com.othercompany.TargetApp" if sourceBundleID != thirdPartyTargetID { print("Clipboard content didn't come from the third-party target app") } }
关键注意事项
- macOS Permissions: No special permissions are needed for
NSPasteboard.sourceApplication, but if you need to interact with other apps' windows, you might need Accessibility permissions. - iOS Limitations: Sandbox rules prevent checking if third-party apps are running. You can only confirm if the clipboard content came from a specific bundle ID, not whether that app is currently active/running.
- Edge Cases: Some apps might not provide a source bundle ID (e.g., system apps or older apps), so handle
nilvalues gracefully.
内容的提问来源于stack exchange,提问作者Divya Patel

