-
-
Save zorgiepoo/8a1af8cc5ae6878fa10433b3099771b3 to your computer and use it in GitHub Desktop.
Hack to emulate Sparkle 1.x installUpdatesIfAvailable. Please don't use it. Use SUAutomaticallyUpdate key for installing updates silently instead or roll out your own custom UI if needed instead. This approach can break in future versions because SPUStandardUserDriver provides no subclassing guarantees. But here it is for illustration purposes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import <Sparkle/Sparkle.h> | |
@interface AutoUserDriver : SPUStandardUserDriver <SPUUserDriver> | |
/* | |
Set to YES, then call -[SPUUpdater checkForUpdates]. At the end of the update cycle it will be reset to NO. | |
Eg: | |
NSBundle *mainBundle = NSBundle.mainBundle; | |
AutoUserDriver *userDriver = [[AutoUserDriver alloc] initWithHostBundle:mainBundle delegate:nil]; | |
SPUUpdater *updater = [[SPUUpdater alloc] initWithHostBundle:mainBundle applicationBundle:mainBundle userDriver:userDriver delegate:nil]; | |
NSError *error = nil; | |
BOOL startedUpdater = [updater startUpdater:&error]; | |
//... | |
// Make sure to set this property right before calling checkForUpdates | |
userDriver.automaticallyInstallsUpdatesForNextCycle = YES; | |
[updater checkForUpdates]; | |
*/ | |
@property (nonatomic) BOOL automaticallyInstallsUpdatesForNextCycle; | |
@end | |
// Fragile hack because it's private method on SPUStandardUserDriver we're relying on | |
@interface SPUStandardUserDriver (Private) | |
- (void)closeCheckingWindow; | |
@end | |
@implementation AutoUserDriver | |
{ | |
BOOL _automaticallyInstallsUpdatesForCurrentCycle; | |
} | |
@synthesize automaticallyInstallsUpdatesForNextCycle = _automaticallyInstallsUpdatesForNextCycle; | |
- (void)showUpdateFoundWithAppcastItem:(SUAppcastItem *)appcastItem state:(SPUUserUpdateState *)state reply:(void (^)(SPUUserUpdateChoice))reply | |
{ | |
// Can't automatically install updates that are info only. | |
// Also what to do if appcastItem is a criticalUpdate or majorUpgrade? | |
_automaticallyInstallsUpdatesForCurrentCycle = (state.userInitiated && _automaticallyInstallsUpdatesForNextCycle && !appcastItem.informationOnlyUpdate); | |
if (!_automaticallyInstallsUpdatesForCurrentCycle) { | |
[super showUpdateFoundWithAppcastItem:appcastItem state:state reply:reply]; | |
} else { | |
// Hack | |
if ([self respondsToSelector:@selector(closeCheckingWindow)]) { | |
[self closeCheckingWindow]; | |
} | |
reply(SPUUserUpdateChoiceInstall); | |
} | |
} | |
- (void)showUpdateNotFoundWithError:(NSError *)error acknowledgement:(void (^)(void))acknowledgement | |
{ | |
_automaticallyInstallsUpdatesForCurrentCycle = _automaticallyInstallsUpdatesForNextCycle; | |
if (_automaticallyInstallsUpdatesForCurrentCycle) { | |
acknowledgement(); | |
} else { | |
[super showUpdateNotFoundWithError:error acknowledgement:acknowledgement]; | |
} | |
} | |
- (void)showReadyToInstallAndRelaunch:(void (^)(SPUUserUpdateChoice))reply | |
{ | |
if (_automaticallyInstallsUpdatesForCurrentCycle) { | |
reply(SPUUserUpdateChoiceInstall); | |
} else { | |
[super showReadyToInstallAndRelaunch:reply]; | |
} | |
} | |
- (void)dismissUpdateInstallation | |
{ | |
// Reset state | |
_automaticallyInstallsUpdatesForCurrentCycle = NO; | |
_automaticallyInstallsUpdatesForNextCycle = NO; | |
[super dismissUpdateInstallation]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment