Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Components of XPC service.
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)
}
@Herz3h

This comment has been minimized.

Copy link

commented Jul 5, 2018

Thank you very much for this clear and concise example.

@adur1990

This comment has been minimized.

Copy link

commented Oct 24, 2018

This is not working with macOS Mojave and Swift 4.2.

The connection to service named com.matthewminer.MyService was invalidated.

Apple's documentation is horrible. I can not figure out how to do this. Any suggestions?

@adur1990

This comment has been minimized.

Copy link

commented Oct 25, 2018

So, I figured it our. In Swift 4 you have to pass @escaping to the result parameter of the service:

// MyService.swift

import Foundation

class MyService: NSObject, MyServiceProtocol {
    func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void) {
        let response = string.uppercased()
        reply(response)
    }
}
// MyServiceProtocol.swift

import Foundation

@objc public protocol MyServiceProtocol {
    func upperCaseString(_ string: String, withReply reply: @escaping (String) -> Void)
}
@mminer

This comment has been minimized.

Copy link
Owner Author

commented Dec 12, 2018

@adur1990: Thanks for the fix, I updated the Gist.

@madscientistjaidev

This comment has been minimized.

Copy link

commented May 29, 2019

@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)

@mminer

This comment has been minimized.

Copy link
Owner Author

commented Jun 26, 2019

@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.

@tt-embodied

This comment has been minimized.

Copy link

commented Jul 30, 2019

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).

@mminer

This comment has been minimized.

Copy link
Owner Author

commented Jul 31, 2019

@tt-embodied: Glad it's helpful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.