On macOS 13 (Ventura) and later, installation could fail if Gatekeeper blocks app modifications. Note this is only applicable for external updaters like sparkle-cli where the updater and target bundle to update have different team identifiers.
When the framework or sparkle-cli is run as root, we always launch the installer (Autoupdate) in the system domain.
For the progress tool agent, we chown() the copied Updater.app so the Updater app has proper ownership of it (and clean it up later). The progress tool app may not be able to clean up the parent directory, but that's okay and will be garbage collected on a later run.
To get the username and home directory for the user session when running the framework as root, we use the SecurityConfiguration framework. Sparkle needs and depends on an active GUI user login session. If a user ssh's in to install an update, that user must be the same as the active logged in user.
Installing interactive based package updates as root is not supported. For sparkle-cli, we disallow using --interactive when running as root.
An additional error exit code is added for sparkle-cli when ran as root and trying to install a interactive based package update, which is unsupported.
* Don't expose SPUDownloadData initializer publicly
* Make SUAppcast -init unavailable
* Fix documented default user agent string
* Improve header documentation for SUAppcast(Item) and comparators
* Update more API documentation headers
Also allow returning nil in -allowedSystemProfileKeysForUpdater:
* Clarify documentation on -allowedSystemProfileKeysForUpdater:
* Rename willIdleScheduling -> notSchedule for delegate method
* Make minor correctness fix for reading info URL
In some cases for shared headers in downloader XPC Service or generate_appcast / sign_update tools, I had to do a little dance for using double quote imports.
And remove logic in SPUStandardUpdaterController and SUUpdater that defers starting the updater one cycle later, because that logic is now in SPUUpdater which they invoke.
It is too easy to start the updater "too soon" (if not using SPUStandardUpdaterController or SUUpdater) and I had some weird approach before that allowed the developer to check for updates before starting the updater and it would get deferred until the updater was started (without showing a permission prompt). Instead, defer the update cycle check allowing developer to check for updates immediately after starting the updater if needed (sparkle-cli needs to do this in one case).
Errors are now logged when checking for updates without having started the updater.
This fixes edge cases of UI being shown too early.
This allows us to remove SPUUserDriverUIComponent and remove a bunch of logic in the user driver regarding termination. The user drivers generally don't need to know about the application bundle anymore, and strictly now only show UI events.
This has another advantage of the agent being able to quit multiple instances of an application even if the application to update is sandboxed.
We enforce the logic that an application can only be relaunched if it was running initially.
This may be useful if user defaults can't be relied on for the feed URL.
For example, if an app is sandboxed, its user defaults may differ from the defaults sparkle-cli looks up.
I think I used to have this when the remote XPC callbacks were in the user driver and I removed them at some point.
These callbacks are now part of the SPUUpdaterDelegate and the logic is simpler now than before.
The command line utility makes use of these callbacks.