-
-
Save mminer/be55bcdf7c4ff004ecafba6a664addc5 to your computer and use it in GitHub Desktop.
import Foundation | |
let delegate = MyServiceDelegate() | |
let listener = NSXPCListener.service() | |
listener.delegate = delegate | |
listener.resume() |
import Foundation | |
class MyService: NSObject, MyServiceProtocol { | |
func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) { | |
let response = string.uppercased() | |
reply(response) | |
} | |
} |
import Foundation | |
class MyServiceDelegate: NSObject, NSXPCListenerDelegate { | |
func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool { | |
let exportedObject = MyService() | |
newConnection.exportedInterface = NSXPCInterface(with: MyServiceProtocol.self) | |
newConnection.exportedObject = exportedObject | |
newConnection.resume() | |
return true | |
} | |
} |
import Foundation | |
@objc public protocol MyServiceProtocol { | |
func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) | |
} |
import MyService | |
... | |
let connection = NSXPCConnection(serviceName: "com.matthewminer.MyService") | |
connection.remoteObjectInterface = NSXPCInterface(with: MyServiceProtocol.self) | |
connection.resume() | |
let service = connection.remoteObjectProxyWithErrorHandler { error in | |
print("Received error:", error) | |
} as? MyServiceProtocol | |
service?.upperCaseString("Hello XPC") { response in | |
print("Response from XPC service:", response) | |
} |
@mminer - listener.resume() in main.swift is throwing the following error. Any idea how to fix it?
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
@madscientistjaidev: I'm not too sure what might cause that error. I tried the code in the Gist in a fresh project using the Xcode 11 beta + Swift 5 and it worked without a hitch. Sorry I can't be of more help.
Thanks for making your code available.. I reference this every time I create a xpc service and want swift instead. Maybe Xcode 11 will make this obsolete (we can hope).
@tt-embodied: Glad it's helpful!
If anyone like me tried it in a command-line tool and got “The connection to service named ... was invalidated.”, it’s because it doesn’t seem to work in command-line tools at all, the same code in an app will work.
I've tried this in a SwiftUI app and I'm getting the error "The connection to service named ... was invalidated". Any ideas?
UPDATE: My problem was that the XPS Service was not copied to Contents/XPCServices. If you don't properly place the XPC Service within the app bundle, this doesn't work (also why you cannot call the XPC Service from a command line that is expecting it in it's bundle - haven't figure out how to do this yet)
@rsalesas Good to know, that’s an easy mistake to make. Thanks for the extra info.
I also just ran into this error:
Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named <service-name> was invalidated."
It turns out I just misspelled the service name when initializing the NSXPCConnection
. Hope this saves someone a few hours of debugging lol.
@adur1990: Thanks for the fix, I updated the Gist.