summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2016-09-22 15:07:33 (GMT)
committerKevin Smith <kevin.smith@isode.com>2016-09-26 22:04:24 (GMT)
commit05fbe78f5c3b30517f7152b37c157a99120682dc (patch)
tree865ffa3fdcf73d8044c3478ef8e52b159c3fc738 /SwifTools
parent82d4ca00958d6d097aee830ac300ecfd9014d2b3 (diff)
downloadswift-05fbe78f5c3b30517f7152b37c157a99120682dc.zip
swift-05fbe78f5c3b30517f7152b37c157a99120682dc.tar.bz2
Update and tidy up Sparkle software update support
Sparkle is configured to do silent automatic background updates based on the provide appcast feed. When a new update was downloaded and is ready to be installed Swift notifies the user that they can restart to take advantage of the newly available version. Test-Information: Setup a custom appcast feed with a newer Swift dev release. Tested updating with Sparkle 1.14.0 binary release using DSA keys and signatures. Did not test Sparkle update with code signed Swift builds. Tested on macOS 10.12. Change-Id: Idad461ec53963c80990e51a502cb6e28bc7b6b4e
Diffstat (limited to 'SwifTools')
-rw-r--r--SwifTools/AutoUpdater/AutoUpdater.h13
-rw-r--r--SwifTools/AutoUpdater/SparkleAutoUpdater.h7
-rw-r--r--SwifTools/AutoUpdater/SparkleAutoUpdater.mm31
-rw-r--r--SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h35
-rw-r--r--SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.mm57
-rw-r--r--SwifTools/SConscript2
6 files changed, 141 insertions, 4 deletions
diff --git a/SwifTools/AutoUpdater/AutoUpdater.h b/SwifTools/AutoUpdater/AutoUpdater.h
index dec85c9..ed53e11 100644
--- a/SwifTools/AutoUpdater/AutoUpdater.h
+++ b/SwifTools/AutoUpdater/AutoUpdater.h
@@ -1,16 +1,27 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <boost/signals2.hpp>
+
namespace Swift {
class AutoUpdater {
public:
virtual ~AutoUpdater();
virtual void checkForUpdates() = 0;
+ virtual bool recommendRestartToUpdate() = 0;
+
+ public:
+ /**
+ * Emit this signal if a new version of the software has been downloaded
+ * and the user needs to be notified so they can quit the app and start
+ * the newer version.
+ */
+ boost::signals2::signal<void()> onSuggestRestartToUserToUpdate;
};
}
diff --git a/SwifTools/AutoUpdater/SparkleAutoUpdater.h b/SwifTools/AutoUpdater/SparkleAutoUpdater.h
index 95ca35e..c3394f7 100644
--- a/SwifTools/AutoUpdater/SparkleAutoUpdater.h
+++ b/SwifTools/AutoUpdater/SparkleAutoUpdater.h
@@ -11,12 +11,19 @@
#include <SwifTools/AutoUpdater/AutoUpdater.h>
namespace Swift {
+ /**
+ * @brief The SparkleAutoUpdater class provides integration with Sparkle.
+ * This enables automatic silent background updates. If using this in Qt you
+ * need to emit a NSApplicationWillTerminateNotification before you quit
+ * the application.
+ */
class SparkleAutoUpdater : public AutoUpdater {
public:
SparkleAutoUpdater(const std::string& url);
~SparkleAutoUpdater();
void checkForUpdates();
+ bool recommendRestartToUpdate();
private:
class Private;
diff --git a/SwifTools/AutoUpdater/SparkleAutoUpdater.mm b/SwifTools/AutoUpdater/SparkleAutoUpdater.mm
index bcd1388..7e06b2f 100644
--- a/SwifTools/AutoUpdater/SparkleAutoUpdater.mm
+++ b/SwifTools/AutoUpdater/SparkleAutoUpdater.mm
@@ -1,13 +1,24 @@
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#include <SwifTools/AutoUpdater/SparkleAutoUpdater.h>
#include <Cocoa/Cocoa.h>
#include <Sparkle/Sparkle.h>
+#include <SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h>
+#include <SwifTools/Cocoa/CocoaUtil.h>
+
namespace Swift {
class SparkleAutoUpdater::Private {
public:
SUUpdater* updater;
+ boost::intrusive_ptr<SparkleAutoUpdaterDelegate> delegate;
+ bool restartToUpdate = false;
};
SparkleAutoUpdater::SparkleAutoUpdater(const std::string& url) {
@@ -15,20 +26,36 @@ SparkleAutoUpdater::SparkleAutoUpdater(const std::string& url) {
d->updater = [SUUpdater sharedUpdater];
[d->updater retain];
+
+ d->delegate = boost::intrusive_ptr<SparkleAutoUpdaterDelegate>([[SparkleAutoUpdaterDelegate alloc] init], false);
+ [d->delegate.get() setUpdateDownloadFinished: [&](){
+ d->restartToUpdate = true;
+ onSuggestRestartToUserToUpdate();
+ }];
+ [d->updater setDelegate: d->delegate.get()];
+
[d->updater setAutomaticallyChecksForUpdates: true];
+ // Automatically check for an update after a day.
+ [d->updater setUpdateCheckInterval: 86400];
+ [d->updater setAutomaticallyDownloadsUpdates: true];
- NSURL* nsurl = [NSURL URLWithString:
- [NSString stringWithUTF8String: url.c_str()]];
+ NSURL* nsurl = [NSURL URLWithString: std2NSString(url)];
[d->updater setFeedURL: nsurl];
}
SparkleAutoUpdater::~SparkleAutoUpdater() {
[d->updater release];
delete d;
+ SWIFT_LOG(warning) << std::endl;
}
void SparkleAutoUpdater::checkForUpdates() {
+ //[d->updater resetUpdateCycle]; // This is useful for testing to force a check ot start.
[d->updater checkForUpdatesInBackground];
}
+bool SparkleAutoUpdater::recommendRestartToUpdate() {
+ return d->restartToUpdate;
+}
+
}
diff --git a/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h b/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h
new file mode 100644
index 0000000..8f408de
--- /dev/null
+++ b/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <functional>
+
+#import <Cocoa/Cocoa.h>
+
+#import <Sparkle/Sparkle.h>
+
+namespace Swift {
+ class SparkleAutoUpdater;
+}
+
+@interface SparkleAutoUpdaterDelegate : NSObject<SUUpdaterDelegate>
+@property (atomic) std::function< void ()> updateDownloadFinished;
+
+- (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast;
+
+- (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update;
+
+- (id <SUVersionComparison>)versionComparatorForUpdater:(SUUpdater *)updater;
+
+- (void)updaterDidNotFindUpdate:(SUUpdater *)update;
+
+- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update;
+
+- (void)updater:(SUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationInvocation:(NSInvocation *)invocation;
+
+- (void)updater:(SUUpdater *)updater didAbortWithError:(NSError *)error;
+@end
diff --git a/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.mm b/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.mm
new file mode 100644
index 0000000..6e832ba
--- /dev/null
+++ b/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.mm
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#import "SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h"
+
+#include <string>
+
+#include <Swiften/Base/Log.h>
+
+#include <SwifTools/Cocoa/CocoaUtil.h>
+
+using namespace Swift;
+
+@implementation SparkleAutoUpdaterDelegate
+
+@synthesize updateDownloadFinished;
+
+- (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast {
+ (void)updater;
+ (void)appcast;
+}
+
+- (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update {
+ (void)updater;
+ (void)update;
+}
+
+- (id <SUVersionComparison>)versionComparatorForUpdater:(SUUpdater *)updater {
+ (void)updater;
+ return nil;
+}
+
+- (void)updaterDidNotFindUpdate:(SUUpdater *)updater {
+ (void)updater;
+}
+
+- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update {
+ (void)updater;
+ (void)update;
+}
+
+- (void)updater:(SUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationInvocation:(NSInvocation *)invocation {
+ (void)updater;
+ (void)item;
+ (void)invocation;
+ updateDownloadFinished();
+}
+
+- (void)updater:(SUUpdater *)updater didAbortWithError:(NSError *)error {
+ (void)updater;
+ SWIFT_LOG(error) << ns2StdString([error localizedDescription]) << std::endl;
+}
+
+@end
diff --git a/SwifTools/SConscript b/SwifTools/SConscript
index aa6d47e..dec343e 100644
--- a/SwifTools/SConscript
+++ b/SwifTools/SConscript
@@ -50,7 +50,7 @@ if env["SCONS_STAGE"] == "build" :
if swiftools_env.get("HAVE_SPARKLE", 0) :
swiftools_env.UseFlags(swiftools_env["SPARKLE_FLAGS"])
swiftools_env.Append(CPPDEFINES = ["HAVE_SPARKLE"])
- sources += ["AutoUpdater/SparkleAutoUpdater.mm"]
+ sources += ["AutoUpdater/SparkleAutoUpdater.mm", "AutoUpdater/SparkleAutoUpdaterDelegate.mm"]
if swiftools_env["PLATFORM"] == "win32" :
sources += ["Idle/WindowsIdleQuerier.cpp"]