gpt4 book ai didi

swift - 如何为 macOS 菜单栏应用程序启用自动启动?

转载 作者:行者123 更新时间:2023-12-03 17:45:54 28 4
gpt4 key购买 nike

我正在为菜单栏构建一个 ma​​cOS 应用程序,它应该随系统启动而自动启动。我开始按照本教程 this tutorial 为基于标准窗口的 macOS 应用程序实现自动启动功能。我有

  • 在主项目(帮助应用程序)中添加了一个新目标
  • 将助手应用的skip install更改为yes
  • 将辅助应用设置为仅后台应用
  • 为主应用程序添加了一个新的复制文件构建阶段,以将帮助程序应用程序复制到 bundle 中
  • 链接了ServiceManagement.framework
  • 在应用程序委托(delegate)中实现了帮助器应用程序随系统启动而启动的功能。启动后,它会启动主应用程序(有关更多信息,请参阅教程链接或下面的源代码)

效果很好,应用程序自动启动:)所以我开始更改项目,主应用程序变成了菜单栏应用程序。但是,该应用程序将不再自动启动:/有人有解决方案吗?

这是主应用程序的应用程序委托(delegate)的代码:

import Cocoa
import ServiceManagement

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)


func applicationDidFinishLaunching(_ aNotification: Notification) {

statusItem.button?.title = "Test"
statusItem.button?.target = self
statusItem.button?.action = #selector(showWindow)


// auto start
let launcherAppId = "com.####.####Helper"
let runningApps = NSWorkspace.shared.runningApplications
let isRunning = !runningApps.filter { $0.bundleIdentifier == launcherAppId }.isEmpty

SMLoginItemSetEnabled(launcherAppId as CFString, true)

if isRunning {
DistributedNotificationCenter.default().post(name: .killLauncher, object: Bundle.main.bundleIdentifier!)
}
}

func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}

@objc func showWindow() {
let storyboard = NSStoryboard(name: "Main", bundle: nil)
guard let vc = storyboard.instantiateController(withIdentifier: "ViewController") as? ViewController else {
fatalError("Unable to find main view controller")
}

guard let button = statusItem.button else {
fatalError("Unable to find status item button")
}

let popover = NSPopover()
popover.contentViewController = vc
popover.behavior = .transient
popover.show(relativeTo: button.bounds, of: button, preferredEdge: .maxY)

}


}

extension Notification.Name {
static let killLauncher = Notification.Name("killLauncher")
}

这是辅助应用程序的应用程序委托(delegate):

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {



func applicationDidFinishLaunching(_ aNotification: Notification) {
let mainAppIdentifier = "com.####.####"
let runningApps = NSWorkspace.shared.runningApplications
let isRunning = !runningApps.filter { $0.bundleIdentifier == mainAppIdentifier }.isEmpty

if !isRunning {
DistributedNotificationCenter.default().addObserver(self, selector: #selector(self.terminate), name: .killLauncher, object: mainAppIdentifier)

let path = Bundle.main.bundlePath as NSString
var components = path.pathComponents
components.removeLast()
components.removeLast()
components.removeLast()
components.append("MacOS")
components.append("####") //main app name

let newPath = NSString.path(withComponents: components)

NSWorkspace.shared.launchApplication(newPath)
}
else {
self.terminate()
}
}

func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}

@objc func terminate() {
NSApp.terminate(nil)
}


}

extension Notification.Name {
static let killLauncher = Notification.Name("killLauncher")
}

非常感谢您的帮助:)

最佳答案

我的代码看起来几乎相同,除了我如何在帮助程序应用程序中编写路径:

var pathComponents = (Bundle.main.bundlePath as NSString).pathComponents
pathComponents.removeLast()
pathComponents.removeLast()
pathComponents.removeLast()
pathComponents.removeLast()
let newPath = NSString.path(withComponents: pathComponents)
NSWorkspace.shared.launchApplication(newPath)

另外,如果我没记错的话,我必须确保 Main.storyboard 文件仍然具有带有应用程序对象和空主菜单的“应用程序场景”。

Application Scene

关于swift - 如何为 macOS 菜单栏应用程序启用自动启动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61933813/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com