Skip to content

Sparkle does not restart app after update completes (sandboxed app with SUEnableInstallerLauncherService=true) #2725

Description

@jeremyhu

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...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions