Ah, you mistake me. I was asking because sandboxing makes this harder.
Anyway, I believe you’re hitting a known bug in macOS 13 (FB11745075
). The bug affects anyone who uses NSWorkspace
, and that includes the open
tool. I took a TSI about this last year and was able to work around the bug by sending an Apple event directly. I’ve pasted a snippet in below. However, given that you’re not calling NSWorkspace
directly, your idea of using osacript
is probably the easiest path forward for you.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
| @IBAction |
| private func testAppleEventAction(_ sender: Any) { |
| self.status = "Opening with Apple event…" |
| let url = FileManager.default.temporaryDirectory.appendingPathComponent("tmp.sh") |
| let script = """ |
| #! /bin/sh |
| echo 'Hail Teapot! (Apple event)' |
| """ |
| do { |
| try script.write(to: url, atomically: true, encoding: .utf8) |
| let success = chmod(url.path, 0o755) >= 0 |
| guard success else { throw POSIXError(.init(rawValue: errno)!) } |
| } catch let error as NSError { |
| self.status = "Did not open, write error (\(error.domain) / \(error.code))" |
| return |
| } |
| guard let terminal = NSRunningApplication.runningApplications(withBundleIdentifier: "com.apple.Terminal").first else { |
| self.status = "Terminal is not open." |
| return |
| } |
| |
| |
| |
| let target = NSAppleEventDescriptor(processIdentifier: terminal.processIdentifier) |
| let event = NSAppleEventDescriptor( |
| eventClass: AEEventClass(kCoreEventClass), |
| eventID: AEEventID(kAEOpenDocuments), |
| targetDescriptor: target, |
| returnID: AEReturnID(kAutoGenerateReturnID), |
| transactionID: AETransactionID(kAnyTransactionID) |
| ) |
| |
| |
| |
| let scriptURL = NSAppleEventDescriptor(fileURL: url) |
| let itemsToOpen = NSAppleEventDescriptor.list() |
| itemsToOpen.insert(scriptURL, at: 0) |
| event.setParam(itemsToOpen, forKeyword: keyDirectObject) |
| |
| |
| |
| do { |
| let reply = try event.sendEvent(options: [.waitForReply], timeout: 60.0) |
| |
| |
| |
| _ = reply |
| |
| |
| |
| terminal.activate() |
| } catch let error as NSError { |
| self.status = "Did not open (\(error.domain) / \(error.code))" |
| return |
| } |
| self.status = "Did open." |
| } |