我想知道是否有任何以编程方式重启我的应用的方法。 这是一个mac os应用程序,我在swift中使用Xcode 6。
程序很简单,在给定时间我想重新启动我的应用程序。我想我需要一个简单的助手,但我不确定。
答案 0 :(得分:10)
是的,你需要帮助工具。这是程序:
在项目中创建帮助程序“命令行工具”目标。例如,名为“重新启动”
<强>重新推出/ main.swift 强>:
import AppKit
// KVO helper
class Observer: NSObject {
let _callback: () -> Void
init(callback: () -> Void) {
_callback = callback
}
override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
_callback()
}
}
// main
autoreleasepool {
// the application pid
let parentPID = atoi(C_ARGV[1])
// get the application instance
if let app = NSRunningApplication(processIdentifier: parentPID) {
// application URL
let bundleURL = app.bundleURL!
// terminate() and wait terminated.
let listener = Observer { CFRunLoopStop(CFRunLoopGetCurrent()) }
app.addObserver(listener, forKeyPath: "isTerminated", options: nil, context: nil)
app.terminate()
CFRunLoopRun() // wait KVO notification
app.removeObserver(listener, forKeyPath: "isTerminated", context: nil)
// relaunch
NSWorkspace.sharedWorkspace().launchApplicationAtURL(bundleURL, options: nil, configuration: [:], error: nil)
}
}
将Products/relaunch
二进制文件添加到主应用程序目标中的“复制包资源”。
将relaunch
目标添加到主应用程序目标中的“目标依赖项”。
在主应用程序中添加relaunch
功能。
例如: NSApplication + Relaunch.swift :
extension NSApplication {
func relaunch(sender: AnyObject?) {
let task = NSTask()
// helper tool path
task.launchPath = NSBundle.mainBundle().pathForResource("relaunch", ofType: nil)!
// self PID as a argument
task.arguments = [String(NSProcessInfo.processInfo().processIdentifier)]
task.launch()
}
}
然后,根据需要致电NSApplication.sharedApplication().relaunch(nil)
。
答案 1 :(得分:4)
Swift 3版本,基于Rintaro的代码和Cenox Kang的解决方法。
请参阅Rintaro的答案以获取指示。
<强>重新推出/ main.swift:强>
import AppKit
// KVO helper
class Observer: NSObject {
let _callback: () -> Void
init(callback: @escaping () -> Void) {
_callback = callback
}
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
_callback()
}
}
// main
autoreleasepool {
// the application pid
guard let parentPID = Int32(CommandLine.arguments[1]) else {
fatalError("Relaunch: parentPID == nil.")
}
// get the application instance
if let app = NSRunningApplication(processIdentifier: parentPID) {
// application URL
let bundleURL = app.bundleURL!
// terminate() and wait terminated.
let listener = Observer { CFRunLoopStop(CFRunLoopGetCurrent()) }
app.addObserver(listener, forKeyPath: "isTerminated", context: nil)
app.terminate()
CFRunLoopRun() // wait KVO notification
app.removeObserver(listener, forKeyPath: "isTerminated", context: nil)
// relaunch
do {
try NSWorkspace.shared().launchApplication(at: bundleURL, configuration: [:])
} catch {
fatalError("Relaunch: NSWorkspace.shared().launchApplication failed.")
}
}
}
<强>的NSApplication + Relaunch.swift:强>
import AppKit
extension NSApplication {
func relaunch(sender: AnyObject?) {
let task = Process()
// helper tool path
task.launchPath = Bundle.main.path(forResource: "relaunch", ofType: nil)!
// self PID as a argument
task.arguments = [String(ProcessInfo.processInfo.processIdentifier)]
task.launch()
}
}
答案 2 :(得分:4)
swift4功能
@objc private func buttonClicked(_ sender: NSButton) {
if let path = Bundle.main.resourceURL?.deletingLastPathComponent().deletingLastPathComponent().absoluteString {
NSLog("restart \(path)")
_ = Process.launchedProcess(launchPath: "/usr/bin/open", arguments: [path])
NSApp.terminate(self)
}
}
答案 3 :(得分:1)
在Swift 2中解决rintaro的代码。
// the application pid
let parentPID = atoi(C_ARGV[1])
到
// the application pid
let parentPID = Int32(Process.arguments[1])
对我有用。
答案 4 :(得分:1)
https://gist.github.com/BenLeggiero/449fb9b1a45b69fb276f4f9ad86cab7a
为我工作
func relaunch(afterDelay seconds: TimeInterval = 0.5) -> Never {
let task = Process()
task.launchPath = "/bin/sh"
task.arguments = ["-c", "sleep \(seconds); open \"\(Bundle.main.bundlePath)\""]
task.launch()
NSApp.terminate(self)
exit(0)
}
答案 5 :(得分:0)
谢谢你,我只是简化一下:
func restart()
{
Process.launchedProcess(launchPath: "/usr/bin/open", arguments: ["-b", Bundle.main.bundleIdentifier!])
NSApp.terminate(self)
}