### showReadyToInstallAndRelaunch: Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUserDriver.md Called when the update is ready to be installed and the application is ready to be relaunched. Prompts the user to install now or delay, and calls the relaunch block if the user chooses to install. ```APIDOC ## showReadyToInstallAndRelaunch: ### Description Update is ready to install and application is ready to be relaunched. Ask the user if they want to install now or delay. If installing now, call the `relaunch` block. ### Method Signature - (void)showReadyToInstallAndRelaunch:(void (^)(void))relaunch; ### Parameters #### relaunch - Type: Block - Description: Call to proceed with installation and relaunching. ``` -------------------------------- ### Show Ready to Install and Relaunch Prompt Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUserDriver.md Called when the update is ready to install and the application is ready to be relaunched. Prompt the user to install now or delay. Call the relaunch block to proceed with installation. ```Objective-C - (void)showReadyToInstallAndRelaunch:(void (^)(void))relaunch; ``` -------------------------------- ### Enable Installer Launcher Service Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/configuration.md Set SUEnableInstallerLauncherServiceKey to true to enable the installer launcher XPC service for normal operation. ```xml SUEnableInstallerLauncherServiceKey ``` -------------------------------- ### Enable Installer Connection Service Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/configuration.md Set SUEnableInstallerConnectionServiceKey to true to enable the installer connection XPC service. ```xml SUEnableInstallerConnectionServiceKey ``` -------------------------------- ### Enable Installer Status Service Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/configuration.md Set SUEnableInstallerStatusServiceKey to true to enable the installer status XPC service for displaying progress UI. ```xml SUEnableInstallerStatusServiceKey ``` -------------------------------- ### Prevent Relaunch After Installation Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/configuration.md Set SURelaunchHostBundleKey to false if the application should not be relaunched after installation completes. ```xml SURelaunchHostBundleKey ``` -------------------------------- ### Enable Automatic Downloading and Installing Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/configuration.md If YES, users are offered the option to enable automatic downloading and installing of updates. The actual setting persists in user defaults. ```xml SUAutomaticallyUpdate ``` -------------------------------- ### Programmatic Initialization with Start Control Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUpdaterController.md Creates a new controller programmatically, allowing control over when the updater starts. If startUpdater is NO, you must call -startUpdater later. ```Objective-C - (instancetype)initWithStartingUpdater:(BOOL)startUpdater updaterDelegate:(nullable id)updaterDelegate userDriverDelegate:(nullable id)userDriverDelegate; ``` ```Objective-C SPUStandardUpdaterController *controller = [[SPUStandardUpdaterController alloc] initWithStartingUpdater:NO updaterDelegate:self userDriverDelegate:self]; // Perform other setup... [controller startUpdater]; ``` -------------------------------- ### Sparkle Info.plist Configuration Example Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/configuration.md Example XML snippet for configuring Sparkle settings directly within your application's Info.plist file. This is a common method for static configuration. ```xml SUFeedURL https://example.com/appcast.xml SUEnableAutomaticChecks SUScheduledCheckInterval 86400 SUAutomaticallyUpdate SUPublicEDKeyKey ABCD1234EF...your Ed25519 public key... SURequireSignedFeed SUSendProfileInfoKey SUShowReleaseNotesKey SURelaunchHostBundleKey ``` -------------------------------- ### Checking ARM64 Support Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SUAppcastItem.md This example shows how to check if an update supports ARM64 architecture, relevant for Apple Silicon Macs. ```Objective-C SUAppcastItem *item = ...; #ifdef __ARM64__ if (!item.supportsArm64) { NSLog(@"This update doesn't support Apple Silicon"); } #endif ``` -------------------------------- ### SPUUpdater Initializer Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUpdater.md Initializes a new SPUUpdater instance. This instance must be explicitly started using the `startUpdater:` method. It manages the complete update lifecycle, from checking for new versions to coordinating installation. ```APIDOC ## init(hostBundle:applicationBundle:userDriver:delegate:) ### Description Initializes a new `SPUUpdater` instance that must be explicitly started with `-startUpdater:`. This method sets up the updater to manage the update lifecycle, including checking for, downloading, and installing updates. ### Method `init` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **hostBundle** (`NSBundle *`) - Required - The bundle that should be targeted for updating. For updating the main application, pass `[NSBundle mainBundle]`. For updating plugins or extensions, pass their bundle. - **applicationBundle** (`NSBundle *`) - Required - The application bundle that will be waited for termination and relaunched. Usually identical to hostBundle, but may differ when updating a plugin (where the plugin bundle is hostBundle and the hosting app is applicationBundle). - **userDriver** (`id`) - Required - The user driver that handles all UI interactions. Pass an instance of `SPUStandardUserDriver` for built-in UI or implement `SPUUserDriver` for custom UI. - **delegate** (`id`) - Optional - Optional delegate receiving callbacks about update events. The updater holds a weak reference, so you must maintain a strong reference elsewhere. Pass nil if no delegate is needed. ### Request Example ```objc SPUStandardUserDriver *userDriver = [[SPUStandardUserDriver alloc] initWithHostBundle:[NSBundle mainBundle] delegate:nil]; SPUUpdater *updater = [[SPUUpdater alloc] initWithHostBundle:[NSBundle mainBundle] applicationBundle:[NSBundle mainBundle] userDriver:userDriver delegate:self]; NSError *error = nil; if (![updater startUpdater:&error]) { NSLog(@"Failed to start updater: %@", error); } ``` ### Response #### Success Response An initialized `SPUUpdater` instance. #### Response Example None (initialization does not return a value in the typical sense, but an instance is created). ``` -------------------------------- ### Appcast XML Example Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SUAppcastItem.md An example of an appcast XML structure, demonstrating various elements used for update information, including versioning, system requirements, and enclosure details with signatures. ```xml Version 2.0 Released Wed, 09 Jun 2021 12:00:00 UTC Version 2.0
  • New feature 1
  • New feature 2
  • Bug fixes
]]>
100 2.0 10.13.0 https://example.com/rn-2.0.html https://example.com/changelog.html
``` -------------------------------- ### Handling Item Description Format Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SUAppcastItem.md This example demonstrates how to conditionally load release notes based on their format (HTML or plain text). ```Objective-C SUAppcastItem *item = ...; if ([item.itemDescriptionFormat isEqualToString:@"html"]) { [self.webView loadHTMLString:item.itemDescription baseURL:nil]; } else { self.textView.string = item.itemDescription; } ``` -------------------------------- ### Show Download Extraction Start Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUserDriver.md Called when the downloaded update begins extraction. Use this to update the UI to indicate that extraction is in progress. ```Objective-C - (void)showDownloadDidStartExtractingUpdate; ``` -------------------------------- ### Starting the Updater Manually Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUpdaterController.md Starts the updater if it is not already running. This is only necessary if the controller was initialized with `initWithStartingUpdater:updaterDelegate:userDriverDelegate:` passing NO. Calls `-[SPUUpdater startUpdater:]` internally. ```Objective-C - (void)startUpdater; ``` ```Objective-C [self.updaterController startUpdater]; ``` -------------------------------- ### Start SPUUpdater Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUpdater.md Starts the updater and begins its update cycle on the main thread. This method validates Sparkle configuration and initiates update checks if enabled or prompts for permission. ```objc - (BOOL)startUpdater:(NSError * __autoreleasing *)error; ``` ```objc NSError *error = nil; if (![updater startUpdater:&error]) { NSLog(@"Updater failed to start: %@", [error localizedDescription]); // Handle error - perhaps show alert to user that updates are unavailable } ``` -------------------------------- ### Ed25519 Example Usage Source: https://github.com/sparkle-project/sparkle/blob/2.x/Vendor/ed25519-sparkle/readme.md Demonstrates the basic workflow of creating a seed, generating a key pair, and signing a message using the Ed25519-Sparkle library. ```c unsigned char seed[32], public_key[32], private_key[64], signature[64]; unsigned char other_public_key[32], other_private_key[64], shared_secret[32]; const unsigned char message[] = "TEST MESSAGE"; /* create a random seed, and a key pair out of that seed */ if (ed25519_create_seed(seed)) { printf("error while generating seed\n"); exit(1); } ed25519_create_keypair(public_key, private_key, seed); /* create signature on the message with the key pair */ ``` -------------------------------- ### Handle Update Cycle Completion Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUpdaterDelegate.md This method is called when an update cycle (check, download, extraction, installation) finishes. It is invoked for both successful updates and errors. Note that this callback signifies the end of the updater's session, not necessarily the completion of the physical installation process. ```objc - (void)updater:(SPUUpdater *)updater didFinishUpdateCycleForUpdateCheck:(SPUUpdateCheck)updateCheck error:(NSError *)error; ``` ```objc - (void)updater:(SPUUpdater *)updater didFinishUpdateCycleForUpdateCheck:(SPUUpdateCheck)updateCheck error:(NSError *)error { if (error) { NSLog(@"Update cycle failed: %@", error.localizedDescription); } else { NSLog(@"Update cycle completed successfully"); } } ``` -------------------------------- ### startUpdater Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUpdaterController.md Starts the Sparkle updater if it is not already running. This method is typically used when the controller was initialized with `startUpdater` set to NO. ```APIDOC ## startUpdater ### Description Starts the updater if it is not already running. This is only necessary if you initialized the controller with `initWithStartingUpdater:updaterDelegate:userDriverDelegate:` passing NO. Calls `-[SPUUpdater startUpdater:]` internally. If startup fails, a standard error alert is shown to the user indicating the app is misconfigured. ### Method - (void)startUpdater; ### Parameters None ### Request Example ```objc [self.updaterController startUpdater]; ``` ### Response None ``` -------------------------------- ### Iterating Through Appcast Items Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SUAppcast.md This example demonstrates how to access and log the version strings of all items within an SUAppcast object. It's useful for inspecting the available updates. ```objc - (void)updater:(SPUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast { NSLog(@"Appcast contains %lu items:", (unsigned long)appcast.items.count); for (SUAppcastItem *item in appcast.items) { NSLog(@" - Version %@ (%@)", item.versionString, item.displayVersionString); } } ``` -------------------------------- ### initWithStartingUpdater:updaterDelegate:userDriverDelegate: Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUpdaterController.md Initializes the SPUStandardUpdaterController programmatically, providing control over whether the updater starts immediately. This allows for deferred startup and manual invocation. ```APIDOC ## initWithStartingUpdater:updaterDelegate:userDriverDelegate: ### Description Creates a new controller programmatically with control over when the updater starts. ### Method - (instancetype)initWithStartingUpdater:(BOOL)startUpdater updaterDelegate:(nullable id)updaterDelegate userDriverDelegate:(nullable id)userDriverDelegate; ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **startUpdater** (BOOL) - Required - If YES, the updater is started immediately. If NO, you must call `-startUpdater` later. - **updaterDelegate** (id) - Optional - Optional update lifecycle delegate. Weakly referenced. - **userDriverDelegate** (id) - Optional - Optional UI delegate. Weakly referenced. ### Request Example ```objc SPUStandardUpdaterController *controller = [[SPUStandardUpdaterController alloc] initWithStartingUpdater:NO updaterDelegate:self userDriverDelegate:self]; // Perform other setup... [controller startUpdater]; ``` ### Response #### Success Response An initialized controller with the updater in the requested state. #### Response Example None provided. ``` -------------------------------- ### showUpdateFoundWithAppcastItem:state:reply: Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUserDriver.md Informs the user that an update is available and asks what they want to do. Presents the update details and prompts the user to install, dismiss, or skip the update. ```APIDOC ## showUpdateFoundWithAppcastItem:state:reply: ### Description Informs the user that an update is available and asks what they want to do. Presents the update details (version, release notes, file size) and asks the user to install, dismiss, or skip the update. ### Method Signature - (void)showUpdateFoundWithAppcastItem:(SUAppcastItem *)appcastItem state:(SPUUserUpdateState *)state reply:(void (^)(SPUUserUpdateChoice))reply; ### Parameters #### Path Parameters - **appcastItem** (SUAppcastItem *) - The available update with properties: `displayVersionString`, `itemDescription`, `releaseNotesURL`, `contentLength`, `criticalUpdate`, `majorUpgrade`, `informationOnlyUpdate`, `infoURL`, `signingValidationStatus`. - **state** (SPUUserUpdateState *) - Current state including `stage` (NotDownloaded/Downloaded/Installing) and `userInitiated` (YES if user manually checked). - **reply** (Block) - Call with user's choice: `SPUUserUpdateChoiceInstall`, `SPUUserUpdateChoiceDismiss`, or `SPUUserUpdateChoiceSkip`. ### Notes - If `appcastItem.informationOnlyUpdate` is YES, the update cannot be installed directly. Direct user to `appcastItem.infoURL` instead. - If `state.stage` is `SPUUpdateStateInstalling`, the update has already begun installation and is being resumed. - For `SPUUpdateStateDownloaded`, the update has been downloaded in background and is ready to install. - User may be prompted for admin password before installation if needed. ### Example ```objc - (void)showUpdateFoundWithAppcastItem:(SUAppcastItem *)appcastItem state:(SPUUserUpdateState *)state reply:(void (^)(SPUUserUpdateChoice))reply { NSAlert *alert = [[NSAlert alloc] init]; alert.messageText = [NSString stringWithFormat:@"Update to %@ Available", appcastItem.displayVersionString]; if (appcastItem.informationOnlyUpdate) { alert.informativeText = @"A new version is available. Please visit our website."; [alert addButtonWithTitle:@"Visit Website"]; [alert addButtonWithTitle:@"Cancel"]; if ([alert runModal] == NSAlertFirstButtonReturn) { [[NSWorkspace sharedWorkspace] openURL:appcastItem.infoURL]; } reply(SPUUserUpdateChoiceDismiss); } else { alert.informativeText = appcastItem.itemDescription; [alert addButtonWithTitle:@"Install"]; [alert addButtonWithTitle:@"Remind Later"]; [alert addButtonWithTitle:@"Skip"]; NSModalResponse response = [alert runModal]; switch (response) { case NSAlertFirstButtonReturn: reply(SPUUserUpdateChoiceInstall); break; case NSAlertSecondButtonReturn: reply(SPUUserUpdateChoiceDismiss); break; case NSAlertThirdButtonReturn: reply(SPUUserUpdateChoiceSkip); break; } } } ``` ``` -------------------------------- ### Initialize SPUStandardUserDriver and SPUUpdater Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUserDriver.md Initializes the standard user driver and the updater with the application's bundle and delegate. This is a common setup for integrating Sparkle. ```objc SPUStandardUserDriver *userDriver = [[SPUStandardUserDriver alloc] initWithHostBundle:[NSBundle mainBundle] delegate:self]; SPUUpdater *updater = [[SPUUpdater alloc] initWithHostBundle:[NSBundle mainBundle] applicationBundle:[NSBundle mainBundle] userDriver:userDriver delegate:nil]; ``` -------------------------------- ### Example Appcast XML Structure Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SUAppcast.md This XML snippet demonstrates the structure of a Sparkle appcast, including channel information and individual item entries with version details and enclosure links. ```xml My App Updates https://example.com Latest updates for My App Version 2.0 Released Wed, 09 Jun 2021 12:00:00 UTC Version 2.0
  • New feature 1
  • New feature 2
]]>
100 2.0 10.13.0
Version 1.9 Mon, 01 Jun 2021 12:00:00 UTC 99 1.9
``` -------------------------------- ### Migrating from Sparkle 1.x SUUpdater to Sparkle 2.x Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/configuration.md Example demonstrating the transition from the older SUUpdater class to Sparkle 2.x's SPUStandardUpdaterController. This involves replacing the updater class and potentially moving configuration. ```objc // OLD (Sparkle 1.x) SUUpdater *updater = [SUUpdater sharedUpdater]; updater.delegate = self; updater.automaticallyChecksForUpdates = YES; // NEW (Sparkle 2.x) SPUStandardUpdaterController *controller = [[SPUStandardUpdaterController alloc] initWithUpdaterDelegate:self userDriverDelegate:nil]; // Updater is automatically started ``` -------------------------------- ### Initialize SPUUpdater Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUpdater.md Initializes a new SPUUpdater instance. You must explicitly start the updater after initialization using -startUpdater:. Ensure you maintain a strong reference to the delegate if provided. ```objc - (instancetype)initWithHostBundle:(NSBundle *)hostBundle applicationBundle:(NSBundle *)applicationBundle userDriver:(id )userDriver delegate:(nullable id)delegate; ``` ```objc SPUStandardUserDriver *userDriver = [[SPUStandardUserDriver alloc] initWithHostBundle:[NSBundle mainBundle] delegate:nil]; SPUUpdater *updater = [[SPUUpdater alloc] initWithHostBundle:[NSBundle mainBundle] applicationBundle:[NSBundle mainBundle] userDriver:userDriver delegate:self]; NSError *error = nil; if (![updater startUpdater:&error]) { NSLog(@"Failed to start updater: %@", error); } ``` -------------------------------- ### Handling Information-Only Updates with SUAppcastItem Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SUAppcastItem.md Illustrates the logic for handling an informational-only update using the informationOnlyUpdate property of SUAppcastItem. If true, it directs the user to a website; otherwise, it proceeds with a normal download and installation. ```Objective-C SUAppcastItem *item = ...; if (item.informationOnlyUpdate) { // Direct user to website NSLog(@"Please visit: %@", item.infoURL); [[NSWorkspace sharedWorkspace] openURL:item.infoURL]; } else { // Normal update - will be downloaded and installed } ``` -------------------------------- ### Programmatic Initialization with Delegates Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUpdaterController.md Creates a new controller programmatically with optional delegates for update lifecycle and UI callbacks. The updater starts automatically upon initialization. ```Objective-C - (instancetype)initWithUpdaterDelegate:(nullable id)updaterDelegate userDriverDelegate:(nullable id)userDriverDelegate; ``` ```Objective-C SPUStandardUpdaterController *controller = [[SPUStandardUpdaterController alloc] initWithUpdaterDelegate:self userDriverDelegate:self]; // The updater is immediately started; begin checking for updates ``` -------------------------------- ### Show Update Found Prompt Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUserDriver.md Informs the user about an available update and prompts for action (install, dismiss, skip). Handles information-only updates by directing the user to a URL. ```objc - (void)showUpdateFoundWithAppcastItem:(SUAppcastItem *)appcastItem state:(SPUUserUpdateState *)state reply:(void (^)(SPUUserUpdateChoice))reply; ``` ```objc - (void)showUpdateFoundWithAppcastItem:(SUAppcastItem *)appcastItem state:(SPUUserUpdateState *)state reply:(void (^)(SPUUserUpdateChoice))reply { NSAlert *alert = [[NSAlert alloc] init]; alert.messageText = [NSString stringWithFormat:@"Update to %@ Available", appcastItem.displayVersionString]; if (appcastItem.informationOnlyUpdate) { alert.informativeText = @"A new version is available. Please visit our website."; [alert addButtonWithTitle:@"Visit Website"]; [alert addButtonWithTitle:@"Cancel"]; if ([alert runModal] == NSAlertFirstButtonReturn) { [[NSWorkspace sharedWorkspace] openURL:appcastItem.infoURL]; } reply(SPUUserUpdateChoiceDismiss); } else { alert.informativeText = appcastItem.itemDescription; [alert addButtonWithTitle:@"Install"]; [alert addButtonWithTitle:@"Remind Later"]; [alert addButtonWithTitle:@"Skip"]; NSModalResponse response = [alert runModal]; switch (response) { case NSAlertFirstButtonReturn: reply(SPUUserUpdateChoiceInstall); break; case NSAlertSecondButtonReturn: reply(SPUUserUpdateChoiceDismiss); break; case NSAlertThirdButtonReturn: reply(SPUUserUpdateChoiceSkip); break; } } } ``` -------------------------------- ### Control Minimization of Status Window Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUserDriverDelegate.md Determine whether the download, extraction, or installation status window can be minimized. Return NO to prevent minimization, which is useful for critical updates where visibility is important. ```objc - (BOOL)standardUserDriverAllowsMinimizableStatusWindow { // Don't allow minimizing critical security updates return !self.criticalSecurityUpdate; } ``` -------------------------------- ### initWithUpdaterDelegate:userDriverDelegate: Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUpdaterController.md Initializes the SPUStandardUpdaterController programmatically with optional delegates for update lifecycle and UI callbacks. The updater starts automatically upon initialization. ```APIDOC ## initWithUpdaterDelegate:userDriverDelegate: ### Description Creates a new controller programmatically with optional delegates. The updater is started automatically. ### Method - (instancetype)initWithUpdaterDelegate:(nullable id)updaterDelegate userDriverDelegate:(nullable id)userDriverDelegate; ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **updaterDelegate** (id) - Optional - Optional delegate receiving update lifecycle callbacks. Weakly referenced; maintain a strong reference. - **userDriverDelegate** (id) - Optional - Optional delegate receiving UI-related callbacks. Weakly referenced; maintain a strong reference. ### Request Example ```objc SPUStandardUpdaterController *controller = [[SPUStandardUpdaterController alloc] initWithUpdaterDelegate:self userDriverDelegate:self]; // The updater is immediately started; begin checking for updates ``` ### Response #### Success Response An initialized controller with an already-started updater. #### Response Example None provided. ``` -------------------------------- ### Appcast Phase Error: SUResumeAppcastError Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/errors.md Indicates a failure to resume an update from a previous session. The installer session was lost, and a fresh update check will be initiated. ```objective-c // Code: 1004 // Constant: SUResumeAppcastError // Trigger Condition: Failed to resume an update from a previous session (retrieving stored appcast item data from installer). // Resolution: The installer session was lost. A fresh update check will be initiated. ``` -------------------------------- ### standardUserDriverWillFinishUpdateSession Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUserDriverDelegate.md Called before the update session finishes. This method is invoked after the user dismisses or skips an update, after an error, or after installation completes. It's intended for cleaning up any custom UI elements introduced during the update process. ```APIDOC ## standardUserDriverWillFinishUpdateSession ### Description Called before the update session finishes. This occurs after the user dismisses/skips an update, after an error, or after installation completes. Use this to clean up any custom UI you added (notification badges, notifications, custom indicators, etc.). This is different from `-standardUserDriverDidReceiveUserAttentionForUpdate:` — this is called after the entire session ends, not when the user first focuses on the alert. ### Method `-(void)standardUserDriverWillFinishUpdateSession;` ### Example ```objc - (void)standardUserDriverWillFinishUpdateSession { // Cleanup after update session ends self.updateIndicator.hidden = YES; [self.notificationCenter removeAllDeliveredNotifications]; } ``` ``` -------------------------------- ### Observing Appcast Load Notification Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SUAppcast.md This example shows how to observe the SUUpdaterDidFinishLoadingAppCastNotification to be notified when an appcast has finished loading. The loaded SUAppcast object can be accessed from the notification's user info. ```objc - (void)applicationDidFinishLaunching:(NSNotification *)notification { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appcastDidLoad:) name:SUUpdaterDidFinishLoadingAppCastNotification object:updater]; } - (void)appcastDidLoad:(NSNotification *)notification { SUAppcast *appcast = notification.userInfo[SUUpdaterAppcastNotificationKey]; NSLog(@"Appcast loaded with %lu items", appcast.items.count); } ``` -------------------------------- ### Accessing SPUStandardUpdaterController from Nib Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUpdaterController.md Example of accessing an SPUStandardUpdaterController instance that was loaded from a nib file within an application's launch sequence. Ensure this code runs on the main thread. ```objective-c - (void)applicationDidFinishLaunching:(NSNotification *)notification { // IBOutlet to the nib-instantiated controller [self.updaterController.updater checkForUpdatesInBackground]; } ``` -------------------------------- ### Clean up after update session ends Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUserDriverDelegate.md Implement this method to perform cleanup tasks after an update session concludes. This is called after the user dismisses, skips, or an error occurs during an update, or after installation completes. Use it to remove any custom UI elements like notification badges or indicators. ```objc - (void)standardUserDriverWillFinishUpdateSession; ``` ```objc - (void)standardUserDriverWillFinishUpdateSession { // Cleanup after update session ends self.updateIndicator.hidden = YES; [self.notificationCenter removeAllDeliveredNotifications]; } ``` -------------------------------- ### Prompt User on First Launch Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/configuration.md Set SUPromptUserOnFirstLaunchKey to true to prompt users about automatic checking on the first launch instead of the second. ```xml SUPromptUserOnFirstLaunchKey ``` -------------------------------- ### Handling Startup Errors Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/errors.md Shows how to check for and handle errors that occur during the initialization and startup of the Sparkle updater. This includes common issues like invalid feed URLs or missing bundle identifiers. ```objc NSError *error = nil; if (![updater startUpdater:&error]) { if ([error.domain isEqualToString:SUSparkleErrorDomain]) { switch (error.code) { case SUInvalidFeedURLError: NSLog(@"Please set SUFeedURL in Info.plist"); break; case SUInvalidHostBundleIdentifierError: NSLog(@"Bundle is missing CFBundleIdentifier"); break; case SUNoPublicDSAFoundError: NSLog(@"Appcast signing required but no key configured"); break; default: NSLog(@"Failed to start updater: %@", error.localizedDescription); } } } ``` -------------------------------- ### Access System Profile Array Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUpdater.md Get the array of system profile dictionaries sent when `sendsSystemProfile` is enabled. This property is read-only. ```Objective-C @property (nonatomic, readonly, copy) NSArray *> *systemProfileArray; ``` -------------------------------- ### updater:didFinishUpdateCycleForUpdateCheck:error: Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUpdaterDelegate.md Called when an update cycle (check, download, extraction, installation) completes. This is called for both successful completions and errors. ```APIDOC ## updater:didFinishUpdateCycleForUpdateCheck:error: ### Description Called when an update cycle (check, download, extraction, installation) completes. This is called for both successful completions and errors. Note this is called when the updater's session ends, not necessarily when the update installation physically finishes (the separate installer process may still be running). ### Parameters #### Path Parameters - **updater** (SPUUpdater *) - The updater instance. - **updateCheck** (SPUUpdateCheck) - The type of check that was performed. - **error** (NSError *) - An error if the update cycle failed, or nil if it succeeded. ### Request Example ```objc - (void)updater:(SPUUpdater *)updater didFinishUpdateCycleForUpdateCheck:(SPUUpdateCheck)updateCheck error:(NSError *)error { if (error) { NSLog(@"Update cycle failed: %@", error.localizedDescription); } else { NSLog(@"Update cycle completed successfully"); } } ``` ``` -------------------------------- ### Disallow Automatic Updates Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/configuration.md If NO, prevents users from enabling automatic downloading and installing of updates entirely. The option is not offered in the permission prompt. ```xml SUAllowsAutomaticUpdates ``` -------------------------------- ### SPUUpdater Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/README.md The primary entry point for update control. Manages checking, downloading, and installing updates. Must be used on the main thread. ```APIDOC ## Class: SPUUpdater ### Description The primary entry point for controlling the software update process. It manages checking for updates, downloading them, and initiating the installation. ### Usage Must be used on the main thread. ### Delegate Weakly references `SPUUpdaterDelegate` for controlling update logic. ``` -------------------------------- ### Enable Downloader Service Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/configuration.md Set SUEnableDownloaderServiceKey to true to enable the downloader XPC service for secure isolated downloads. ```xml SUEnableDownloaderServiceKey ``` -------------------------------- ### SPUUserUpdateStage Enumeration Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/types.md Indicates the current phase of an update's lifecycle. This helps track whether an update has been found, downloaded, or is currently being installed. ```objc typedef NS_ENUM(NSInteger, SPUUserUpdateStage) { SPUUserUpdateStageNotDownloaded = 0, SPUUserUpdateStageDownloaded = 1, SPUUserUpdateStageInstalling = 2 }; ``` -------------------------------- ### Show Update Release Notes Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUserDriver.md Displays the release notes for a downloaded update. It handles both HTML and plain text formats by loading them into a web view or text view respectively. ```objc - (void)showUpdateReleaseNotesWithDownloadData:(SPUDownloadData *)downloadData; ``` ```objc - (void)showUpdateReleaseNotesWithDownloadData:(SPUDownloadData *)downloadData { NSString *notes = [[NSString alloc] initWithData:downloadData.data encoding:NSUTF8StringEncoding]; if ([downloadData.MIMEType hasPrefix:@"text/html"]) { [self.webView loadHTMLString:notes baseURL:nil]; } else { self.textView.string = notes; } [self.releaseNotesWindow makeKeyAndOrderFront:nil]; } ``` -------------------------------- ### Clear Last Update Check Date (Bash) Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUpdater.md Example command to clear the last update check date from user defaults for testing purposes. ```Bash defaults delete com.example.MyApp SULastCheckTime ``` -------------------------------- ### Get Last Update Check Date Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUpdater.md Retrieve the date and time of the last successful update check. This property is read-only and read on the main thread. ```Objective-C @property (nonatomic, readonly, copy, nullable) NSDate *lastUpdateCheckDate; ``` -------------------------------- ### Check for Update Information Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUpdater.md Performs a probing check for updates, notifying the delegate of the results without showing any UI or offering installation. Useful for informational purposes only. ```objc - (void)checkForUpdateInformation; ``` ```objc [updater checkForUpdateInformation]; // In your delegate: - (void)updater:(SPUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)item { NSLog(@"New version available: %@", item.displayVersionString); } ``` -------------------------------- ### Checking SUAppcastItem Download URL and Information URL Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SUAppcastItem.md Illustrates how to check for the presence of a download URL (fileURL) or an information URL (infoURL) for an SUAppcastItem. This helps determine if an update is downloadable or informational. ```Objective-C SUAppcastItem *item = ...; if (item.fileURL) { NSLog(@"Download from: %@", item.fileURL); } else if (item.informationOnlyUpdate) { NSLog(@"No download available. Info: %@", item.infoURL); } ``` -------------------------------- ### SPUUserUpdateChoice Enumeration Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/types.md Represents the user's decision when presented with an available update. This enumeration is crucial for handling user interactions like skipping, installing, or dismissing an update. ```objc typedef NS_ENUM(NSInteger, SPUUserUpdateChoice) { SPUUserUpdateChoiceSkip = 0, SPUUserUpdateChoiceInstall = 1, SPUUserUpdateChoiceDismiss = 2 }; ``` -------------------------------- ### Sparkle Command-Line Arguments for Testing Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/configuration.md Pass these arguments to your application for testing specific Sparkle behaviors. These allow overriding default configurations for testing purposes. ```bash ./MyApp.app/Contents/MacOS/MyApp -SUEnableAutomaticChecks NO ``` ```bash ./MyApp.app/Contents/MacOS/MyApp -SUScheduledCheckInterval 3600 ``` ```bash ./MyApp.app/Contents/MacOS/MyApp -SUFeedURL https://example.com/appcast-test.xml ``` -------------------------------- ### standardUserDriverAllowsMinimizableStatusWindow Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUserDriverDelegate.md Called to determine whether the download/extraction/installation status window can be minimized. Return NO to prevent minimization for critical updates. ```APIDOC ## standardUserDriverAllowsMinimizableStatusWindow ### Description Called to determine whether the download/extraction/installation status window can be minimized. For regular application updates, the status window is minimizable by default. Return NO to prevent minimization (useful for critical updates or when you want to ensure the status remains visible). ### Method - (BOOL)standardUserDriverAllowsMinimizableStatusWindow; ### Parameters None ### Response - **Returns**: YES to allow minimization (default), NO to prevent it. ### Example ```objc - (BOOL)standardUserDriverAllowsMinimizableStatusWindow { // Don't allow minimizing critical security updates return !self.criticalSecurityUpdate; } ``` ``` -------------------------------- ### showUpdateErrorWithError:acknowledgement: Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUserDriver.md Called when an error occurs during the update process (downloading, extracting, or installing). It displays error details and calls an acknowledgement block when the user closes the dialog. ```APIDOC ## showUpdateErrorWithError:acknowledgement: ### Description An error occurred during the update process. Called if an error happens while downloading, extracting, or installing the update. The error contains details about the failure. Call acknowledgement when the user closes the dialog. ### Method Signature - (void)showUpdateErrorWithError:(NSError *)error acknowledgement:(void (^)(void))acknowledgement; ### Parameters #### error - Type: NSError * - Description: Describes the failure (download error, signature validation failure, installation error, etc.). Domain is `SUSparkleErrorDomain`. #### acknowledgement - Type: Block - Description: Call when the user dismisses the dialog. ### Example ```objc - (void)showUpdateErrorWithError:(NSError *)error \ acknowledgement:(void (^)(void))acknowledgement { NSAlert *alert = [[NSAlert alloc] init]; alert.messageText = @"Update Failed"; alert.informativeText = error.localizedDescription; [alert addButtonWithTitle:@"OK"]; [alert runModal]; acknowledgement(); } ``` ``` -------------------------------- ### Provide Custom Version Formatter Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUserDriverDelegate.md Return an object conforming to the SUVersionDisplay protocol to format version numbers for display. If nil is returned, Sparkle's default formatter will be used. This allows for custom version string presentation. ```objc - (id)standardUserDriverRequestsVersionDisplayer { return self.customVersionFormatter; } // Implement SUVersionDisplay - (NSString *)formatVersion:(NSString *)version { return [NSString stringWithFormat:@"v%@", version]; } ``` -------------------------------- ### checkForUpdateInformation Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUpdater.md Performs a "probing" check for updates that notifies the delegate without showing UI or offering to install. Useful for checking update availability for informational purposes only. ```APIDOC ## checkForUpdateInformation ### Description Performs a "probing" check for updates that notifies the delegate without showing UI or offering to install. This is useful for checking update availability for informational purposes only. The delegate methods `-[SPUUpdaterDelegate updater:didFindValidUpdate:]` and `-[SPUUpdaterDelegate updaterDidNotFindUpdate:]` are called with results, but no update installation UI is shown. This method does nothing if `sessionInProgress` is YES. ### Method `- (void)checkForUpdateInformation;` ### Threading This must be called on the main thread. ### Example ```objc [updater checkForUpdateInformation]; // In your delegate: - (void)updater:(SPUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)item { NSLog(@"New version available: %@", item.displayVersionString); } ``` ``` -------------------------------- ### showDownloadDidStartExtractingUpdate Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUserDriver.md Called when the downloaded update begins extraction. Use this to update the progress UI to indicate that extraction is occurring. ```APIDOC ## showDownloadDidStartExtractingUpdate ### Description Called when the downloaded update is beginning extraction. Update the progress UI to show extraction is occurring. ### Method Signature - (void)showDownloadDidStartExtractingUpdate; ``` -------------------------------- ### showUpdateReleaseNotesWithDownloadData: Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUUserDriver.md Shows the release notes for the update after it has been downloaded. Displays the release notes, which can be in HTML or plain text format. ```APIDOC ## showUpdateReleaseNotesWithDownloadData: ### Description Shows the release notes for the update. Called after the update is shown to the user. Display the release notes (either as HTML or plain text depending on availability). The `downloadData` parameter contains the downloaded release notes. ### Method Signature - (void)showUpdateReleaseNotesWithDownloadData:(SPUDownloadData *)downloadData; ### Parameters #### Path Parameters - **downloadData** (SPUDownloadData *) - Contains `data` (NSData), `textEncodingName` (e.g., "utf-8"), and `MIMEType` (e.g., "text/html", "text/plain"). ### Example ```objc - (void)showUpdateReleaseNotesWithDownloadData:(SPUDownloadData *)downloadData { NSString *notes = [[NSString alloc] initWithData:downloadData.data encoding:NSUTF8StringEncoding]; if ([downloadData.MIMEType hasPrefix:@"text/html"]) { [self.webView loadHTMLString:notes baseURL:nil]; } else { self.textView.string = notes; } [self.releaseNotesWindow makeKeyAndOrderFront:nil]; } ``` ``` -------------------------------- ### standardUserDriverWillHandleShowingUpdate:forUpdate:state: Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUserDriverDelegate.md Called before an update will be shown to the user. If handleShowingUpdate is NO, the delegate should show the update itself. ```APIDOC ## standardUserDriverWillHandleShowingUpdate:forUpdate:state: ### Description Called before an update will be shown to the user. If `handleShowingUpdate` is YES, Sparkle will handle showing the update via its standard UI. If NO (because you returned NO from `standardUserDriverShouldHandleShowingScheduledUpdate:`), you should show the update yourself at an appropriate time. ### Method - (void)standardUserDriverWillHandleShowingUpdate:(BOOL)handleShowingUpdate forUpdate:(SUAppcastItem *)update state:(SPUUserUpdateState *)state; ### Parameters #### Path Parameters - **handleShowingUpdate** (BOOL) - YES if Sparkle will handle showing; NO if delegate handles it. - **update** (SUAppcastItem *) - The update to be shown. - **state** (SPUUserUpdateState *) - Current state (stage, userInitiated). ### Example ```objc - (void)standardUserDriverWillHandleShowingUpdate:(BOOL)handleShowingUpdate forUpdate:(SUAppcastItem *)update state:(SPUUserUpdateState *)state { if (!handleShowingUpdate) { // Show gentle reminder instead of modal [self scheduleGentleReminderForUpdate:update]; } } ``` ``` -------------------------------- ### Initializing SPUUpdater with Delegates in Objective-C Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/configuration.md Set up an SPUUpdater instance by providing delegates for user interaction and update logic. This is essential for custom UI or advanced configuration. ```objc // Create updater with delegates SPUStandardUserDriver *userDriver = [[SPUStandardUserDriver alloc] initWithHostBundle:[NSBundle mainBundle] delegate:self]; // SPUStandardUserDriverDelegate SPUUpdater *updater = [[SPUUpdater alloc] initWithHostBundle:[NSBundle mainBundle] applicationBundle:[NSBundle mainBundle] userDriver:userDriver delegate:self]; // SPUUpdaterDelegate NSError *error = nil; [updater startUpdater:&error]; ``` -------------------------------- ### standardUserDriverShowVersionHistoryForAppcastItem: Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SPUStandardUserDriverDelegate.md Called to display version history/release notes when no update is found. If not implemented, Sparkle opens the release notes URL in the user's default browser. Implement this to show release notes in-app. ```APIDOC ## standardUserDriverShowVersionHistoryForAppcastItem: ### Description Called to display version history/release notes when no update is found. If not implemented, Sparkle opens `fullReleaseNotesURL` (or `releaseNotesURL`) in the user's default browser. Implement this to show release notes in-app. ### Method - (void)standardUserDriverShowVersionHistoryForAppcastItem:(SUAppcastItem *)item; ### Parameters #### Path Parameters - **item** (SUAppcastItem *) - The latest appcast item with `fullReleaseNotesURL`. ### Response None ### Example ```objc - (void)standardUserDriverShowVersionHistoryForAppcastItem:(SUAppcastItem *)item { if (item.fullReleaseNotesURL) { // Load and display in-app [self.webView loadRequest: [NSURLRequest requestWithURL:item.fullReleaseNotesURL]]; [self.versionHistoryWindow makeKeyAndOrderFront:nil]; } } ``` ``` -------------------------------- ### Phased Rollout Interval Property Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SUAppcastItem.md Defines the phased rollout interval in seconds. When set, the update is rolled out gradually based on user installation date. If nil, the update is available immediately. ```objc @property (nonatomic, readonly, nullable) NSTimeInterval phasedRolloutInterval; ``` ```xml 604800 ``` -------------------------------- ### Accessing SUAppcastItem Display Version String Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SUAppcastItem.md Shows how to retrieve the human-readable version string for display to users, which typically corresponds to the bundle's CFBundleShortVersionString. ```Objective-C SUAppcastItem *item = ...; NSLog(@"User sees: %@", item.displayVersionString); // Output: "2.0" ``` -------------------------------- ### Appcast XML for Minimum System Version Source: https://github.com/sparkle-project/sparkle/blob/2.x/_autodocs/api-reference/SUAppcastItem.md This XML snippet shows how to specify the minimum system version required for an update in the appcast file. ```XML 10.13.0 ```