以编程方式重启应用

C-V*_*rel 8 macos swift

我想知道是否有任何方法以编程方式重新启动我的应用程序.这是一个mac os应用程序,我在swift中使用Xcode 6.

程序很简单,在给定时间我想重新启动我的应用程序.我想我需要一个简单的助手,但我不确定.

rin*_*aro 10

是的,你需要帮助工具.这是程序:

  1. 在项目中创建帮助程序"命令行工具"目标.例如,名为" 重新启动 "

    重新启动/ 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)
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. Products/relaunch二进制文件添加到主应用程序目标中的"Copy Bundle Resources".

  3. relaunch目标添加到主应用程序目标中的"目标依赖项".

    截图

  4. 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()
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

然后,随心所欲地打电话NSApplication.sharedApplication().relaunch(nil).


Phi*_*rin 6

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.")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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()
    }
}
Run Code Online (Sandbox Code Playgroud)