From 8ee3a8558f4efb21c1d78ecec149828b7814e271 Mon Sep 17 00:00:00 2001 From: Zorg Date: Tue, 25 Nov 2025 14:29:18 -0800 Subject: [PATCH] Refine updater customizations documentation --- documentation/customization/index.md | 145 +++------------------- documentation/preferences-ui/index.md | 56 ++------- documentation/programmatic-setup/index.md | 16 +-- documentation/publishing/index.md | 2 +- 4 files changed, 29 insertions(+), 190 deletions(-) diff --git a/documentation/customization/index.md b/documentation/customization/index.md index 1856b5c..24d126c 100644 --- a/documentation/customization/index.md +++ b/documentation/customization/index.md @@ -5,20 +5,27 @@ title: Customizing Sparkle --- ## Customizing Sparkle -Here are the main routes by which you can bend Sparkle's behavior to your will: +Besides the `SUFeedURL` and `SUPublicEDKey` options, Sparkle will choose defaults for your app's update behavior. However you can change these settings if you want different behavior. + +For example: + +* If you do not want Sparkle to prompt the user (on second app launch) asking for permission if your app can check for updates automatically in the background, set `SUEnableAutomaticChecks` in your app's Info.plist. +* If you want Sparkle to automatically download and install updates silently in the background instead of notifying users of updates every time by default, enable `SUAutomaticallyUpdate` in your app's Info.plist. + +Some of the Info.plist settings below are also paired with an updater API to change the settings at runtime, like `SUEnableAutomaticChecks` with [automaticallyChecksForUpdates](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(py)automaticallyChecksForUpdates). The Info.plist settings are meant for default configuration, while the runtime APIs are in response to user setting changes. Please do not use the runtime APIs for setting initial default behavior. Check how to [add update settings](/documentation/preferences-ui/) for examples on changing user settings. ### Info.plist Settings {:.table .table-bordered} | Key | Type | Value | | --- | ---- | ----- | ------- | -| `SUFeedURL` | String | The URL of your appcast, e.g. `https://example.com/appcast.xml`. It's recommended to always set it in Info.plist, even if you change it later programmatically. | +| `SUFeedURL` | String | The URL of your appcast, e.g. `https://example.com/appcast.xml`. It's recommended to set it in Info.plist, even if you change it later programmatically. | | `SUPublicEDKey` | String | The base64-encoded public EdDSA key. Use Sparkle's `generate_keys` tool to get it. | -| `SUEnableAutomaticChecks` | Boolean | By default when this is not set, automatic checking for updates is initially disabled but users will be prompted for permission for Sparkle to check for updates automatically on second launch. If permission is granted, automatic checks for updates then becomes enabled. As of Sparkle 2.4 or later, the user will also have an option to opt into or out of automatic downloading of updates; the default state is based on the `SUAutomaticallyUpdate` setting.
Setting this to `YES` enables automatic checking for updates (but not installation) by default, without asking your users for permission first.
Setting this to `NO` disables automatic checking for updates by default, also without asking your users for permission.
This default property can later be overridden by setting [automaticallyChecksForUpdates](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(py)automaticallyChecksForUpdates) in response to user setting changes. | -| `SUEnableSystemProfiling` | Boolean | Default: `NO`. Enables anonymous system profiling. See [System Profiling](/documentation/system-profiling) for more. | -| `SUScheduledCheckInterval` | Number | The number of seconds between updates. The default is `86400` (1 day). Setting to 0 disables updates.

**Note:** this has a minimum bound of 1 hour in order to keep you from accidentally overloading your servers. | +| `SUEnableAutomaticChecks` | Boolean | By default when this is not set, automatic checking for updates is initially disabled but users will be prompted for permission for Sparkle to check for updates automatically on second launch. If permission is granted, automatic checks for updates then becomes enabled. As of Sparkle 2.4 or later, the user will also have an option to opt in or out of automatic downloading of updates; the default state is based on the `SUAutomaticallyUpdate` setting.
Setting this to `YES` enables automatic checking for updates (but not installation) by default, without asking your users for permission first.
Setting this to `NO` disables automatic checking for updates by default, also without asking your users for permission.
This default property can later be overridden by setting [automaticallyChecksForUpdates](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(py)automaticallyChecksForUpdates) in response to user setting changes. | +| `SUScheduledCheckInterval` | Number | The number of seconds between updates. The default is `86400` (1 day).

**Note:** this has a minimum bound of 1 hour in order to keep you from accidentally overloading your servers. | +| `SUAutomaticallyUpdate` | Boolean | Default: `NO`. Enables automatic download and installation of updates by default. If set to `YES`, Sparkle will attempt to download and install new updates silently in the background. Updates may be downloaded but not installed automatically if authorization is required. If the application hasn't quit for 1 week the user will be presented with installing the downloaded update (unless the updater delegate overrides this).
This default property can later be overridden by setting [automaticallyDownloadsUpdates](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(py)automaticallyDownloadsUpdates) in response to user setting changes (for example, the standard update alert has a checkbox for changing this). | `SUAllowsAutomaticUpdates` | Boolean | By default, Sparkle automatically presents your users with the *option* to allow to automatically download and install any available updates if automatic checking of updates is enabled.
Set this to `NO` to disallow automatic updates and require manual installation every time.
Set this to `YES` to always allow automatic updates even if automatic checking of updates is disabled. | -| `SUAutomaticallyUpdate` | Boolean | Default: `NO`. Enables automatic download and installation of updates by default. If set to `YES`, Sparkle will attempt to download and install new updates silently in the background. In Sparkle 1, updates won't be opted into this if users need to provide authorization. In Sparkle 2, updates will be downloaded but not installed automatically if authorization is required. In all versions of Sparkle, if the application hasn't quit for 1 week the user will be presented with installing the downloaded update (unless the updater delegate overrides this).
This default property can later be overridden by setting [automaticallyDownloadsUpdates](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(py)automaticallyDownloadsUpdates) in response to user setting changes. +| `SUEnableSystemProfiling` | Boolean | Default: `NO`. Enables anonymous system profiling. See [System Profiling](/documentation/system-profiling) for more. | | `SUVerifyUpdateBeforeExtraction` | Boolean | Default: `NO`. Set this to `YES` to force verification of updates before Sparkle extracts the downloaded update. Use this setting if you want stronger update validation and you aren't likely to lose access to your private EdDSA key (typically stored inside the macOS Keychain). EdDSA signing is required to use this setting. [Key rotation](/documentation/#rotating-signing-keys) is still possible by using Apple Developer ID code signed disk images as fallback. This setting is available in Sparkle 2.7 and later. | | `SUShowReleaseNotes` | Boolean | Default: `YES`. Set this to `NO` to hide release notes display from the update alert. | | `SUAllowedURLSchemes` | Array of Strings | An array of custom URL schemes allowed to be clicked from Sparkle's release notes view. By default, Sparkle only allows clicks to links that have a safe known URL scheme (like `https`). This setting is available in Sparkle 2.5 and later. @@ -39,128 +46,6 @@ Here are the Info.plist settings relevant to use for Sandboxed applications usin | `SUEnableInstallerConnectionService` | Boolean | Default: `NO`. Set this to `YES` to enable using the Installer Connection Service. This service is usually not needed due to being able to [add a mach name lookup exception entitlement](/documentation/sandboxing#installer-connection--status-services) instead. This service is not included in Sparkle's framework distribution by default. | | `SUEnableInstallerStatusService` | Boolean | Default: `NO`. Set this to `YES` to enable using the Installer Status Service. This service is usually not needed due to being able to [add a mach name lookup exception entitlement](/documentation/sandboxing#installer-connection--status-services) instead. This service is not included in Sparkle's framework distribution by default. | -### Sparkle 2 APIs - -Please visit the [Sparkle 2 API Reference](/documentation/api-reference). - -### Sparkle 1 APIs - -#### Calls to SUUpdater - -The `SUUpdater` object is the main controller for the updating system in your app. There is a singleton instance of this class for each bundle being updated. If you're trying to update the running .app, you can retrieve the appropriate `SUUpdater` by calling `[SUUpdater sharedUpdater]`. If you're trying to update some [other bundle](/documentation/bundles/), you can use `[SUUpdater updaterForBundle:(NSBundle *)myBundle]`. - -Once you have the `SUUpdater` instance, there are a few interesting accessors you could use. Please use them only if you need dynamic behavior (e.g. user preferences). Do not use these functions to set default configuration. Use Info.plist keys to set default configuration instead. - -```objc -- (void)setAutomaticallyChecksForUpdates:(BOOL)automaticallyChecks; -- (BOOL)automaticallyChecksForUpdates; - -- (void)setUpdateCheckInterval:(NSTimeInterval)interval; -- (NSTimeInterval)updateCheckInterval; - -- (void)setFeedURL:(NSURL *)feedURL; -- (NSURL *)feedURL; - -- (void)setSendsSystemProfile:(BOOL)sendsSystemProfile; -- (BOOL)sendsSystemProfile; - -- (void)setAutomaticallyDownloadsUpdates:(BOOL)automaticallyDownloadsUpdates; -- (BOOL)automaticallyDownloadsUpdates; -``` - -There is a risk of race conditions. If you want to make sure these settings are changed before the first automatic update check, you should do this in the `NSApplication` delegate method `-applicationWillFinishLaunching:`. For a non-app bundle you should then make the changes immediately after you first create the `SUUpdater` instance in your code. - -A few more methods of interest: - -```objc -// This IBAction is meant for a main menu item. Hook up any menu item to this action, -// and Sparkle will check for updates and report back its findings through UI. -- (IBAction)checkForUpdates:sender; - -// This kicks off an update meant to be programmatically initiated. That is, -// it will display no UI unless it actually finds an update, in which case it -// proceeds as usual. If the automated downloading is turned on, however, -// this will invoke that behavior, and if an update is found, it will be -// downloaded and prepped for installation. -// -// You do not need to call this. Sparkle calls it automatically according to -// the update schedule. -- (void)checkForUpdatesInBackground; - -// This begins a "probing" check for updates which will not actually offer to -// update to that version. The delegate methods, though, (up to updater:didFindValidUpdate: -// and updaterDidNotFindUpdate:), are called, so you can use that information in your UI. -// Essentially, you can use this to UI-lessly determine if there's an update. -- (void)checkForUpdateInformation; - -// Date of last update check. Returns nil if no check has been performed. -- (NSDate *)lastUpdateCheckDate; - -// Call this to appropriately schedule or cancel the update checking timer according -// to the preferences for time interval and automatic checks. If this SUUpdater instance -// was not present during the application's launch, you must call this method to start -// the update cycle explicitly. -- (void)resetUpdateCycle; - -- (BOOL)updateInProgress; - -- (void)setDelegate:(id)delegate; // See below for more information on the delegate. -- delegate; -``` - -#### SUUpdater delegate methods - -You can control the SUUpdater's behavior a little more closely by providing it with a delegate. Here are the delegate methods you might implement: - -```objc -// Use this to override the default behavior for Sparkle prompting the -// user about automatic update checks. You could use this to make Sparkle -// prompt for permission on the first launch instead of the second. -- (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)bundle; - -- (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast; - -// If you're using special logic or extensions in your appcast, implement -// this to use your own logic for finding a valid update, if any, in the given appcast. -- (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast - forUpdater:(SUUpdater *)bundle; - -- (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update; -- (void)updaterDidNotFindUpdate:(SUUpdater *)update; - -// Sent immediately before installing the specified update. -- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update; - -// Return YES to delay the relaunch until you do some processing. -// Invoke the provided NSInvocation to continue the relaunch. -- (BOOL)updater:(SUUpdater *)updater - shouldPostponeRelaunchForUpdate:(SUAppcastItem *)update - untilInvoking:(NSInvocation *)invocation; - -// Called immediately before relaunching. -- (void)updaterWillRelaunchApplication:(SUUpdater *)updater; - -// Called if the application has been relaunched from an update -- (void)updaterDidRelaunchApplication:(SUUpdater *)updater; - -// This method allows you to provide a custom version comparator. -// If you don't implement this method or return nil, the standard version -// comparator will be used. See SUVersionComparisonProtocol.h for more. -- (id )versionComparatorForUpdater:(SUUpdater *)updater; - -// Returns the path which is used to relaunch the client after the update -// is installed. By default, the path of the host bundle. -- (NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater; - -// This method allows you to add extra parameters to the appcast URL, -// potentially based on whether or not Sparkle will also be sending along -// the system profile. This method should return an array of dictionaries -// with keys: "key", "value", "displayKey", "displayValue", the latter two -// being human-readable variants of the former two. -- (NSArray *)feedParametersForUpdater:(SUUpdater *)updater - sendingSystemProfile:(BOOL)sendingProfile; -``` - -#### Other options +### Sparkle APIs -If these methods aren't enough to do what you need, you're going to have to dig into Sparkle's code. You might start by creating a different update driver: check out SUBasicUpdateDriver.h to get an idea. +Please visit the [Sparkle 2 API Reference](/documentation/api-reference) for full documentation on class and delegate APIs. diff --git a/documentation/preferences-ui/index.md b/documentation/preferences-ui/index.md index 0705e5d..98cb710 100644 --- a/documentation/preferences-ui/index.md +++ b/documentation/preferences-ui/index.md @@ -4,20 +4,18 @@ id: documentation title: Adding a Settings UI --- -## Sparkle 2 - -### Adding a Settings UI in Cocoa +## Adding a Settings UI in Cocoa These instructions below are for adding settings in a Cocoa nib and assume you have a Settings nib with its `File's Owner` being set to your Settings controller class (e.g, a `NSWindowController` subclass). The controller class should have an `updater` property set to your application's `SPUUpdater`, which may be passed from your application's delegate. -#### Enable automatic checking +### Enable automatic checking * Drag a check button from the Library to your document. * Set the title to something like "Automatically check for updates". * Select the check button, and under the Bindings tab, select Value. * Check the Bind to: check button, choose `File's Owner` from the popup, and set the Model Key Path to `updater.automaticallyChecksForUpdates`. -#### Update check interval +### Update check interval * Drag a popup button from the Library to your document. * Set the titles of the menu items to e.g. "Hourly", "Daily", "Weekly", "Monthly". @@ -26,11 +24,11 @@ These instructions below are for adding settings in a Cocoa nib and assume you h * Check the Bind to: check button, choose `File's Owner` from the popup, and set the Model Key Path to `updater.updateCheckInterval`. * Select Enabled, check the Bind to: check button, choose `File's Owner` from the popup, and set the Model Key Path to `updater.automaticallyChecksForUpdates`. -#### Other settings +### Other settings -Follow directions similar to [Enable automatic checking](#enable-automatic-checking) to bind a check button to `updater.sendsSystemProfile` or `updater.automaticallyDownloadsUpdates`. See [customization](/documentation/customization/#infoplist-settings) for details on the available keys. +Follow directions similar to [Enable automatic checking](#enable-automatic-checking) to bind a check button to `updater.automaticallyDownloadsUpdates` or `updater.sendsSystemProfile`. See [customization](/documentation/customization/#infoplist-settings) for details on the available keys. -### Adding Settings in SwiftUI +## Adding Settings in SwiftUI This is a continuation from [Creating an Updater in SwiftUI](/documentation/programmatic-setup#create-an-updater-in-swiftui). @@ -81,7 +79,7 @@ var body: some Scene { } ``` -### Adding Settings in Qt +## Adding Settings in Qt This is a continuation from [Creating an Updater in Qt](/documentation/programmatic-setup#create-an-updater-in-qt) and illustrates one way of adding updater settings. @@ -144,44 +142,6 @@ Note that [automaticallyChecksForUpdates](/documentation/api-reference/Classes/S --- -## Sparkle 1 - -These instructions below are for adding settings in a Cocoa nib and assume you have a Settings nib with its `File's Owner` being set to your Settings controller class (e.g, a `NSWindowController` subclass). The controller class should have an `updater` property set to your application's `SUUpdater`, which may be passed from your application's delegate. - -### Enable automatic checking - -* Drag a check button from the Library to your document. -* Set the title to something like "Automatically check for updates". -* Select the check button, and under the Bindings tab, select Value. -* Check the Bind to: check button, choose `File's Owner` from the popup, and set the Model Key Path to `updater.automaticallyChecksForUpdates`. - -### Update check interval - -* Drag a popup button from the Library to your document. -* Set the titles of the menu items to e.g. "Hourly", "Daily", "Weekly", "Monthly". -* Set the tags of the menu items to the corresponding times in seconds, e.g. 3600, 86400, 604800, 2629800. -* Select the popup button, and under the Bindings tab, select Selected Tag. -* Check the Bind to: check button, choose `File's Owner` from the popup, and set the Model Key Path to `updater.updateCheckInterval`. -* Select Enabled, check the Bind to: check button, choose `File's Owner` from the popup, and set the Model Key Path to `updater.automaticallyChecksForUpdates`. - -### Other settings - -Follow directions similar to [Enable automatic checking](#enable-automatic-checking). to bind a check button to `sendsSystemProfile` or `automaticallyDownloadsUpdates`. See [customization](/documentation/customization/#infoplist-settings) for details on the available keys. - -### Settings for non-app bundles - -These directions do not work for non-app bundles, as the updater you add to the nib will be the `sharedUpdater` for the application bundle. To be able to bind to the updater for your bundle, you can add the following accessor to your settings controller (the owner of the nib): - -```objc -- (SUUpdater *)updater { - return [SUUpdater updaterForBundle:[NSBundle bundleForClass:[self class]]]; -} -``` - -Then just bind the controls to the File's Owner, and start the Model Key Path with updater., e.g. updater.automaticallyChecksForUpdates. - ---- - -### Watch out for Preference Caching +## Watch out for Preference Caching macOS caches plist files in `~/Library/Preferences`, so don't edit them directly. If you want to tweak these files for testing (e.g. change last update check date), use the `defaults` command. diff --git a/documentation/programmatic-setup/index.md b/documentation/programmatic-setup/index.md index f7a4fdb..afed917 100644 --- a/documentation/programmatic-setup/index.md +++ b/documentation/programmatic-setup/index.md @@ -266,7 +266,7 @@ For adding additional updater settings, you may also want to check out [Adding S ## Core APIs -In Sparkle 2 you can also choose to instantiate and use [SPUUpdater](/documentation/api-reference/Classes/SPUUpdater.html) directly instead of the [SPUStandardUpdaterController](/documentation/api-reference/Classes/SPUStandardUpdaterController.html) wrapper if you need more control over your user interface or what bundle to update. +In Sparkle 2 you can use [SPUStandardUpdaterController](/documentation/api-reference/Classes/SPUStandardUpdaterController.html) if you are using Sparkle's standard user interface and updating your own app bundle. Otherwise, you can choose to just use the core [SPUUpdater](/documentation/api-reference/Classes/SPUUpdater.html). The updater can be accessed from `SPUStandardUpdaterController` via the [updater](https://sparkle-project.org/documentation/api-reference/Classes/SPUStandardUpdaterController.html#/c:objc(cs)SPUStandardUpdaterController(py)updater) property. If you use another UI toolkit, these are the relevant APIs in Sparkle 2 for checking for updates and handling menu item validation: @@ -274,20 +274,14 @@ If you use another UI toolkit, these are the relevant APIs in Sparkle 2 for chec * [-[SPUStandardUpdaterController checkForUpdates:]](/documentation/api-reference/Classes/SPUStandardUpdaterController.html#/c:objc(cs)SPUStandardUpdaterController(im)checkForUpdates:) or [-[SPUUpdater checkForUpdates]](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(im)checkForUpdates) for the user to check for updates * [-[SPUUpdater canCheckForUpdates]](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(py)canCheckForUpdates) for menu item validation and knowing when the user can check for updates. This property is also [KVO compliant and its value changes are observable](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOBasics.html#//apple_ref/doc/uid/20002252-BAJEAIEE). -If you are using Sparkle 1, you will need to use these APIs: - -* `+[SUUpdater sharedUpdater]` for creating and starting the updater automatically -* `-[SUUpdater checkForUpdates:]` for the user to check for updates -* `-[SUUpdater validateMenuItem:]` for menu item validation - ## API Expectations This section only applies if you plan to use additional updater APIs that are not a part of the [Core API methods](#core-apis) listed above. -Prefer to set the updater's initial properties in your bundle's Info.plist as described in [Customizing Sparkle](/documentation/customization/). This includes properties like the updater's feed URL and its update checking behavior. Only configuring the feed URL and signing keys (via `SUFeedURL` and `SUPublicEDKey`) in your bundle's Info.plist is strongly recommended, which are described in [later documentation sections](/documentation/#3-segue-for-security-concerns). +Prefer to set your updater's initial configuration in your bundle's Info.plist as described in [Customizing Sparkle](/documentation/customization/). This includes properties like the updater's feed URL and its update checking behavior. Besides configuring the feed URL and signing keys (via `SUFeedURL` and `SUPublicEDKey`), customization of settings is opt-in. -Only set [SPUUpdater](/documentation/api-reference/Classes/SPUUpdater.html) (or `SUUpdater` for Sparkle 1) properties, related to update checking, programatically when the user wants to make updater setting changes, otherwise you may be ignoring the user's preferences and resetting the updater's cycle unnecessarily. Similarly, developers shouldn't maintain their own set of user defaults on top of [SPUUpdater](/documentation/api-reference/Classes/SPUUpdater.html) (or `SUUpdater`) properties that are documented to already be backed by `NSUserDefaults` from user setting changes. Please also refer to [Adding a Settings UI](/documentation/preferences-ui) for examples. +Only set [SPUUpdater](/documentation/api-reference/Classes/SPUUpdater.html) runtime properties, related to update checking, programatically when the user wants to make updater setting changes, otherwise you may be ignoring the user's preferences and resetting the updater's cycle unnecessarily. Similarly, developers shouldn't maintain their own set of user defaults on top of [SPUUpdater](/documentation/api-reference/Classes/SPUUpdater.html) properties that are documented to already be backed by `NSUserDefaults` from user setting changes. Please also refer to [Adding a Settings UI](/documentation/preferences-ui) for examples. -If you want to switch to an alternative feed at runtime, please check our section on [setting the feed programmatically](/documentation/publishing#setting-the-feed-programmatically) first on the recommended API usage (which is not through `-setFeedURL:`). +Avoid forcing a manual call to [-[SPUUpdater checkForUpdatesInBackground]](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(im)checkForUpdatesInBackground). By default, Sparkle calls this method automatically for you on a scheduled basis (the default is once every 24 hours). If you want to additionally force an update check on every app launch though, only call this method immediately after the updater is started, and only call this method if the user hasn't disabled automatic checking of updates by ensuring [-[SPUUpdater automaticallyChecksForUpdates]](api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(py)automaticallyChecksForUpdates) reads as `YES`. Invoking `checkForUpdatesInBackground` manually at later points can interfere with Sparkle's update scheduler in unexpected ways. -Avoid forcing a manual [-checkForUpdatesInBackground](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(im)checkForUpdatesInBackground) unless your application requires this check at specific points of time. If used incorrectly, this can interfere with Sparkle's default behavior for asking the user's permission to check for updates automatically, and for Sparkle calling this method periodically without probing too often. If you do require a manual background update check, either ensure [-automaticallyChecksForUpdates](api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(py)automaticallyChecksForUpdates) is already `YES` (but don't set the property yourself in this context) or set `SUEnableAutomaticChecks` Info.plist key described in [Customizing Sparkle](/documentation/customization/) to explicitly opt out of asking the user permission to check for updates automatically. Finally, note that by default a new update that is found from a background check is not guaranteed to be shown to the user immediately (due to poor connectivity, downloading/installing an update silently in the background, or waiting until a more opportune time to alert the user). As of Sparkle 2.4 or later, if you want to trigger a background update check after the user has changed the allowed channels or feed, use [-[SPUUpdater resetUpdateCycleAfterShortDelay]](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(im)resetUpdateCycleAfterShortDelay) or [-[SPUUpdater resetUpdateCycle]](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(im)resetUpdateCycle) instead. +If you want to trigger a background update check after the user has changed the allowed channels or feed in your app's settings, use [-[SPUUpdater resetUpdateCycleAfterShortDelay]](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(im)resetUpdateCycleAfterShortDelay) or [-[SPUUpdater resetUpdateCycle]](/documentation/api-reference/Classes/SPUUpdater.html#/c:objc(cs)SPUUpdater(im)resetUpdateCycle). diff --git a/documentation/publishing/index.md b/documentation/publishing/index.md index 81cc5c8..0f7b392 100644 --- a/documentation/publishing/index.md +++ b/documentation/publishing/index.md @@ -333,7 +333,7 @@ The appcast feed URL can be changed programmatically at runtime. If the feed URL If you want to set the feed programmatically to provide beta/nightly updates, please try to adopt [channels](#channels) in the future instead. -The recommended way to change the feed URL programmatically is using `-[SUUpdaterDelegate feedURLStringForUpdater:]` or [-[SPUUpdaterDelegate feedURLStringForUpdater:]](/documentation/api-reference/Protocols/SPUUpdaterDelegate.html#/c:objc(pl)SPUUpdaterDelegate(im)feedURLStringForUpdater:) in Sparkle 2. +The recommended way to change the feed URL programmatically is using [-[SPUUpdaterDelegate feedURLStringForUpdater:]](/documentation/api-reference/Protocols/SPUUpdaterDelegate.html#/c:objc(pl)SPUUpdaterDelegate(im)feedURLStringForUpdater:). Here is an example: