macOS Apple Help Authoring - Якоря

Я пытаюсь создать справочную книгу Apple для своего приложения для macOS, которое я готов выпустить. Однако я пытаюсь заставить якоря работать в моем HTML. По определению Apple:

«Якоря позволяют однозначно определять темы в справочной книге. Когда пользователь переходит по ссылке на якорь, Help Viewer загружает страницу, содержащую якорь. ... Якоря также можно использовать для загрузки привязанной страницы из приложения, вызов метода NSHelpManager openHelpAnchor: inBook: ... "

Пример от Apple: <a name="ArrivalTimesUsingStopID"></a>

В моем Apple у меня есть NSAlert, в котором есть следующий код для отображения кнопки справки, чтобы при нажатии на нее открывалась указанная строка привязки.

alert.showsHelp = true
alert.helpAnchor = NSHelpManager.AnchorName(stringLiteral: "ArrivalTimesUsingStopID")

При запуске кода отображается кнопка справки, и справка Mac открывается, но с сообщением об ошибке, что указанное содержимое не может быть найдено. Не уверен, почему якоря не работают, потому что я могу получить доступ к Справочнику, если перейду в меню «Справка» и открою его оттуда.

Кроме того, в документе Apple говорится:

Классы NSAlert, SFChooseIdentityPanel, SFCertificatePanel предоставляют кнопки справки для диалогов. Чтобы отобразить такую ​​кнопку справки и связать ее с привязкой в ​​книге справки, используйте методы setShowsHelp: и setHelpAnchor: в этих классах.

и документация по этим свойствам в состоянии NSAlert:

-setShowsHelp: YES добавляет кнопку справки на панель предупреждений. Когда кнопка помощи нажата, сначала консультируется с делегатом. Если делегат не реализует alertShowHelp: или возвращает NO, то - [NSHelpManager openHelpAnchor: inBook:] вызывается с нулевой книгой и привязкой, заданной -setHelpAnchor:, если есть. Исключение будет вызвано, если делегат вернет NO и не установлена ​​привязка справки.

... так что я знаю, что использую эти два правильно.

Я также понимаю, что мне нужно создавать файл .helpindex каждый раз, когда я обновляю HTML-документы моей справочной книги Apple. Я использую Help Indexer.app, который находится в дополнительных инструментах Xcode на сайте developer.apple.com. Я убеждаюсь, что:

  • У меня есть опция для индексации всех якорей.
  • Любая HTML-страница с привязкой имеет <meta name="ROBOTS" content="ANCHORS"> в заголовке, поэтому привязки индексируются.
  • Plist-файл моей справочной книги Apple правильно указывает на файл .helpindex, созданный «Help Indexer.app».

Но даже при всем этом я не могу заставить его открыть справочную книгу Apple с правильной привязкой или даже титульную страницу моей справочной книги Apple.

Я прочитал https://developer.apple.com/library/archive/documentation/Carbon/Conceptual/ProvidingUserAssitAppleHelp/user_help_intro/user_assistance_intro.html#//apple_ref/doc/uid-CH30000-90 / а>

от корки до корки несколько раз, и я не могу найти решение или где-либо в Интернете.

Я также пробовал открыть его вручную, но он просто открывает ту же ошибку, говоря, что указанный контент не может быть найден с помощью следующего кода:

let bookName = Bundle.main.object(forInfoDictionaryKey: "CFBundleHelpBookName") as! String
NSHelpManager.shared.openHelpAnchor("ArrivalTimesUsingStopID", inBook: bookName)

Использование nil для параметра inBook тоже не работает:

NSHelpManager.shared.openHelpAnchor("ArrivalTimesUsingStopID", inBook: nil)

Любые идеи?


person Mario A Guzman    schedule 05.12.2018    source источник


Ответы (2)


Я не уверен, что это ответ на данный момент, но это ответ, который, кажется, помогает. Мне не удалось заставить helpAnchor в предупреждении работать, но при использовании делегата справки метод, описанный ниже, работает.

Я начал свой день с попытки открыть Справочную книгу с помощью простого якоря. Я уверен, что раньше это работало с NSHelpManager, но не похоже на последние версии ОС.

Наблюдение за консолью при открытии справочной книги моего приложения, находящегося в стадии разработки, привело к следующему:

Opening URL help:openbook=%22com.ClueTrust.Cartographica.help*1.5.2d1%22 with application <FSNode 0x6000006a1b40> { isDir = y, path = '/System/Library/CoreServices/HelpViewer.app' }

Открытие моего якоря с использованием NSHelpManager привело к:

Opening URL help:anchor=SpatialJoinOperation%20bookID=%22com.ClueTrust.Cartographica.help%22%20appID=%22com.ClueTrust.Cartographica%22 with application <FSNode 0x6000006a8260> { isDir = y, path = '/System/Library/CoreServices/HelpViewer.app' }

И это не привело к открытию моего якоря.

Я попытался добавить *<version> к своему URL:

Opening URL help:anchor=SpatialJoinOperation%20bookID=%22com.ClueTrust.Cartographica.help*1.5.2d1%22%20appID=%22com.ClueTrust.Cartographica%22 with application <FSNode 0x600000682c20> { isDir = y, path = '/System/Library/CoreServices/HelpViewer.app'

Однако, заглянув глубже в консоль, я заметил, что это определенно запускает сетевой запрос и возвращается unsupported URL.

Мне не ясно, не работает ли help:anchor=... больше, но я нашел относительно простой, но раздражающий способ решения проблемы.

Якоря в справке обязательно будут открываться при использовании help: URL, отформатированного как file: URL и содержащего якорь; и они откроются в правильном месте якоря.

Для этого необходимо найти конкретную справочную книгу и файл HTML, чтобы вы могли точно указать, где открыть.

    NSURL *helpBookURL = [NSBundle.mainBundle URLForResource:@"Cartographica" withExtension:@"help"];
    NSBundle *helpBundle = [NSBundle bundleWithURL:helpBookURL];
    NSURL *helpPageURL = [helpBundle URLForResource:@"Spatial_Join" withExtension:@"html"];
    NSURLComponents *urlParts = [NSURLComponents componentsWithURL:helpPageURL resolvingAgainstBaseURL:NO];
    urlParts.scheme=@"help";
    urlParts.fragment=@"SpatialJoinOperation";
    NSURL *finalHelpURL = urlParts.URL;
    [NSWorkspace.sharedWorkspace openURL:finalHelpURL];

По сути:

  1. Получите URL-адрес справочной книги (необходимо сделать это таким образом, чтобы получить его из пути к ресурсу, поэтому мы используем NSBundle)
  2. Найдите страницу, содержащую ссылку, на основе предшествующих знаний (в данном случае Spatial_Join.html - это наше имя файла, поэтому пакет будет искать его по имени и расширению.
  3. Используйте интерфейс NSURLComponents, чтобы изменить NSURL, изменив схему с file на help и добавив наш ахор в fragment.
  4. Наконец, откройте вновь созданный URL

Это некрасиво, но кажется эффективным и безопасным, по крайней мере, в приложении macOS без песочницы до версии 10.15.

Обратите внимание, что я мог бы сделать здесь некоторые предположения относительно названия справочной книги, но для целей иллюстрации это кажется более ясным, и из-за того, как работают ресурсы, неясно, будут ли эти предположения об именах уместны во всех ситуациях.

Моим окончательным результатом был вспомогательный метод:

- (void)openHelpPage:(NSString*)pageName anchor:(NSString  * _Nullable)anchor bookName:(NSString * _Nullable)bookName
{
    NSURL *helpBookURL = [NSBundle.mainBundle URLForResource:bookName withExtension:@"help"];
    NSBundle *helpBundle = [NSBundle bundleWithURL:helpBookURL];
    NSURL *helpPageURL = [helpBundle URLForResource:pageName withExtension:@"html"];
    NSURLComponents *urlParts = [NSURLComponents componentsWithURL:helpPageURL resolvingAgainstBaseURL:NO];
    urlParts.scheme=@"help";
    if (anchor)
        urlParts.fragment=anchor;
    NSURL *finalHelpURL = urlParts.URL;
    [NSWorkspace.sharedWorkspace openURL:finalHelpURL];
}

Синтаксис сайта звонка:

// to specific anchor on a page
[self openHelpPage: @"Spatial_Join" anchor: @"SpatialJoinOperation" helpBook: nil];
// to specific page
[self openHelpPage: @"Spatial_Join" anchor: nil helpBook: nil];

Я попытался получить пакет справки с [NSBundle bundleWithIdentifier:], используя идентификатор пакета справки, но он вернул ноль. Однако [NSBundle URLForResource:withExtension] примет nil аргумент для resourceName и получит первый элемент, соответствующий расширению. В моем случае (а я считаю, что многие) существует только один help ресурс, поэтому это позволяет использовать метод, который не требует знания имени справочной книги приложения.

person gaige    schedule 09.08.2020

Я наконец смог заставить это работать в изолированном приложении.

Если вы используете кнопку «Справка» напрямую, вы можете использовать что-то вроде:

@IBAction func helpButtonAction(_ sender: Any)
{
    if  let bookName = Bundle.main.object(forInfoDictionaryKey: "CFBundleHelpBookName") as? String {
        NSHelpManager.shared.openHelpAnchor("MY_ANCHOR_HERE", inBook: bookName)
    }
}

Если вы используете NSAlert(), вы можете использовать его кнопку справки с привязкой следующим образом:

let alert = NSAlert()
...
alert.showsHelp = true
alert.helpAnchor = NSHelpManager.AnchorName("MY_ANCHOR_HERE")

Несколько вещей, которые я усвоил на собственном горьком опыте:

  1. Убедитесь, что ваша HTML-страница для вашей Справочной книги имеет правильную настройку для привязки:

<meta name="robots" content="anchors"> в разделе <head>, а также соответствующий тег заголовка, например:

<a name="MY_ANCHOR_HERE"></a> в вашем <body> разделе.

  1. Убедитесь, что вы используете Help Indexer.app для индексации своей справочной книги. Я обнаружил, что это не сработает, если вы не проиндексируете справочную книгу с помощью этого приложения. Это приложение можно загрузить с developer.apple.com в разделе "Другие загрузки". Обычно они выпускают новую версию с каждым обновлением Xcode. Вы хотите найти дополнительные инструменты, и конкретное приложение индексатора будет расположено в

    Дополнительные инструменты ›Утилиты› Справка Indexer.app

  2. Кроме того, macOS не любит, когда у вас есть несколько справочных книг. Это означает наличие нескольких копий вашего приложения на вашем Mac независимо от того, где они находятся. Это может быть ваша папка отладки и папка приложения как ваши наиболее распространенные места. Я обнаружил, что удаление копии в папке «Приложения» обычно помогает macOS не запутаться при открытии Справочной книги. Я также обнаружил, что он открывает более старые версии Справочной книги, поэтому лучше убедиться, что у вас есть только одна копия вашего приложения на Mac при отладке справочных книг.

Но кроме этого, они должны нормально открываться с помощью простой строки привязки и нескольких строк кода в зависимости от того, как вы отображаете кнопку справки!

person Mario A Guzman    schedule 06.09.2020