How to utilize NSXPCListener/Connection for IPC on iOS

Hello,

I'm struggling to understand how I can use NSXPC API to communicate between two processes on iOS. The problem which I want to solve is how to pass some information from VPN tunnel to the VPN app.

I'm looking at the XPC documentation and for iOS I can create NSXPCListener only with the following functions:

  • service()
  • anonymous()

Both return NSXPCListener instance. But the question remains, how to connect to such an instance?

In NSXPConnection API I see only one option for iOS:

  • init(listenerEndpoint: NSXPCListenerEndpoint)

Other constructors accepting serviceName or machServiceName are available only form macOS.

I feel like the problem of communicating between two processes should be easy, but surprisingly I did find it quite difficult on iOS. Can you please advice if this is a proper API for my use case? Or maybe is there some better one, which I'm not aware of?

If this is a proper API, how should I create a connection between two apps? How to pass a listener from one process to the other?

Replies

NSXPCConnection has very limited utility on iOS. AFAIK the only places it’s useful is in interacting with a file provider. It sounds like you’re trying to use it to communicate between your NE provider and its container app. That won’t work.

The alternative is provider/app messaging. The container app sends a message by calling the sendProviderMessage(_:responseHandler:) method and the provider receives it by overriding the handleAppMessage(_:completionHandler:) method. This is clunky, but it’s usually enough to do what you need to do.

You’re not first person to ask for this. See this thread. There’s even a bug number!

Share and Enjoy

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

  • Thanks for quick response and the link.

    Unfortunately using provider/app messaging is not a best choice for me, because it would require constant polling from the app. But if there is no other way, I believe I'd have to live with that.

Add a Comment

Do you know if I can consider messages send via sendProviderMessage secure? I cannot find any information if this channel is safe for sensitive data or not.

Unfortunately using provider/app messaging is not a best choice for me

You and me both! It wouldn’t hurt for you to file your own enhancement request for XPC support, describing your specific requirements and why the current situation is causing you grief.

because it would require constant polling from the app.

I’ve had some success using long polling for this.

Do you know if I can consider messages send via sendProviderMessage secure?

As the API is designed, an app can only message its embedded NE extensions, and vice versa.

Share and Enjoy

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

I will file the enhancement request, it would really nice feature to have.

EDIT: Enhancement request created - https://feedbackassistant.apple.com/feedback/12817005

As the API is designed, an app can only message its embedded NE extensions, and vice versa.

Do you know if the message itself is somehow encrypted so no 3rd party app can sniff the message? I'm investigating the viability of sending some sensitive information through such a channel and I'm concerned about security of such solution.

Do you know if the message itself is somehow encrypted so no 3rd party app can sniff the message?

Probably not. However, that doesn’t matter because Apple platforms tend to use Mach IPC under the covers, typically via XPC. This is a capability-based system. You can only receive a message if you have a receive right for the port to which it was being sent.

ps It’s not encryption if the key to undo the encryption is on the device. It’s just scrambling. If you want to scramble the messages yourself, go ahead.

Share and Enjoy

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