【发布时间】:2020-04-09 09:38:14
【问题描述】:
我有一对基本上是双胞胎的应用程序——一个是客户端,另一个是服务器。它们共享许多相同的代码,并且都使用相同的 NSDocument 子类来实现它们共享的文档格式。客户端应用程序有一个用户界面,允许用户以可视方式处理文档,但服务器应用程序没有(尽管它确实作为常规应用程序运行,而不是作为守护程序运行),它被设计为不可见地运行。
问题在于,当文档放在其图标上时,服务器应用程序会被触发。如果服务器应用程序正在运行而客户端应用程序未运行,并且用户双击文档,也会触发服务器应用程序。在这种情况下,我希望启动服务启动客户端应用程序并打开文档,而是尝试使用服务器应用程序打开文档。我已经自定义了 NSApplicationDelegate application:openFile: 方法,以便服务器应用程序拒绝在这种情况下实际打开文档,但我想要的是 NSApplicationDelegate 不使用文档打开事件调用它。这让用户感到困惑,因为他们希望双击文档来打开客户端应用程序,无论服务器应用程序是否正在运行。
Apple 的 Core Foundation Keys 文档似乎表明这样做的方法是使用 LSHandlerRank 属性。
对于客户端应用,我已将其设置为“所有者”。
<key>LSHandlerRank</key>
<string>Owner</string>
对于服务器应用程序,我将其设置为“无”。
<key>LSHandlerRank</key>
<string>None</string>
不幸的是,这没有效果。如果客户端应用程序没有运行,我仍然可以将文档放在服务器应用程序图标上,或者双击文档以使服务器应用程序前进。
我认为可能有希望的另一个属性是 CFBundleTypeRole。客户端应用程序的 plist 将此设置为“编辑器”。
<key>CFBundleTypeRole</key>
<string>Editor</string>
该属性的文档非常少,但确实说“无”是一个选项。所以我在服务器应用程序 plist 中进行了尝试,然后我无法再以编程方式打开我的 NSDocument 文件。另一方面,将文档放在服务器应用程序图标上仍然会导致图标亮起,因此 Launch Services 显然仍然认为服务器应用程序可以处理这种类型的文件。
总而言之,我需要对 plist 进行一些更改,以便我仍然可以以编程方式处理与我的 NSDocument 子类关联的文件,但我不希望 Launch Services 知道我的(服务器)应用程序可以使用这些文件。这可能吗?
---- 跟进彼得·霍西的回答----
感谢您的回答。我不知道 lsregister shell 命令,它看起来很方便。转储会在我的机器上产生 46 兆字节的数据!
但是,我很确定这不是缓存问题。虽然我的电脑有多个服务器应用程序副本,但这个问题是由客户发现的。他只有一个应用程序的副本,而且他只有很短的时间。我已经一年多没有更改 plist 的内容了,所以他的系统上不会有任何缓存。
您建议不要使用 Launch Services,但我没有说清楚,我没有利用它,并且不希望 Launch Services 打开我的文档(至少不使用我的应用程序的服务器版本)。事实上,我已经成功地修改了这个应用程序,如果 Launch Services 确实请求服务器应用程序打开一个文档,它会忽略这个请求。通过使用openDocumenWithContentsOfURL 的内部 TCP/IP 服务器来打开文档,如下所示:
[sharedDocumentController openDocumentWithContentsOfURL:databaseURL display:openWindows error:&err];
openDocumenWithContentsOfURL 方法似乎要求为文档类型设置 plist。我的问题是,这也告诉 Finder 这个应用程序可以处理我不想要的这种类型的文档。所以我正在寻找一种可以在应用程序中使用 NSDocument 的方法,但不将其暴露给 Finder(所以我认为不要将它暴露给 Launch Services)。也许这是不可能的。
是否有一些方法可以打开没有 URL 的文档,这样扩展名是什么或 plist 的设置方式都无关紧要?我在 NSDocumentController 类中没有看到任何这样的记录方法。在我看来,测试似乎证实了 NSDocument 类依赖于 plist 将文件扩展名链接到 NSDocument 子类。
如果有办法改变 plist 来做到这一点,那么我肯定需要使用 lsregister 来清除缓存来测试这个:)
【问题讨论】:
标签: macos cocoa info.plist