Как установить приложение Какао в качестве веб-браузера по умолчанию?

Как установить приложение Какао в качестве веб-браузера по умолчанию?

Я хочу создать приложение, которое запускается по умолчанию, когда пользователь щелкает ссылку HTTP или HTTPS в других приложениях (Mail, iChat и т. д.).

github.com/Lord-Kamina/SwiftDefaultApps#usage-notes could help you as it allows to reassociate URI scheme handlers to different applications from its GUI.
Jaime Hablutzel 16.10.2018 18:28
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
32
1
13 173
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Чтобы создать приложение, которое может выступать в качестве веб-браузера по умолчанию, необходимо выполнить четыре шага. Первые три шага позволяют вашему приложению выступать в качестве обработчика ролей для соответствующих схем URL-адресов (HTTP и HTTPS), а на последнем этапе оно становится обработчиком ролей по умолчанию для этих схем.

1) Добавьте схемы URL-адресов, которые ваше приложение может обрабатывать, в файл info.plist вашего приложения.

Чтобы добавить поддержку http:// и https://, вам нужно добавить следующее в файл info.plist вашего приложения. Это сообщает ОС, что ваше приложение способно обрабатывать URL-адреса HTTP и HTTP.

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>http URL</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>http</string>
        </array>
    </dict>
    <dict>
        <key>CFBundleURLName</key>
        <string>Secure http URL</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>https</string>
        </array>
    </dict>
</array>

2) Напишите метод обработчика URL

Этот метод будет вызываться ОС, когда она хочет использовать ваше приложение для открытия URL-адреса. Неважно, к какому объекту вы добавляете этот метод, он будет явно передан диспетчеру событий на следующем шаге. Метод обработчика URL должен выглядеть примерно так:

- (void)getUrl:(NSAppleEventDescriptor *)event 
    withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
  // Get the URL
  NSString *urlStr = [[event paramDescriptorForKeyword:keyDirectObject] 
    stringValue];

  //TODO: Your custom URL handling code here
}

3) Зарегистрируйте метод обработчика URL

Затем сообщите диспетчеру событий, какой объект и метод вызывать, когда он хочет использовать ваше приложение для загрузки URL-адреса. В приведенном здесь коде мне передали self в качестве обработчика событий, предполагая, что мы вызываем setEventHandler из того же объекта, который определяет метод getUrl:withReplyEvent:.

Вы должны добавить этот код где-нибудь в код инициализации вашего приложения.

NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager];
[em 
  setEventHandler:self 
  andSelector:@selector(getUrl:withReplyEvent:) 
  forEventClass:kInternetEventClass 
  andEventID:kAEGetURL];

Некоторые приложения, включая ранние версии Adobe AIR, используют альтернативное событие WWW! / OURL AppleEvent, чтобы запросить, чтобы приложение открывало URL-адреса, поэтому для совместимости с этими приложениями вам также следует добавить следующее:

[em
  setEventHandler:self 
  andSelector:@selector(getUrl:withReplyEvent:) 
  forEventClass:'WWW!' 
  andEventID:'OURL'];

4) Установите приложение в качестве браузера по умолчанию.

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

Для этого нам нужно использовать API Launch Services. В этом случае мы устанавливаем наше приложение как обработчик роли по умолчанию для ссылок HTTP и HTTPS:

CFStringRef bundleID = (CFStringRef)[[NSBundle mainBundle] bundleIdentifier];
OSStatus httpResult = LSSetDefaultHandlerForURLScheme(CFSTR("http"), bundleID);
OSStatus httpsResult = LSSetDefaultHandlerForURLScheme(CFSTR("https"), bundleID);
//TODO: Check httpResult and httpsResult for errors

(Вероятно, лучше всего спросить разрешения пользователя, прежде чем менять его браузер по умолчанию.)

Пользовательские схемы URL

Стоит отметить, что вы также можете использовать эти же шаги для обработки ваших собственных схем URL-адресов. Если вы создаете настраиваемую схему URL-адресов, рекомендуется основывать ее на идентификаторе пакета вашего приложения, чтобы избежать конфликтов с другими приложениями. Поэтому, если ваш идентификатор пакета - com.example.MyApp, вам следует рассмотреть возможность использования URL-адресов x-com-example-myapp://.

Launch Services является частью CoreServices, а не Carbon. (Таким образом, он переживает 64-битный переход.)

Peter Hosey 10.11.2008 19:42

Нет необходимости создавать литерал NSString, а затем преобразовывать его в CFStringRef, как в (CFStringRef)@"http". Вместо этого напрямую создайте литерал CFString: CFSTR("http").

Jeremy W. Sherman 03.11.2010 21:42

Можете ли вы опубликовать ссылку для скачивания на пример проекта? Я не совсем понимаю, куда вставлять все фрагменты кода. Кроме того, есть идеи, как добиться этого как приложение Cocoa-AppleScript?

Geoffrey Booth 21.08.2013 21:13

Есть ли что-то дополнительное / отличное, что нужно сделать, чтобы зарегистрировать приложение в качестве почтового приложения?

RJVB 04.09.2014 05:08

Стоит отметить, что на шаге № 3 выше регистрация обработчика событий должна происходить в init (или аналогичном). Это НЕ будет работать, если поместить в applicationDidFinishLaunching:

tomwhipple 03.11.2010 20:15

Отличный учебник. Один вопрос: куда идет код из пункта 4? Спасибо

ed22 22.06.2015 18:09

У меня есть приложение, которое запускает JVM через JNI в отдельном потоке. Если я запускаю поток, приложение больше не получает событие (kAEGetURL), если я этого не делаю, оно получает событие нормально. Есть идеи, что не так? Графический интерфейс Cocoa продолжает работать в основном потоке, в то время как у JVM есть собственный.

ed22 15.07.2015 17:12

Если вы просто хотите изменить вспомогательное приложение по умолчанию для http (s), вы можете сделать это в настройках Safari. Там вы найдете раскрывающийся список, который позволит вам выбрать все зарегистрированные приложения-обработчики для http. Чтобы автоматически установить приложение в качестве браузера по умолчанию, см. Предыдущие инструкции.

Чтобы появиться в качестве опции на System Preferences > General > Default web browser (по крайней мере, для macOS 11), вам необходимо добавить типы документов для HTML и XHTML в Info.plist (после 4 шагов, уже описанных в принятый ответ), например:

<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeName</key>
        <string>HTML document</string>
        <key>CFBundleTypeRole</key>
        <string>Viewer</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>public.html</string>
        </array>
    </dict>
    <dict>
        <key>CFBundleTypeName</key>
        <string>XHTML document</string>
        <key>CFBundleTypeRole</key>
        <string>Viewer</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>public.xhtml</string>
        </array>
    </dict>
</array>

macOS Big Sur и выше

Скопируйте и вставьте этот код в свой info.plist

<key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLName</key>
            <string>Web site URL</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>http</string>
                <string>https</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleURLName</key>
            <string>http URL</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>http</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleURLName</key>
            <string>Secure http URL</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>https</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>HTML document</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.html</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>XHTML document</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.xhtml</string>
            </array>
        </dict>
    </array>
    <key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>GIF image</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.compuserve.gif</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>HTML document</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.html</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>XHTML document</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.xhtml</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>JavaScript script</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.netscape.javascript-​source</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>JPEG image</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.jpeg</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>MHTML document</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>org.ietf.mhtml</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>HTML5 Audio (Ogg)</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>org.xiph.ogg-audio</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>HTML5 Video (Ogg)</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>org.xiph.ogv</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>PNG image</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.png</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>SVG document</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.svg-image</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>Plain text document</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.text</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>HTML5 Video (WebM)</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>org.webmproject.webm</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>WebP image</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>org.webmproject.webp</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>org.chromium.extension</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>document.icns</string>
            <key>CFBundleTypeName</key>
            <string>PDF Document</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.adobe.pdf</string>
            </array>
        </dict>
    </array>

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

Убедитесь, что вы делаете это

    func application(_ application: NSApplication, open urls: [URL]) {
// do a for loop, I recommend it
}

Другие вопросы по теме