Skip to content

Instantly share code, notes, and snippets.

@mminer mminer/MyService.swift
Last active Jun 23, 2019

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)

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.