Mandatory Updates?

Asked by Karl Moskowski

Is there a way to make Sparkle updates mandatory, e.g., via defaults, delegate method(s), or, perhaps, by creating an update driver sub-class? That is, if an update is available, it'll be downloaded and installed without giving the user a choice.

The reason I need this is that my app is client/server, and if things change on the server, I have to be able to force users to upgrade.

Thanks.

Question information

Language:
English Edit question
Status:
Solved
For:
Sparkle Edit question
Assignee:
No assignee Edit question
Solved by:
Karl Moskowski
Solved:
Last query:
Last reply:
Revision history for this message
Karl Moskowski (kolpanic-deactivatedaccount) said :
#1

One of the recommendations in the wiki on how to customize Sparkle's behaviour is to use a custom update driver if delegation isn't enough. However, the SUUpdateDriver and its descendants are not public headers. Moreover, searching through the old bugs, this is intentional.

Is this no longer a recommended way to provide greater control over updates?

Revision history for this message
Hofman (cmhofman) said :
#2

This would not be recommended, because in fact it's really, really, really bad behavior. You should NEVER install anything without the user's consent or even no warning whatsoever. Your users will certainly file a bug that the app just quits by itself (probably say it's a crash), and they would be in their right to call it a serious bug (and personally I would immediately delete such a badly behaving app from my system).

Your stated reason makes no sense either. It doesn't even guarantee that users will have the latest version at any time. You should make the server/client sufficiently compatible enough (i.e. make sure they check their respective 'compatibility versions'), or otherwise the user should live with his decision if he can't connect when he doesn't update.

This is why this is not provided, and you'd have to change private code in Sparkle. In particular, you'd always use SUBasicUpdateDriver in -[SUUpdater checkForUpdatesInBackground]. But again, YOU SHOULD NOT DO THAT.

Revision history for this message
Karl Moskowski (kolpanic-deactivatedaccount) said :
#3

I understand your objections. In this case, our user base is notorious for not updating the client app, then complaining when things don't work with the service. It's basically a requirement that app updates be mandatory.

Anyway, I don't want to do force updates silently; the update alert would always be presented. I basically want to make the Skip and Remind Me Later buttons non-functional and make Install Update the only option. Since it's not possible to hide the buttons from an app using the FW, I'd like to override the default behaviour when the user clicks either button, and pop a dialog saying something like "Sorry, you can't do that".

If that's not possible in the currently available customization methods, I'll either have to customize the source go another route.

BTW, does the section at the bottom of the Customization page in the Wiki no longer apply?
<http://sparkle.andymatuschak.org/documentation/pmwiki.php/Documentation/Customization>

Revision history for this message
Hofman (cmhofman) said :
#4

> I understand your objections. In this case, our user base is notorious for not updating the client app, then complaining when things don't work with the service. It's basically a requirement that app updates be mandatory.

It really sounds like you have a serious design problem in your app. Updates that lead to incompatibilities between versions should be very rare, unless perhaps you're having a beta version, in which case the users should expect things to break down. What I'm saying is that clients/servers should generally be able to connect to other versions, possibly with some loss of functionality, but not all. Moreover, when they don't update for some version that does lead to incompatibilities, the way to warn your user is to strongly emphasize that on the release notes, than those users have no reasonable right to complain.

> BTW, does the section at the bottom of the Customization page in the Wiki no longer apply?
> <http://sparkle.andymatuschak.org/documentation/pmwiki.php/Documentation/Customization>

This still applies, however for what you asked in your initial request (no user interaction) the update driver is already defined. but when you want to still show some UI but differently, you'll have to write another driver, or change the alerts. In any way, you'll have to rewrite Sparkle.

Revision history for this message
Karl Moskowski (kolpanic-deactivatedaccount) said :
#5

It's not simple incompatibilities we're worried about, it's bugs in the client. Every time the it sends something wrong to the server, someone gets notified of the bug and has to deal with it. Experience with the Windows version shows that when the users had the option of not installing updates, they didn't, but complained when things didn't work. The requirement is that updates are compulsory, and I have to handle it.

Maybe the updater delegate protocol should be enhanced to deal with user responses to the update alert and allow overriding of the default behaviour, or the UI should be customizable in code to hide the buttons, or both (with documentation about why it may not be a good idea, of course).

Anyway, my concern about the wiki is that, since Sparkle's driver classes are not public, you can't inherit from them to provide custom behaviour; you have to write your own class from the ground up. Then, unless I'm missing something, to make Sparkle use your driver, you'd have customize SUUpdater (which is public) to override checkForUpdatesWithDriver:, then deal with compiler warnings because your class doesn't inherit from SUUpdateDriver.

Revision history for this message
Andy Matuschak (andymatuschak) said :
#6

Sorry for the delayed response, Karl.

I'm not quite ready for the update drivers to be first-class guaranteed API, but you can always include the headers manually in your project if you'd like to make your own.

You can call setAutomaticallyDownloadsUpdates:YES on your SUUpdater to make the user automatically download any updates

Revision history for this message
Karl Moskowski (kolpanic-deactivatedaccount) said :
#7

Thanks for the follow-up, Andy.

However, I think a custom driver subclass is not really a solution for my problem. A better solution would be to have flags on SUUpdater that control visibility of the Skip and Remind buttons. That way, there is no confusion about updates being mandatory.

I ended up hacking the FW a bit so that when the user clicks the Skip or Remind buttons, a dialog pops up saying, You can't do that. Granted, it's bad UI, but less fragile code-wise than customizing all the localized NIBs.

AFAIK, using setAutomaticallyDownloadsUpdates:YES downloads updates silently then asks to install, right? I'd like to show the release notes UI but make the Install button the only option.

Revision history for this message
Karl Moskowski (kolpanic-deactivatedaccount) said :
#8

As soon as I submitted that last comment I thought about another solution.

How about a new appcast property that marks an update as mandatory? When such an update is found, the updater could hide the buttons, and perhaps show a Quit button.

Revision history for this message
Andy Matuschak (andymatuschak) said :
#9

I'm sorry, but I need to keep the API and the number of code paths small, and I think this is just too much of an edge case to be in the main branch. It's a totally easy change to make yourself, and bzr makes it easy to keep your branch in-sync with the main branch (just run "bzr merge lp:sparkle" every once in a while).

Revision history for this message
Adrian De La Mora (email-adriand) said :
#10

I am looking to build a few apps for a company environment and would like to have the "mandatory" update as well. It doesn't have to force the update process, but prohibit the window from going away (maybe the user will minimize it until they are ready, but it never closes).