- Apr 7, 2011
How can I have my sandboxed app announce something to other sandboxed apps? NSDistributedNotificationCenter can't post notifications with user info. What are my other options?
You can't use XPC to communicate with another app.
Yes you can. Create an XPC service and have both apps connect to it.
See this question and answer on Stackoverflow for more information:
Please describe exactly what you want to announce, for how long, and to whom.
"How long" means how long the announcement is visible and can be acted upon: it's lifetime. "To whom" means who can see it, who would miss it, etc. A notification via NSDistributedNotificationCenter is ephemeral. If a potential recipient isn't looking at the time, it's gone. For example, a process started after the announcement is sent would never see the announcement.
When I read "announce" I think mDNS (Bonjour), which is a generalized networked "announcement" service, with a certain amount of persistence (non-ephemerality). If you mean something specific by "announce", or can describe what information is in the announcement, that would help clarify what you're trying to do.
Otherwise why not just try it with NSDistributedNotificationCenter and see what happens. If it works, problem solved. If it doesn't ask again with more details.
I have no idea if mDNS is allowed in the sandbox. If not, can you advertise a Service?
Basically, I want Me.SomeApp to ask Me.GamepadManager a simple question: What's the numerical id (1, 2, 3, 4, etc.) for the gamepad with HID Device ID ABCDEFGH? Me.GamepadManager handles assigning IDs to controllers and setting their LEDs properly to reflect that ID.
That's more a client-server architecture than an "announcement" one. The client (Me.SomeApp) makes a specific request to a server (Me.GamepadManager), and gets back a specific reply. When the requests and replies are that clearly delineated, it's definitely client-server.
Since the data in both directions seems to be quite small, I see no reason you couldn't use distributed notifications for this. You have two NSStrings you can use. Make one of them encode an identifier for the request or reply. The other string then becomes the parameter. For a request, the parameter is the device ID. For a reply, the parameter is the numerical id. You can get clever and use JSON text, or you can keep it simple since both parameters seem to be simple. There may be a length limit on the strings, so keeping it simple is the safest starting choice. You could test the limits later on, if simple doesn't cut it.
You could also use UDP packets (datagrams) in a similar way. I don't know if that would require a sandbox entitlement or not. If you've never done UDP before, look at an existing UDP protocol like NTP (Network Time Protocol) to see how it works and how it was designed. To get a sense of how UDP datagrams works, see Beej's Guide to Networking.
You wouldn't need to support remote UDP, just the local loopback interface would suffice. That might simplify the security and entitlements, since you're not sending or receiving packets from outside localhost. If none of that makes sense, you should read about the loopback interface by reading the man page for lo ('man lo').
I think you could probably mock something up with distributed notifications and see how well it works, what causes it to fail (too frequent, too big, etc.), and then decide whether it's good enough to use. You'd still be at the mercy of Apple's approval process, as they may take a dim view of abusing distributed notifications in this way.
Thanks - I'm looking into this but it's so dense and I apparently need to do some RTFMing first - one thing I couldn't google though, what does it mean to have launchd vend a service? I know what launchd is but does the use of the word "vend" specifically have any significance?
I'm not asking how to do IPC, I'm asking how to do IPC *BETWEEN SANDBOXED APPS*. Distributed Notifications can't carry userInfo dictionaries from the sandbox ...
Please reread what I wrote. I didn't say "put two NSStrings in a userInfo dictionary". I referred to the two NSStrings which are available regardless of a userInfo dictionary. Those two strings can contain any text.
There are relatively few channels of communication possible between apps. Networking is one. Distributed notifications is another. There are others in the file-system, like Unix-domain sockets, pipes, named pipes, and so on, but file-system access is controlled by the sandbox. There are Posix signals, but those have effectively no payload capacity, and have their own restrictions. If you can't fit what you want into one of those channels, I don't know of any others.
D'oh! I forgot AppleScript, but that's also restricted in the sandback, IIRC.