У меня есть пара приложений, которые в основном близнецы - одно - клиент, а другое - сервер. Они совместно используют большую часть одного и того же кода и оба используют один и тот же подкласс NSDocument для реализации формата документа, который они совместно используют. Клиентское приложение имеет пользовательский интерфейс и позволяет пользователям визуально работать с документами, но серверное приложение не (хотя оно работает как обычное приложение, а не как демон), оно предназначено для невидимого запуска.
Проблема в том, что приложение сервера запускается, когда на иконку перетаскивается документ. Серверное приложение также запускается, если оно запущено, а клиентское приложение не запущено, и пользователь дважды щелкает документ. В этом случае я хочу, чтобы Launch Services запустил клиентское приложение и открыл документ, вместо этого он пытается открыть документ с помощью серверного приложения. Я настроил метод NSApplicationDelegate application:openFile:
так, чтобы приложение сервера отказывалось фактически открывать документ в этой ситуации, но я хочу, чтобы NSApplicationDelegate не вызывал его с событиями открытия документа. Это сбивает с толку пользователей, поскольку они ожидают, что двойной щелчок по документу откроет клиентское приложение, независимо от того, запущено приложение сервера или нет.
Документация Apple Core Foundation Keys, похоже, указывает на то, что способ сделать это - использовать LSHandlerRank свойство.
https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html# // apple_ref / doc / uid / TP40009249-SW1
Для клиентского приложения я установил это в «Владелец».
<key>LSHandlerRank</key>
<string>Owner</string>
Для серверного приложения я установил для него значение «Нет».
<key>LSHandlerRank</key>
<string>None</string>
К сожалению, это не дало эффекта. Я все еще могу перетащить документы на значок серверного приложения или дважды щелкнуть документ, чтобы вывести серверное приложение вперед, если клиентское приложение не запущено.
Еще одно свойство, которое, на мой взгляд, может быть многообещающим, - CFBundleTypeRole . В plist для клиентского приложения устанавливается значение «Редактор».
<key>CFBundleTypeRole</key>
<string>Editor</string>
Документация по этому свойству очень скудна, но в ней говорится, что «Нет» - это вариант. Поэтому я попробовал это в списке приложений сервера, и тогда я больше не мог программно открывать свои файлы NSDocument. С другой стороны, перетаскивание документа на значок приложения сервера still привело к тому, что значок загорелся, поэтому службы запуска, по-видимому, все еще считают, что приложение сервера может обрабатывать файлы этого типа.
Подводя итог, мне необходимо внести некоторые изменения в plist, чтобы я мог программно работать с файлами, связанными с моим подклассом NSDocument, но я не хочу, чтобы Launch Services знал, что мое (серверное) приложение может работать с этими документами. Возможно ли это?
---- Продолжение ответа Питера Хоси ----
Спасибо за этот ответ. Я не знал о команде оболочки lsregister, и она выглядит очень удобной. Дамп производит 46 мегабайт данных на моей машине!
Однако я уверен, что это не проблема кэширования. Хотя на моем компьютере имеется несколько копий серверного приложения, эта проблема была обнаружена клиентом. У него есть только одна копия приложения, и у него было только короткое время. Я не менял содержание plist более года, так что в его системе не было бы кешировать ничего.
Вы предлагаете не использовать Launch Services, но я не давал понять, что не принимаю Я не хочу, чтобы Launch Services открывал мои документы (по крайней мере, с серверной версией моего приложения). Фактически, я успешно изменил приложение, так что если Launch Services действительно запрашивает приложение сервера, чтобы открыть документ, он игнорирует этот запрос. Открытие документов выполняется через внутренний сервер TCP / IP, который использует openDocumenWithContentsOfURL
, например:
[sharedDocumentController openDocumentWithContentsOfURL:databaseURL display:openWindows error:&err];
Метод openDocumenWithContentsOfURL
, похоже, требует, чтобы plist был настроен для типа документа , Моя проблема в том, что это также говорит Finder, что это приложение может обрабатывать документы такого типа, которые я не хочу. Поэтому я ищу способ, которым я могу использовать NSDocument в приложении, но не предоставлять его Finder (так что я думаю, что не предоставлять его Launch Services). Возможно, это невозможно.
Существует ли какой-либо способ открытия документа без URL-адреса, чтобы не имело значения, что такое расширение или как составляется список? Я не вижу такого документированного метода в классе NSDocumentController. Мне кажется, и тестирование, кажется, подтверждает, что класс NSDocument использует plist для связи расширений файлов с подклассами NSDocument.
Если есть способ изменить plist, чтобы сделать это, то я определенно нужно будет использовать lsregister для очистки кэша, чтобы проверить это:)