Hi,
So, one thing I'd like to understand better is why/what you actually "need" this for. The reason for the "basic" limitation here isn't all that complicated- ExtensionKit was designed around a "one endpoint" model, so that's just the way it happens to work. That main advantage of this approach is that it simplifies the entire API design, as it allows you to think of an extension as "a component I communicate with that provides a specific interface", NOT "a component I find and then choose a particular interface on".
I think the other reason they choose this approach is that they didn't really consider it much of a limitation/restriction.
Going back to your original explanation here:
...open concurrent XPC connections to both an extension process (via AppExtensionProcess.makeXPCConnection) that extension's scenes (via EXHostViewController.makeXPCConnection)?...
The typical way you would implement something like this is not to open two independant XPC connections, it to open the "primary" XPC connection (in the context of ExtensionKit, this would "the extension") and THEN have that XPC connection vend another XPC connection "to" the client. The context is slightly different, but this is the same technique that's described in the "XPC Rendezvous" section of "XPC and App-to-App Communication".
Also, as a side comment here, it's important to keep in mind how the "larger" context of this kind of API plays out in an app. For example, imagine you had an extension architected like this;
a) The extension provides a user interface that's used to configure "something".
b) The extension the provides an XPC connection that's used to complete the work configured in "a".
The tricky point here is that in most cases connection "b" should actually be to some other component your broader architecture, NOT directly the the extension. Turning that into a more concrete example, think about the two different "extremes" of the "work" involved in "b":
- The actual work involved requires minimal time (say 0.1s).
In that case, why bother creating a whole separate interface, etc? Just include whatever you need in the XPC interface for "a", finish everything "at once", and then "everything" can be destroyed when your extension exits.
- The actual work involved will require substantial time (say 60min).
Now the problem isn't just with keeping an extension active for 60min, it's with assuming ANYTHING (extension/app/the entire system) will continue to be running uninterrupted for the next 60min. For most case, the right approach here is for your extension to vend an interface to a different component (typically a daemon), which is then responsible for managing the entire work lifetime.
I'm not sure where you your needs fit along that spectrum, but I hope that opens up some new ideas about how you can approach this.
-Kevin Elliott
DTS Engineer, CoreOS/Hardware