如何使得Macos的剪切板感知fileURL并当fileURL被执行paste 动作时 回调到某个监听的函数 从而来填充file content

问题及尝试:

我在做一个跨平台文件拷贝的功能,文件可能是从其他操作系统比如Linux 或者Windows 拷贝到Macos上, 但是我试过所有可以hook NSPasteboard的方法,确实没有找到可以监听macos 剪切板的方法,因为fileURL 确实在NSPasteboard是一个类型的数据,这个数据的value 其实是一个路径,我们可以通过下载macos 里面的一个工具 Pasteboard Viewer: ‎Pasteboard Viewer on the App Store

从工具中我们可以看到当我自macos 本地copy一个file时 会有fileURL的数据类型被加到NSPasteboard里面 从截图可以得知 fileURL数据类型的值其实就是一个路径,因此我们通过NSPasteboard 提供的回调方法

@protocol NSPasteboardItemDataProvider <NSObject>

/* Implemented by the data provider of a pasteboard item, to provide the data for a particular UTI type.

*/

@required

  • (void )pasteboard:(nullable NSPasteboard *)pasteboard item:(NSPasteboardItem *)item provideDataForType:(NSPasteboardType)type NS_SWIFT_NONISOLATED;

无法在paste的时候才触发到这个方法 但是其他的数据类型比如 plain text/HTML/Bitmap 都是可以自回调的时候触发到这里,这时你就可以在回调的这个函数里去fetch 具体的内容 可能这些内容来自其他平台,但是fileURL不行, 我尝试过,现象是一旦加到NSPasteboard里, 这个方法就会被触发,我也想了一下原因,可能是因为fileURL的数据类型的值就是一个文件路径, 所以也决定了这个数据大小不会很大,不像HTML 或者是Bitmap 可大可小,这个文件路径的长度是可以预估的,还有一个原因可能是因为如果fileURL被加入到了NSPasteboard里但是不提供给其具体的路径,当用户在Finder 或者其他应用(支持文件拷贝)里进行粘贴时,用户是无法进行paste的因为paste选项不会被高亮。

探究Microsoft Remote Desktop:

这也是一个支持文件拷贝的跨系统的app,当我运行mac版本的app 从windows里往mac拷贝文件时, 通过Pasteboard Viewer,我们可以看到RDP创建里一个临时的Placeholder文件, 如下:
当我在RDP里面的windows copy一个aa.txt时候,RDP会在macos上创建一个Placeholder文件,从而监听这个Placeholder文件 当用户粘贴时, 空壳子文件才会fetch 远端windows的内容到Placeholder文件,当Placeholder文件内容fetch 完毕时,macos 的paste动作起作用, 我可以听到macos的操作声 文件被paste到了用户指定的位置。在查看了RDP的流程后 ,给了我一些灵感,发现从监听NSPasteboard 切换到了监听创建的PlaceHolder 文件,那问题又来了 怎么监听这个placeholder文件呢?

寻找Macos提供的API:

为了监听创建的PlaceHolder文件,我们需要寻找文件监听API,当时有两个思路一个是因为FileURL也属于NSURL的一种,所以查看NSURL的监听API自然是一个路子,还有一个思路是因为placeholder文件也属于文件,所以自然也会去看filesystem相关的API, 事实证明第一条路子不通,第二条路有效, 因此我找到了两个Macos提供的API,NSFilePresenter 和 NSFilecoordinator,里面提供了read 回调方法 relinquishPresentedItemToReader: | Apple Developer Documentation

所以方法就是当文件在远端系统拷贝时,触发消息发送到本地,本地创建Placeholder,并在创建完placeholder 后 将这个fileURL注册成一个NSFilePresenter 并将创建的filepresenter 实例加入到NSFileCoordinator上,这样当用户执行paste 操作时 NSPasteboard会访问这个PlaceHolder 并回调到relinquishPresentedItemToReader, 在这里不执行Read()方法NSPasteboard就不会被释放就会一直等待 直到在这个方法里执行read, 所以这样就block了NSPasteboard去粘贴文件 与此同时可以从远端fetch 文件内容。

相关推荐
feifeigo12313 小时前
基于隐马尔可夫模型(HMM)的孤立词语音识别系统
人工智能·语音识别·xcode
m0_5358175515 小时前
macOS上Claude Code安装配置保姆级教程:国内直连API,从0到1跑通(附避坑指南)
gpt·macos·ai·node.js·claude·claudecode·88api
basketball61620 小时前
Golang:基本输入输出使用方法总结
开发语言·golang·xcode
我有满天星辰20 小时前
Mac 安装 Redis + Spring Boot 整合 Redis(完整实战指南)
spring boot·redis·macos
游戏开发爱好者821 小时前
iOS开发工具推荐:Xcode、AppCode、SwiftLint使用心得与效率提升
ide·vscode·macos·ios·个人开发·xcode·敏捷流程
whyfail21 小时前
Codex 下载安装指南:Windows 和 macOS 官方版下载
windows·macos·codex
感谢地心引力21 小时前
在Claude Code里面使用Deepseek-v4,支持mac和Windows双系统
人工智能·windows·macos·ai·deepseek·claude code
感谢地心引力1 天前
在codex里面使用Deepseek-v4,支持mac和windows双系统
windows·gpt·macos·ai·codex·deepseek
搬砖的小码农_Sky1 天前
AI Agent:macOS Sequoia 部署 OpenClaw 完整教程
人工智能·macos·ai·人机交互
白玉cfc2 天前
【iOS】底层原理:类的加载
ios·objective-c·xcode