Using Sockets with NSXPCConnection

2019-09-10 22:15发布

问题:

Running into an issue when using sockets with an NSXPCConnection.

Basically, there is a main process and a helper process running, established via NSXPCConnection. That helper process needs to act as a server and listen to a particular port (say 111), which receives outside connections.

The helper process opens a listening socket using the TCPServer helper class (wrapper around CFSocket) which is provided by Apple. Code found here: https://code.google.com/p/iphone-remotepad/source/browse/trunk/RemotePad/TCPServer.h?r=238

The socket is opened successfully in - (BOOL)start:(NSError **)error.

The outer clients can establish with the 111 port. (test in terminal via telnet localhost 111).

However, the helper process never receives the TCPServer callback TCPServerAcceptCallBack.

The helper process has com.apple.security.network.client entitlement enabled.

Also, when I run the TCPServer in the main app instead of the helper process, set up the server on port 111, and try to connect to port 111, I do get the callback.

Any ideas of why the helper process does not receive socket call back? An XPC related issue?

回答1:

Ok figured out the issue.

An xpc service provides you with a default run loop of type dispatch_main.

You want to substitute that with an NSRunLoop - done by changing the xpc service info plist:

https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingXPCServices.html

Once that is done, you want to manually create a run loop inside your xpc service, along lines of:

do {
    @autoreleasepool {
        [[NSRunLoop currentRunLoop]run];
    }
} while (YES);

With that in place, the TCPServer (which needs an active runloop) will return the callback and you'll be able to get the incoming data.