Post

Replies

Boosts

Views

Activity

Custom UI and gracefully failing the .pkg installation
We have an app that is distributed in our .pkg installer (using pkgbuild and productbuild). Now we need to perform various system checks, eg. minimum macOS version and then continue or abort the installation, based on conditions. When we do that in the pre-install script, it works but the user experience is not what we need. The installation aborts with a generic message. What we want is to show the progress, eg. which checks have failed and why, a link to open the installation log, and to gracefully exit the installation. Is it possible to achieve all this without resorting to writing a custom installation mac app ?
0
0
433
Jan ’24
Preventing multiple instances of a mac app
We have a developer signed mac app that users install using an installer. Our use case is to keep the app running all the time, even when user terminates it forcefully. To achieve this, we copy a launch agent plist file to /Library/LaunchAgents with RunAtLoad=true, and KeepAlive=true, during the installation. We load/bootstrap this agent at the end of the installation using launchctl script. This serves our purpose very well. ie. 1) app is launched whenever any user logs in to the machine 2) app is relaunched automatically, even if user terminates it. By default, when the app is already running and users launches it again, there is only one instance of it which is totally fine and is expected. But there are some situations, when after a machine restart or user login, we have observed two instances of the same app running at the same time. Yes, two app icons in the dock and two app windows. But we discovered that if the user has selected 'Open at Login' by right clicking on it's icon in the Dock, and then restarts the machine or re-login, two instances are launched. We suspect that one instance is autolaunched by our keepalive/runatload launch agent. And the other one perhaps by the 'Open at Login' action. But the user experience is very bad in this situation. We tried to add LSMultipleInstancesProhibited key to the app plist, but it didn't work.
0
0
628
Oct ’23
Writing custom uninstaller app for a Mac app
I know it's uncommon for Mac apps to have uninstallers. But in our use-case, we need to have a separate uninstaller app for various purposes, including: to prompt the user for some information before deleting the app to stop the app (which is kept running via launch agent with KeepAlive = TRUE), so technically this is to unload or bootout the launch agent (and delete it's plist from ~/Library/LaunchAgents/) to remove the main app from the /Applications folder (and ofcourse removing its extensions, but I assume that is automatic) to remove the artifacts that the app has created outside it's container Please note that the main app is sandboxed, signed by developer id, and contains system extensions. I've took a look at a couple of other third party apps (eg. AWS VPN Client), which also have a separate uninstaller app. When run, it asks for system admin credentials before proceeding, and then clean up things as expected. The question is: What is the 'right' way (best practices, APIs, pitfalls etc) to build such an uninstaller app that can do all of the above ?
1
0
384
Oct ’23
How to disallow a user to remove a Global Agent
We have a UI app for Mac which we want to keep running all the time, for all the non-admin users on the system. It looks like this can be achieved by adding a 'KeepAlive' launch agent in /Library/LaunchAgents. But since this solution adds an entry into System Preferences -> Login Items -> Allow in Background, any user can toggle the ON/OFF switch to stop the app from 'keeping alive'. Is there a way to restrict user from toggling the switch (unless the user enters admin credentials)?
1
0
545
Mar ’23
File sharing between app and it's system extension
We want our system extension to generate some files, and the container app to read those files. We tried using app group like this: Configuring an app group (group.com.awesomecompany.app) in both the app and system extension FileManager.containerURL(forSecurityApplicationGroupIdentifier: "group.com.awesomecompany.app") For the system extension, this method returns path like this: /private/var/root/Library/Group Containers/group.com.awesomecompany.app For the container app, this method returns a path like this: /Users/username/Library/Group Containers/group.com.awesomecompany.app So even if system extension writes a file in that path, the container app cannot access it, because app cannot read files inside /private/var/root We tried asking the extension to write files in user's home directory. Although the app extension runs as 'root', but it does not seem to have the permission to write files inside ~/SomeFolder or ~/Library/Group Containers/group.com.awesomecompany.app What would be the correct way for the container app to read files generated by the system extension?
1
1
903
Jan ’23