macOS: Add support for Sparkle 2.

Sparkle 2 deprecated the sharedUpdater singleton, so create our own
which uses Sparkle 2's updated API. Ping #18035.

Update our CMake version check.
This commit is contained in:
Gerald Combs 2022-04-09 14:14:04 -07:00
parent c8d9c6fc6a
commit fea6591b0c
4 changed files with 54 additions and 14 deletions

View File

@ -67,8 +67,8 @@ indent_size = 4
indent_style = tab indent_style = tab
indent_size = 8 indent_size = 8
# C/C++ # C/C++/Objective C
[*.{c,cpp,h}] [*.{c,cpp,h,m}]
indent_style = space indent_style = space
indent_size = 4 indent_size = 4

View File

@ -1245,7 +1245,7 @@ if(BUILD_wireshark OR BUILD_logwolf)
endif() endif()
set(QT_FOUND ON) set(QT_FOUND ON)
if(APPLE) if(APPLE)
ws_find_package(Sparkle ENABLE_SPARKLE HAVE_SOFTWARE_UPDATE 1 EXACT) ws_find_package(Sparkle ENABLE_SPARKLE HAVE_SOFTWARE_UPDATE 1)
endif() endif()
if(Qt${qtver}Multimedia_FOUND) if(Qt${qtver}Multimedia_FOUND)
set(QT_MULTIMEDIA_LIB 1) set(QT_MULTIMEDIA_LIB 1)

View File

@ -19,19 +19,18 @@ find_library(SPARKLE_LIBRARY NAMES Sparkle
HINTS ${USR_LOCAL_HINT} ${HOMEBREW_HINT} HINTS ${USR_LOCAL_HINT} ${HOMEBREW_HINT}
) )
# https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html # Sparkle doesn't appear to provide a version macro, and its Info.plist versions
find_file(_info_plist Info.plist # are all over the place. Check for SPUStandardUpdaterController.h, which was
${SPARKLE_LIBRARY}/Resources # added in version 2.
${SPARKLE_LIBRARY}/Versions/Current/Resources set(SPARKLE_VERSION 1)
${SPARKLE_LIBRARY}/Versions/A/Resources
find_file(_spustandardupdatercontroller_h SPUStandardUpdaterController.h
${SPARKLE_LIBRARY}/Headers
NO_DEFAULT_PATH NO_DEFAULT_PATH
) )
if(_info_plist) if(_spustandardupdatercontroller_h)
execute_process(COMMAND defaults read ${_info_plist} CFBundleVersion set(SPARKLE_VERSION 2)
OUTPUT_VARIABLE SPARKLE_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif() endif()
find_package_handle_standard_args(Sparkle find_package_handle_standard_args(Sparkle

View File

@ -15,19 +15,60 @@
#import <Sparkle.h> #import <Sparkle.h>
// XXX Is there a more reliable way to do this?
#ifdef SPUUserUpdateState_h
#define HAVE_SPARKLE_2
#endif
// https://sparkle-project.org/documentation/customization/ // https://sparkle-project.org/documentation/customization/
// Sparkle stores its state in ~/Library/Preferences/org.wireshark.Wireshark.plist // Sparkle stores its state in ~/Library/Preferences/org.wireshark.Wireshark.plist.
// You can check its log output via `log stream | grep -i sparkle`.
#ifdef HAVE_SPARKLE_2
// The Sparkle 1 UI provided a sharedUpdater singleton, which is deprecated
// in Sparkle 2:
// https://sparkle-project.org/documentation/upgrading/
// Create our own singleton which uses the updated API.
// https://sparkle-project.org/documentation/programmatic-setup/
@interface SparkleBridge : NSObject
+ (SPUStandardUpdaterController *)sharedStandardUpdaterController;
@end
@implementation SparkleBridge
+ (SPUStandardUpdaterController *)sharedStandardUpdaterController {
static SPUStandardUpdaterController *sharedStandardUpdaterController_ = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedStandardUpdaterController_ = [[SPUStandardUpdaterController alloc] initWithUpdaterDelegate: nil userDriverDelegate: nil];
});
return sharedStandardUpdaterController_;
}
@end
#endif
void sparkle_software_update_init(const char *url, bool enabled, int interval) void sparkle_software_update_init(const char *url, bool enabled, int interval)
{ {
#ifdef HAVE_SPARKLE_2
[[[SparkleBridge sharedStandardUpdaterController] updater] setAutomaticallyChecksForUpdates: enabled];
[[[SparkleBridge sharedStandardUpdaterController] updater] setUpdateCheckInterval: interval];
[[[SparkleBridge sharedStandardUpdaterController] updater] setFeedURL: [NSURL URLWithString: [[NSString alloc] initWithUTF8String: url] ]];
#else
[[SUUpdater sharedUpdater] setAutomaticallyChecksForUpdates: enabled]; [[SUUpdater sharedUpdater] setAutomaticallyChecksForUpdates: enabled];
[[SUUpdater sharedUpdater] setUpdateCheckInterval: interval]; [[SUUpdater sharedUpdater] setUpdateCheckInterval: interval];
[[SUUpdater sharedUpdater] setFeedURL: [NSURL URLWithString: [[NSString alloc] initWithUTF8String: url] ]]; [[SUUpdater sharedUpdater] setFeedURL: [NSURL URLWithString: [[NSString alloc] initWithUTF8String: url] ]];
#endif
} }
void sparkle_software_update_check(void) void sparkle_software_update_check(void)
{ {
#ifdef HAVE_SPARKLE_2
[[SparkleBridge sharedStandardUpdaterController] checkForUpdates: [[NSApplication sharedApplication] delegate]];
#else
[[SUUpdater sharedUpdater] checkForUpdates: [[NSApplication sharedApplication] delegate]]; [[SUUpdater sharedUpdater] checkForUpdates: [[NSApplication sharedApplication] delegate]];
#endif
} }
// Sparkle requires NSApplicationWillTerminateNotification in order to // Sparkle requires NSApplicationWillTerminateNotification in order to