I’ve done exactly as the Sandboxed Helper App example provided by Apple and all seems to be running fine. I’m able to successfully create a NSXPCConnection object and also get back my remote object (via remoteObjectProxyWithErrorHandler).
However when I call a method on the proxy object (defined in the Protocol definition), I get back this error:
Failed to connect to launch agent: Error Domain=NSCocoaErrorDomain Code=4099 "Couldn’t communicate with a helper application.
Essentially no matter what I do I’m not able to communicate with my helper app. I’m doing nothing fancy, just trying to make a simple call to the helper app to NSLog() something. But it doesn’t work. Strangely I also don’t see any output from inside:
- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
What could I possibly be doing wrong?
UPDATE:
Apparently if I uncheck ‘Enable App Sandboxing’ on my main app, it works! So there’s something wrong with enabling sandboxing after which it does not want to communicate with my helper app. Do I need more entitlements? I’ve tried them all under xcode!
Your helper application is sandboxed. Therefore, it cannot register a mach service dynamically, although Xcode allows it for debug purpose.
However, when you add your helper application to login items (using SMLoginItemSetEnabled() ), launchd will automatically register a mach service for you named with its bundle identifier.
Now your main application is sandboxed. Therefore, random mach communication is not allowed. The only way to make it work was to add a temporary mach lookup entitlement.
Since 10.7.4. Apple introduced the application-groups entitlements as a solution for this case, where an application needs to communicate with a helper app.
Both applications have to share the same application-groups entitlement. It can be any value, but Apple requires that this value must start with your Team-ID (e.g: Team-id.myApp). Then, your helper application bundle identifier must start with that same entitlement (e.g Team-id.myApp.myHelperApp). After that, your main application can freely communicate with your helper application using a XPC communication with the service named with the helper application bundle identifier (i.e. Team-id.myApp.myHelperApp). Also, the two applications will share access to a group container folder named with the application group entitlement (e.g. ~/Library/Group Containers/Team-id.myApp), that you have to create manually if you will need it.