Description of the problem
Sparkle does not restart app after update completes.
Do you use Sandboxing in your app?
My app is sandboxed. It has SUEnableInstallerLauncherService=true set in Info.plist and sanbox exceptions to connect to the following ports:
<string>$(PRODUCT_BUNDLE_IDENTIFIER)-spks</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)-spki</string>
The update works fine. But users need to manually quit and relaunch the app.
Version of Sparkle.framework in the latest version of your app
2.6.4
Version of Sparkle.framework in the old version of app that your users have (or N/A)
2.6.4
Sparkle's output from Console.app
2025-05-14 01:20:05.169512-0700 0x22177f Info 0xca1a25 77180 0 Redacted: (SparkleUpdater) [Redacted:Redacted] Sparkle Update will install update
2025-05-14 01:20:10.097188-0700 0x22177f Info 0xca1a25 77180 0 Redacted: (SparkleUpdater) [Redacted:Redacted] Sparkle Update finished update cycle for update error: nil
2025-05-14 01:21:25.097836-0700 0x226b65 Info 0xcb51a0 77939 0 Redacted: (SparkleUpdater) [Redacted:Redacted] Sparkle Update finished downloading
2025-05-14 01:21:27.403964-0700 0x226f8b Default 0xcb51a0 77971 0 Autoupdate: [org.sparkle-project.Sparkle:Sparkle] Extracting using '/usr/bin/ditto' '-x' '-k' '-' < '/var/root/Library/Caches/Redacted/org.sparkle-project.Sparkle/Installation/rz09IAFKF/Redacted..zip' '/var/root/Library/Caches/Redacted/org.sparkle-project.Sparkle/Installation/rz09IAFKF/c8893zK1s'
2025-05-14 01:21:29.805432-0700 0x226f89 Default 0xcb51a0 77971 0 Autoupdate: [org.sparkle-project.Sparkle:Sparkle] OK: EdDSA signature is correct
2025-05-14 01:21:29.826133-0700 0x226f89 Error 0xcb51a0 77971 0 Autoupdate: [org.sparkle-project.Sparkle:Sparkle] Code signature of the new version doesn't match the old version: identifier RedactedTrampoline and certificate root = H"0c2b0a9baf21fd7ce52e50555bfd347deafbcad5". Please ensure that old and new app is signed using exactly the same certificate.
2025-05-14 01:21:29.830408-0700 0x226f89 Default 0xcb51a0 77971 0 Autoupdate: [org.sparkle-project.Sparkle:Sparkle] old info: {
<redacted>
}
2025-05-14 01:21:29.831057-0700 0x226f89 Default 0xcb51a0 77971 0 Autoupdate: [org.sparkle-project.Sparkle:Sparkle] new info: {
<redacted>
}
2025-05-14 01:21:30.043080-0700 0x226fe2 Default 0xcb51a0 77971 0 Autoupdate: [org.sparkle-project.Sparkle:Sparkle] Skipping atomic rename/swap and gatekeeper scan because Autoupdate is not signed with same identity as the new update Redacted.app
2025-05-14 01:21:30.064454-0700 0x226b65 Info 0xcb51a0 77939 0 Redacted: (SparkleUpdater) [Redacted:Redacted] Sparkle Update will install update
2025-05-14 01:21:38.898940-0700 0x226b65 Info 0xcb51a0 77939 0 Redacted: (SparkleUpdater) [Redacted:Redacted] Sparkle Update finished update cycle for update error: nil%
Note the SparkleUpdater logs there are from our SPUUpdaterDelegate (which was only emitting logging to help track things down here...)
Steps to reproduce the behavior
I check for updates and am presented with the update release notes.
I click Install Update in the release notes window.
Expected (based on behavior I see in other apps):
I should get a dialog with a "Install and Relaunch" button.
Tapping on "Install and Relaunch" should prompt for authentication if required, install, and relaunch the app.
Observed:
I am immediately prompted to auth for the install
I see an Extracting Update dialog and the soon after an 'Update Installed' dialog. The app does not relaunch, and the user is not told to relaunch it.
--
I debugged this a bit in lldb and what I observed is that we're getting a SPUInstallationFinishedStage3 message while _relaunch is set to NO.
It looks like _relaunch is only set to YES in -installWithToolAndRelaunch:displayingUserInterface:, but that isn't getting called.
That in turn is because finishInstallationWithResponse:displayingUserInterface: isn't being called...
That looks to be usually called in -basicDriverDidFindUpdateWithAppcastItem:secondaryAppcastItem: when state is SPUUserUpdateStageInstalling , but the only time I ever see that called is for SPUUserUpdateStageNotDownloaded.
It looks like this is just a gap in how SUEnableInstallerLauncherService=true support was implemented. That seems to completely bypass these function calls, which results in _relaunch never getting set to YES, so we end up passing relaunch=no when receiving SPUInstallationFinishedStage3...
Description of the problem
Sparkle does not restart app after update completes.
Do you use Sandboxing in your app?
My app is sandboxed. It has SUEnableInstallerLauncherService=true set in Info.plist and sanbox exceptions to connect to the following ports:
The update works fine. But users need to manually quit and relaunch the app.
Version of
Sparkle.frameworkin the latest version of your app2.6.4
Version of
Sparkle.frameworkin the old version of app that your users have (or N/A)2.6.4
Sparkle's output from Console.app
Note the SparkleUpdater logs there are from our
SPUUpdaterDelegate(which was only emitting logging to help track things down here...)Steps to reproduce the behavior
I check for updates and am presented with the update release notes.
I click Install Update in the release notes window.
Expected (based on behavior I see in other apps):
I should get a dialog with a "Install and Relaunch" button.
Tapping on "Install and Relaunch" should prompt for authentication if required, install, and relaunch the app.
Observed:
I am immediately prompted to auth for the install
I see an Extracting Update dialog and the soon after an 'Update Installed' dialog. The app does not relaunch, and the user is not told to relaunch it.
--
I debugged this a bit in lldb and what I observed is that we're getting a
SPUInstallationFinishedStage3message while_relaunchis set to NO.It looks like
_relaunchis only set toYESin-installWithToolAndRelaunch:displayingUserInterface:, but that isn't getting called.That in turn is because finishInstallationWithResponse:displayingUserInterface: isn't being called...
That looks to be usually called in -basicDriverDidFindUpdateWithAppcastItem:secondaryAppcastItem: when state is SPUUserUpdateStageInstalling , but the only time I ever see that called is for SPUUserUpdateStageNotDownloaded.
It looks like this is just a gap in how SUEnableInstallerLauncherService=true support was implemented. That seems to completely bypass these function calls, which results in _relaunch never getting set to YES, so we end up passing relaunch=no when receiving SPUInstallationFinishedStage3...