4

I am trying to use NSXPCConnection in swift.

So, this line:

_connectionToService = [[NSXPCConnection alloc] initWithServiceName:@"SampleXPC"];

can be replaced by this line:

_connectionToService = NSXPCConnection(serviceName: "SampleXPC")

And, this line:

_connectionToService.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(StringModifing)];

can be replaced by this line:

_connectionToService.remoteObjectInterface = NSXPCInterface(protocol: <#Protocol#>)

Now I am confused about using the correct replacement for: <#Protocol#> in swift, in objective c I would have used: @protocol(StringModifing), but in swift I am clueless :(

Devarshi
  • 16,440
  • 13
  • 72
  • 125

2 Answers2

2

That's a tricky one.

First of all protocol is a reserved keyword and cannot be used as parameter label. A quick look into Apples official doc helped me here. use `protocol`` instead. That means the parameter name contains single quotes.

"[obj class]" is being replaced by "obj.self" in swift. The same syntax is used for protocols. That means in your case "@protocol(StringModifing)" becomes "StringModifing.self".

Unfortunately this still will not work. The problem now is behind the scenes. The xpc mechanism is some kind of low-level stuff and wants ObjC style protocols. That means that you need the keyword @objc in front of your protocol declaration.

All together the solution is:

@objc protocol StringModifing {

    func yourProtocolFunction()
}

@objc protocol StringModifingResponse {

    func yourProtocolFunctionWhichIsBeingCalledHere()
}

@objc class YourXPCClass: NSObject, StringModifingResponse, NSXPCListenerDelegate {

    var xpcConnection:NSXPCConnection!
    private func initXpcComponent() {

        // Create a connection to our fetch-service and ask it to download for us.
        let fetchServiceConnection = NSXPCConnection(serviceName: "com.company.product.xpcservicename")

        // The fetch-service will implement the 'remote' protocol.
        fetchServiceConnection.remoteObjectInterface = NSXPCInterface(`protocol`: StringModifing.self)


        // This object will implement the 'StringModifingResponse' protocol, so the Fetcher can report progress back and we can display it to the user.
        fetchServiceConnection.exportedInterface = NSXPCInterface(`protocol`: StringModifingResponse.self)
        fetchServiceConnection.exportedObject = self

        self.xpcConnection = fetchServiceConnection

        fetchServiceConnection.resume()

        // and now start the service by calling the first function
        fetchServiceConnection.remoteObjectProxy.yourProtocolFunction()
    }

    func yourProtocolFunctionWhichIsBeingCalledHere() {

        // This function is being called remotely
    }
}
JackPearse
  • 2,922
  • 23
  • 31
0

Swift 4

_connectionToService.remoteObjectInterface = NSXPCInterface(with: StringModifing.self)
Freek Sanders
  • 1,187
  • 10
  • 26