Cocoa 使用NSPasteboard数据启动应用程序

Cocoa 使用NSPasteboard数据启动应用程序,cocoa,nspasteboard,appleevents,Cocoa,Nspasteboard,Appleevents,我希望使用NSPasteboard数据启动应用程序(或使用AppleEvents发送给他们),就像在Finder中拖放文件、文本、图像到应用程序(或在Dock中)并启动或调用应用程序中的数据一样 像LSOpenFromURLSpec这样的启动服务功能只对文件有效,我看到有一个选项可以选择AppleEvents的任意参数,但我不知道如何实现这一点 另一个问题是沙盒,但我不确定这是否可能 谢谢。当您是接收者时,发生的情况取决于用户正在丢弃的内容: 一个或多个文件 应用程序将发送一个或多个打开的文档

我希望使用NSPasteboard数据启动应用程序(或使用AppleEvents发送给他们),就像在Finder中拖放文件、文本、图像到应用程序(或在Dock中)并启动或调用应用程序中的数据一样

像LSOpenFromURLSpec这样的启动服务功能只对文件有效,我看到有一个选项可以选择AppleEvents的任意参数,但我不知道如何实现这一点

另一个问题是沙盒,但我不确定这是否可能


谢谢。

当您是接收者时,发生的情况取决于用户正在丢弃的内容:

  • 一个或多个文件 应用程序将发送一个或多个打开的文档Apple事件。在尝试document controller之前,NSApplication尝试向其应用程序委托发送至少一条(实际上应该只有一条,但在一些版本中此消息已被破坏)消息

  • 一个或多个URL(不属于文件:scheme) 向应用程序发送一个或多个get URL事件。您需要为此实现一个Apple事件处理程序。很方便,这就是我们使用的示例

  • 任何其他数据 你需要这样做。哪个服务将用于Dock Drop是根据类型自动检测的,我不知道它如何在多个匹配中进行选择;没有办法只指定某些服务可用于Dock。关于NSPasteboard,您猜对了:您使用用于I/O的粘贴板实现服务


当您是发件人时:

  • 发送文件 最简单的方法是使用启动服务。这将代表您发送适当的Apple活动

  • 发送URL 同样,Launch Services将为您发送必要的Apple活动。实际上,在现代代码中,您可能会对文件URL和非文件URL使用相同的LSOpen API

  • 发送任何其他数据 由于接收应用程序必须实现服务,因此您也必须实现服务

    最困难的部分是发现:您需要知道要执行哪项服务,并且它需要可用。我假设您知道将发送到哪个应用程序(模拟投递),这对大多数打算发送到服务的人来说是一个优势。我敢肯定,您只需查看目标应用程序的Info.plist,就可以找到与您自己拥有的类型最匹配的服务

    一个潜在的问题是不能指定应用程序包。您必须希望目标应用程序的服务能够显示在“服务”菜单中,并且您必须自己找出正确的菜单项名称。(尝试使用您自己的“服务”菜单中显示的内容,尝试导出对应关系。)即使您提供了正确的服务项名称并且服务已启用,也不能保证服务将由您正在查看的捆绑包中的应用程序执行。它可能是不同的版本,甚至可能是其他版本(可能,取决于名称的构造方式)具有同名服务的不同应用程序

    你可能想知道这件事


那么您只想启动一个特定的应用程序并发送一个文档给它打开吗?我知道如何启动文档,但我对其他数据感兴趣,如文本、图像,它们可能会接受(如info.plist文档类型中的定义)。基本上,我希望通过编程将一些数据放到另一个应用程序上,并获得与在Finder中将数据放到应用程序上相同的效果。这解决了目标应用程序如何响应丢弃的问题,但我感兴趣的是如何将我的应用程序中的数据打包并“发送”到另一个应用程序(即拖到)以调用相同响应的方式(取决于发送的数据)。对于文件和URL,这可以通过启动服务实现,但我不知道如何对任意数据实现这一点,除了可能的AppleEvents。谢谢。@GenericPtr:D'oh。我之前就理解了这一点,但后来忘记了。对不起,我会更新我的答案。我认为服务不是正确的途径,因为许多应用程序都可以接受丢弃的数据各种数据类型,但他们没有为他们注册任何服务。例如,我在自己的应用程序中这样做是为了接受文本拖动以创建新文件。没关系!我注册了一个服务来接受文本拖动。如果我必须通过菜单项名调用服务,而没有捆绑ID,那么我看不出这是如何工作的,可能需要读取fo.plists,我认为这在沙箱中是不可能的。允许TextEdit接受文本的服务名为“New TextEdit Window Contain Selection”,但它不出现在“服务”菜单中(与我的应用程序使用的服务相同)。谢谢。@GenericPtr:默认情况下,除非指定上下文,否则所有服务都被禁用(即使上下文规范为空)。对于TextEdit来说,这可能是故意的,也可能不是故意的。无论如何,您可以在键盘窗格中打开系统上存在的任何服务。