NSXPCConnection passes an object by proxy

The daemon and service programming guide reports that you can return a proxy object through an open XPC connection, even as a parameter to a response block.

Passing an object through a proxy

In most cases, it makes sense to copy objects and send them to the other side of the connection. However, this is not always desirable. In particular:

If you need to share a single instance of data between the client application and the assistant, you must pass the objects through a proxy. If an object must call methods for other objects in your application that you cannot or don’t want to pass through the connection (for example, user interface objects), then you must pass the object through a proxy β€” either the caller, the called (where possible), or the relay object, which you specifically create for this purpose. The disadvantage of transmitted proxy objects is that performance is significantly reduced (since each access to the object requires interprocess communication). For this reason, you should only transfer objects through a proxy server if it is not possible to transfer them by copying.

You can configure additional proxy objects in the same way as you configured the remoteObjectInterface property of the original connection. First, determine which parameter for the method should be passed to the proxy, then specify the NSXPCInterface object that defines the interface for this object.

The first questions arise: how should the object transmitted by the proxy server be determined? How is an NSXPCProxyCreating compliant object? Should the remoteObjectProxy and remoteObjectProxyWithErrorHandler methods be implemented :?

We give an example that I do not quite understand. In particular, I do not understand where I should call the NSXPCInterface (setInterface: forSelector: argumentIndex: ofReply :) method for whitelisting a parameter as a proxy: in the XPC service code or in the host?

0, 1 ..

NO Reply, . , YES.

, : - , XPC?

+5
1

: - XPC, setInterface: forSelector: argumentIndex: ofReply: both:

  • XPC, exportedInterface
  • , remoteObjectInterface

I.e, :

// common (service/host) protocol definition
@protocol Service
@end

@protocol ServiceFactory
-(void)connectToNewService: (void (^)(id<Service>)reply;
@end

In the XPC service:

// Implement the one method in the NSXPCListenerDelegate protocol.
-(BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection*)newConnection {   

    NSXPCInterface *serviceFactoryInterface =[NSXPCInterface interfaceWithProtocol:@protocol(ServiceFactory)];
    NSXPCInterface *serviceInterface =[NSXPCInterface interfaceWithProtocol:@protocol(Service)];

    // connection has to be returned as proxy, not as a copy
    [serviceFactoryInterface setInterface: serviceInterface
                          forSelector: @selector(connectToNewService:)
                        argumentIndex: 0
                              ofReply: YES];

    newConnection.exportedInterface = serviceFactoryInterface;
    newConnection.exportedObject = self;

    [newConnection resume];
    return YES;

}

In the main code:

// in the host

- (void)openNewService
{
    NSXPCConnection *xpcConnection = [[NSXPCConnection alloc] initWithServiceName:@"eu.mycompany.servicefactory"];
    NSXPCInterface *serviceFactoryInterface =[NSXPCInterface interfaceWithProtocol:@protocol(ServiceFactory)];
    NSXPCInterface *serviceInterface =[NSXPCInterface interfaceWithProtocol:@protocol(Service)];

    // connection has to be returned as proxy, not as a copy
    [serviceFactoryInterface setInterface: serviceInterface
                          forSelector: @selector(connectToNewService:)
                        argumentIndex: 0
                          ofReply: YES];

    xpcConnection.remoteObjectInterface = serviceFactoryInterface;
    [xpcConnection resume];

    [[xpcConnection remoteObjectProxy] connectToNewService:^(id<Service> newService) {

        // here a newService is returned as NSXPCDistantObject <Service>*
        [xpcConnection invalidate];

    }];

}
+7
source

All Articles