How do I work with the Mac OS X Helper / Main architecture for basic data, general preferences, and notifications?

I have some architectural doubts about the project (Mac OS X application) I'm working on. It basically consists of two elements: a daemon that runs in the background, collects some data and a viewer used to represent the collected data.

The daemon should be visible in the status bar (without the dock icon) and includes a small menu accessible through the status bar. It stores data in the main data warehouse. One of the menu items is the link that opens the viewer . When this viewer is open, the regular GUI application should start with the dock icon and menu. The viewer also opens when you open the application itself (by double-clicking on the icon).

After some experimentation, I realized that the best way to achieve this functionality is to create two applications, the main application representing the viewer and the utility utility representing the daemon One of the reasons I did this is that it is not possible to instantly switch between LSUIElement values ​​to force the daemon / viewer state.

Now I have some questions about this architecture:

  • Both daemon and viewer applications use the same kernel data store to store and retrieve data. When using a multi-threaded application, I know that several NSManagedObjectContext objects are required for proper data synchronization. How about using multiple applications simultaneously with the same kernel data store? Is this possible even without the risk of conflicts, locks, etc.? How can I guarantee consistency?

  • The daemon should always run when the viewer starts. I achieved this by simply going through all open processes and checking if the daemon bundle id is specified. If not, the daemon is launched using NSWorkspace launchApplication . It works great. Now that the user exits the daemon, the viewer must also stop. What is the best way to notify the viewer of demon termination? I can periodically check active processes and exit the viewer if the daemon is unmounted, but it sounds a little strange. I would rather choose some kind of notification that I will send when the viewer is about to close. But since this notification needs to be sent and captured between applications, I don’t know which notification service is simple available. Any thoughts?

  • The application is isolated because it will be distributed in the Mac App Store. Launching applications with NSWorkspace launchApplication forces the target application to run in the same sandbox as the source code, which, it seems to me, is not a problem, because running both applications in the same sandbox looks better and probably is. But imagine this scenario: the daemon starts automatically when you log in (using SMLoginItemSetEnabled ), and the user double-clicks Viewer.app. Since the daemon is already running (again, this is checked by cycling through active processes), it will not be started. Now we have a demon and a viewer working in different sandboxes? Will it cause problems with settings, master data storage, etc.?

  • I would like to use NSUserDefaults for the basic configuration, can I somehow exchange this data between the daemon and the viewer? Again, both applications will have different package identifiers.

Thank you in advance for your help, appreciated!

+48
core-data daemon notifications macos helpers
Jan 14 '13 at 8:24
source share
1 answer

There is no answer to this problem, but here is how I approach this:

Both daemon and viewer applications use the same kernel data store to store and retrieve data.

Since sharing the master data repository between processes is not supported (as far as I know), I would have a daemon demonstrating the XPC Service . Instead of opening the master data store itself, the viewer will use NSXPCConnection to access the data through the daemon.

Assuming that the viewer never starts without a daemon, it can use SMLoginItemSetEnabled , as you mentioned in the question, to register the mach service for the daemon, and then connect to that service.

Here is an example code that details the settings here on the Apple website (summary: the daemon should be in App.app/Contents/Library/LoginItems/daemon.bundle.id.app ) and you can also read this blog post , which discusses some additional sandbox requirements (summary: make sure your ID command is in the daemon package identifier).

The daemon should always run when the viewer starts.

The whole set: after registering the daemon using SMLoginItemSetEnabled , it starts (if necessary) when the viewer connects to its XPC service.

Now that the user exits the daemon, the viewer must also stop.

The viewer can use the NSXPCConnection to find out when the daemon is NSXPCConnection down. The daemon can also use SMLoginItemSetEnabled for self-registration before it SMLoginItemSetEnabled so that it does not restart.

I would like to use NSUserDefaults for the basic configuration, can I somehow exchange this data between the daemon and the viewer? Again, both applications will have different package identifiers.

Use the set for this:

 // To read or write: NSUserDefaults* suiteDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.example.app.shared"]; [suiteDefaults setObject:[NSDate date] forKey:@"launchTime"]; // Add the suite to -standardUserDefaults to make reading easier: NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; [defaults addSuiteNamed:@"com.example.app.shared"]; 

To work with the sandbox, the viewer and the demon must share a group of applications. You can even use KVO to monitor changes to shared keys.

+1
Jul 30 '17 at 22:56
source share
β€” -



All Articles