Чистим Dock и делаем приложение без xCode

от автора

Мы сделаем программу для запуска приложений из панели статуса.
Вам понадобится terminal, Swift версии 3.1 или выше и любой текстовый редактор.
Я проверял работу на macOS Sierra 10.12.6 и macOS Catalina 10.15.

Открываем terminal /Applications/Utilities/Terminal и создаем файл.

touch toolbar.swift

Открываем файл toolbar.swift и пишем такой код:

import AppKit var app: NSApplication var statusItem: NSStatusItem #if swift(>=5.1)     app = NSApplication.shared     statusItem = NSStatusBar.system.statusItem(         withLength: CGFloat(NSStatusItem.variableLength)) #else     app = NSApplication.shared()     statusItem = NSStatusBar.system().statusItem(withLength: CGFloat(32)) #endif  if #available(macOS 10.10, *) {     statusItem.button?.title = "\u{2699}\u{FE0F}" }  // extension  // menu  app.setActivationPolicy(.prohibited) app.run() 

Часть кода нужна, чтобы поддерживать совместимость со старыми версиями языка.
Строка app.setActivationPolicy(.prohibited) нужна, чтобы иконка активного приложения не появилась в Dock.

Сохраните файл и запустите программу командой:

swift toolbar.swift

Если нет ошибок, то на панели статуса появится «бесполезная» кнопка. Я использовал UTF символ шестеренки «\u{2699}\u{FE0F}», но можно добавить нужную вам картинку используя свойство statusItem.button?.image.

Выйдите из программы нажав в terminal ctrl-c.

Я решил не создавать class AppDelegate для такого маленького приложения, а расширил класс NSApplication. Добавьте после // extension следующие строки:

extension NSApplication {     func runTask(_ appName: String, _ arg: String = "") {         let task = Process()         #if swift(>=5.1)             task.executableURL = URL(fileURLWithPath: "/usr/bin/open")         #else             task.launchPath = "/usr/bin/open"         #endif         task.arguments = arg.isEmpty ?[appName] : [arg, appName]         #if swift(>=5.1)             do {try task.run()}             catch {print(error)}         #else             task.launch()         #endif     }     @objc func securityRun () {         self.runTask("/System/Library/PreferencePanes/Security.prefPane")     }     @objc func diskRun () {         self.runTask( "disk utility", "-a")     }     @objc func automatorRun () {         self.runTask( "automator", "-a")     } } 

Обратите внимание, что таким образом можно быстрее запускать не только приложения, но и отдельные страницы SystemPreference.

Для методов нужен интерфейс. После // menu наберите:

let menu = NSMenu() let items: [String] = ["Security", "Disk Utility", "Automator", "Quit"]  var sel: [Selector] = [] let shared = NSApplication.shared  #if swift(>=5.1)     sel = [         #selector(shared.securityRun), #selector(shared.diskRun),         #selector(shared.automatorRun), #selector(shared.terminate)] #else     sel = [         #selector(shared().securityRun), #selector(shared().diskRun),         #selector(shared().automatorRun), #selector(shared().terminate)] #endif  for i in 0..<items.count {     menu.addItem(NSMenuItem(         title: items[i], action: sel[i], keyEquivalent: ""))     if i==items.count-2 {         menu.addItem(NSMenuItem.separator())     } } statusItem.menu = menu 

Для всех методов мы создали кнопки и привязали к ним методы из экземпляра класса NSApplication. Мы добавили кнопку «Quit», так как нам надо позволить пользователю выйти из программы без использования terminal.

Компилируем программу. Обратите внимание, что вместо swift надо набрать swiftc.

swiftc toolbar.swift

В текущей директории появился файл toolbar. Его можно запустить командой:

./toolbar

Если мы запустим файл toolbar двойным кликом, то вместе с приложением появится окно terminal, а это не очень удобно.

Попробуем исправить ситуацию. Все команды запускаем в terminal.

Для начала создаем дерево директорий для нашего приложения.

mkdir -p ToolBar.app/Contents/MacOS

Меняем доступ к приложению.

chmod a+x ToolBar.app

Создаем директорию для иконки.

mkdir ToolBar.app/Contents/Resources

Копируем и изменяем имя одной из стандартных иконок.

cp /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ToolbarAdvanced.icns ToolBar.app/Contents/Resources/AppIcon.icns

Перемещаем скомпилированный файл toolbar в директорию MacOS.

mv toolbar ToolBar.app/Contents/MacOS

Меняем режим доступа к файлу toolbar.

chmod a+x ToolBar.app/Contents/MacOS/toolbar

Cоздаем файл PkgInfo с информацией о типе приложения. Флаг -n нужен, чтобы в файле PkgInfo не было символа перевода строки.

echo -n "APPL????" > ToolBar.app/Contents/PkgInfo

Меняем режим доступа к файлу PkgInfo.

chmod a+x ToolBar.app/Contents/PkgInfo

Создаем минимальный Info.plist с информацией о приложении:

echo '<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict>   <key>CFBundleIdentifier</key>   <string>example.ToolBar</string>   <key>CFBundleExecutable</key>   <string>toolbar</string>   <key>CFBundleIconFile</key>   <string>AppIcon</string> </dict> </plist>' > ToolBar.app/Contents/Info.plist 

Перемещаем приложение ToolBar.app в /Applications/Utilities.
Terminal попросит ввести пароль администратора.

sudo mv ToolBar.app /Applications/Utilities

После этих операций новое приложение должно появится в /Applications/Utilities и его можно запустить через Launchpad (почему-то директория с утилитами называется Others)

Осталось добавить наше приложение в автозапуск.

Для этого надо создать файл ~/Library/LaunchAgents/example.ToolBar.plist. Сделаем это одно командной:

 echo '<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict>     <key>Label</key>     <string>example.ToolBar</string>     <key>ProgramArguments</key>     <array>         <string>open</string>         <string>/Applications/Utilities/ToolBar.app</string>         <string>--args</string>         <string>-silent</string>     </array>     <key>RunAtLoad</key>     <true/> </dict> </plist>' > ~/Library/LaunchAgents/example.ToolBar.plist

Проверьте появился ли нужный файл.

ls ~/Library/LaunchAgents

Чтобы проверить автозапуск без перезагрузки, выйдите из приложения и запустите в terminal команду:

launchctl load -w ~/Library/LaunchAgents/example.ToolBar.plist

Иконка приложения должна появится на панели статуса.
Выйдите из приложения и сделайте unload командой:

launchctl unload -w ~/Library/LaunchAgents/example.ToolBar.plist

Теперь приложение запустится при перезагрузке системы, а лишние иконки можно убрать из Dock.

Скорее всего, таким способом можно сделать мини-плеер для iTunes, простой todo list или интерфейс для выравнивания окон на рабочем столе.


ссылка на оригинал статьи https://habr.com/ru/post/480876/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *