Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restart application programmatically

Tags:

macos

swift

I would like to know if is any method to restart my app programmatically. It's a mac os app and I work with Xcode 6 in swift.

The procedure is simple, at a given time I want to restart my app. I guess I need a simple Helper but i'm not sure.

like image 684
C-Viorel Avatar asked Dec 15 '14 08:12

C-Viorel


People also ask

How do I programmatically restart an android app?

activity. startActivity(intent); // Start the launch activity System. exit(0); // System finishes and automatically relaunches us. }

How do I programmatically restart an iOS app?

You cannot restart an iOS Application in any case, even if you're able to do using some private api your application will be rejected by Apple and will not be considered for App store release.


2 Answers

https://gist.github.com/BenLeggiero/449fb9b1a45b69fb276f4f9ad86cab7a

worked for me

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)
}
like image 111
water_ak47 Avatar answered Oct 13 '22 16:10

water_ak47


Yes, you need helper tool. here is the procedure:

  1. Create helper "Command Line Tool" target in your Project. For example, named "relaunch"

    relaunch/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)
        }
    }
    
  2. Add Products/relaunch binary to "Copy Bundle Resources" in the main application target.

  3. Add relaunch target to "Target Dependencies" in the main application target.

    screenshot

  4. Add relaunch function in the main application.

    For example: 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()
        }
    }
    

Then, call NSApplication.sharedApplication().relaunch(nil) as you like.

like image 42
rintaro Avatar answered Oct 13 '22 16:10

rintaro