2

I've read the NSXPC* docs, which advise making the vended service as stateless as possible. It's a good idea, at least to the docs and examples I've read, since the service and the calling app see each other as singletons and only one instance of the service runs at a time. This means that the methods are essentially non-member functions (to use a C++ term).

Why do I want to get around this? I want to put the network code into a XPC. Since the XPC will be working with a GUI app, which will have multiple windows, I need to support multiple simultaneous connections. That doesn't work with singletons, at least directly.

The network API is C-based, with the main state type a pointer to a custom struct. So why don't we do something similar:

  1. Have the creation function return a value type, like NSUUID or something. (Passing a pointer across processes would be a bad idea.)
  2. In the service, create a NSDictionary (or std::map or whatever) mapping between the NSUUID and the API C-pointer.
  3. The various service APIs take the UUID and convert it to the C-pointer to use the network API.

Aside: Since the token is random, if the XPC service crashes, the main app will have a token that's useless after the XPC is restarted. Maybe I should a URL (which would have all the information to restart) instead. But then we get potential conflicts if two connections happen to be to the same server. Maybe I can combine the ideas with the token being a URL/UUID pair. (The UUID value would move from being returned by the service to supplied by the main app.)

Would this be a good way to implement state-full XPCs?

CTMacUser
  • 1,996
  • 1
  • 16
  • 27
  • Given there is a one-to-one mapping between the main app and the xpc "slave" why do you need to provide any kind of mapping? Why not take a restful-state approach and provide methods like open/read/write/close so before any read you know you need to do an open, etc? – trojanfoe Jun 25 '14 at 08:53
  • @trojanfoe, I'm using an existing session-based protocol (not a one-and-done type like HTTP). Imagine Apple's Safari with only one window, that only has one tab; that's what would happen if I don't support multiple Internet connections within the XPC. Plus Apple cheats to allow Safari multiple WebKit XPC instances, mere mortal programmers aren't allowed to do that. – CTMacUser Jun 30 '14 at 18:12

1 Answers1

0

You may want to add a method to your service interface which replies with a long-lived proxy object. You can arrange for this to happen by means of a call to -[NSXPCInterface setInterface:forSelector:argumentIndex:ofReply:], passing YES for the last parameter. Details are available here:

https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSXPCInterface_reference/#//apple_ref/occ/instm/NSXPCInterface/setInterface:forSelector:argumentIndex:ofReply:

Integer Poet
  • 747
  • 5
  • 19