Can applications communicate with each other directly by XPC if they are all in one bundle?

In my project I have a host application and a husk application. What I want to do is, every time the user launches a new view in the host application, I want to create one more dock icon by launching another instance of husk application. Then the husk application behaves like it is the view itself by monitoring the event of click/quit and send them to the host application through XPC.

The XPC tutorial tells me an XPC service embedded in an application is invisible to the processes outside the bundle. To communicate between two foreground applications it seems that I need to create a third helperTool/agent/daemon which venders a Mach/XPC service. But I wonder if I can put husk application inside the bundle of the hose application. So they can directly connect to the XPC service which is also embedded in the same bundle.

If the answer is no, maybe NSDistributedNotificationCenter is much better and simpler in my scenario?

  • Forget to mention, all apps are non-sandboxed. I am seeking the most feasible and low cost means.

Add a Comment

Replies

But I wonder if I can put husk application inside the bundle of the hose application. So they can directly connect to the XPC service which is also embedded in the same bundle.

This won’t work. An XPC service embedded in an app is only visible to the containing app, so there’s no place you can put the XPC service where it’s visible to both of these apps. This is an annoying, and long-standing, limitation (r. 22707607).

Given the above, you have a couple of options:

  • You can coordinate this work via some persistent XPC named endpoint, such as the one provided by a launchd agent or Service Management login item.

  • You can use some other IPC mechanism.

The first option makes sense if you have some other reason to have this persistent process around. If not, I generally prefer the second option.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • What a coincidence we post comments at the same time. Yes I decide to go NSDistributedNotificationCenter.

Add a Comment

I finally decide to go NSDistributedNotificationCenter way. Because in our scenarios, messages and applications do not have states. I actually made a demo to test its performance and resource cost. Found out it is quite reliable. For anyone interested in the performance of NSDistributedNotificationCenter:

Keep in mind that any code running in your login session can observe these notifications. If you’re sending low-level events that way, that is likely to have some privacy implications. I recommend a different IPC option, one that give you more control over what code can receive these events.

Is there a parent/child relationship between your host and husk application processes?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • Thank you for the reply. Actually we can build the husk app with a parent/child relationship. Then use what IPC manner?

Add a Comment

Hi @eskimo, About Notification, I thought if the observer is register with a specific name string and the sender post the notification with that string, all other applications will not receive or respond to the notification, right? Besides, the notification does not contain any data that have security risks. Actually there is no data to transmit, only simple events like click and quit. Under this condition, I think NSDistributedNotificationCenter will be neat and suitable candidate method consider the development cost.

It does have potential security threats that if the attacker knows our notification name, he/she could intercepted and mock our messages to maliciously command the main process to quit. I think all we need to do is encrypt the command string.

I thought if the observer is register with a specific name string and the sender post the notification with that string, all other applications will not receive or respond to the notification, right?

That’s true, but there’s nothing stopping some other, unrelated program listening for that notification. Notifications are, by definition, a one-to-many thing.

I think all we need to do is encrypt the command string.

That’s the wrong approach IMO. Encryption only helps if you have a secure way to share the key between the apps, and if you have that you might as well use it as your IPC channel (-:

Actually we can build the husk app with a parent/child relationship.

OK, cool. That makes things much easier.

Then use what IPC manner?

In a parent/child setup, it’s common to set up IPC using a pipe or Unix domain socket. The latter is probably the best here, because a datagram (SOCK_DGRAM) Unix domain socket preserves record boundaries.

Are you using Swift? Or a C-based language?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • I want to use pure swift here.

  • We discussed the feasibility. Considering the developing cost, we still prefer Notification way.

Add a Comment