35 lines
1.4 KiB
Swift
35 lines
1.4 KiB
Swift
import AppKit
|
|
|
|
@MainActor
|
|
enum AppLauncher {
|
|
static func launch(_ url: URL) async throws {
|
|
let configuration = NSWorkspace.OpenConfiguration()
|
|
configuration.activates = true
|
|
configuration.promptsUserIfNeeded = false
|
|
|
|
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, any Error>) in
|
|
NSWorkspace.shared.openApplication(at: url, configuration: configuration) { _, error in
|
|
// AppKit calls this completion on a concurrent queue; only resume the continuation here.
|
|
if let error {
|
|
continuation.resume(throwing: error)
|
|
} else {
|
|
continuation.resume()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static func quit(_ url: URL) throws {
|
|
let path = url.standardizedFileURL.resolvingSymlinksInPath().path
|
|
for application in NSWorkspace.shared.runningApplications {
|
|
guard application.bundleURL?.standardizedFileURL.resolvingSymlinksInPath().path == path,
|
|
!application.isTerminated else { continue }
|
|
guard application.terminate() else {
|
|
throw NSError(domain: "Conjure", code: 1, userInfo: [
|
|
NSLocalizedDescriptionKey: "The application refused the quit request. Save your work and quit it manually."
|
|
])
|
|
}
|
|
}
|
|
}
|
|
}
|