Working on my first macOS Launch Agent using XPC
.
I need the process that is delivering the service to be started by launchd
and to then stay running until the client process that made the initial call is closed.
I have set KeepAlive
to true
in the Launch Agent's plist
but obviously this means the process is still alive even after the client process that made the initial call has ended.
In the documentation in launchd.plist(5)
it states that "a dictionary of conditions may be specified to selectively control whether launchd
keeps a job alive or not"... does someone know what dictionary is being referred to here and how to implement the conditions?
Edit
Adding code for context although I would stress this all works and behaves as I expect it to (setup a connection to start the service).
Thanks to rderik for providing example code (https://github.com/rderik/rdConsoleSequencer).
// Connecting to the service from the client...
let connection = NSXPCConnection(machServiceName: "com.name.servicename")
connection.remoteObjectInterface = NSXPCInterface(with: MyXPCProtocol.self)
connection.resume()
let service = connection.remoteObjectProxyWithErrorHandler { error in
print("Received error:", error)
} as? MyXPCProtocol
// Service main.swift ...
let listener = NSXPCListener(machServiceName:
"com.name.servicename")
let delegate = ServiceDelegate()
listener.delegate = delegate;
listener.resume()
RunLoop.main.run()
// Service class...
@objc class MyXPC: NSObject, MyXPCProtocol {
// My service functions...
}
// Service delegate...
class ServiceDelegate: NSObject, NSXPCListenerDelegate {
func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
let exportedObject = MyXPC()
newConnection.exportedInterface = NSXPCInterface(with: MyXPCProtocol.self)
newConnection.exportedObject = exportedObject
newConnection.resume()
return true
}
}
// Service protocol
@objc(MyXPCProtocol) protocol MyXPCProtocol {
// My protocol functions...
}
// User LaunchAgents plist...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>com.name.MyXPC</string>
<key>Program</key>
<string>/mypath.../</string>
<key>MachServices</key>
<dict>
<key>com.name.myservice</key>
<true/>
</dict>
</dict>
</plist>