1
by andym
Holy restructuring, batman! Watch out for falling folders. |
1 |
//
|
2 |
// SUUpdater.m
|
|
3 |
// Sparkle
|
|
4 |
//
|
|
5 |
// Created by Andy Matuschak on 1/4/06.
|
|
6 |
// Copyright 2006 Andy Matuschak. All rights reserved.
|
|
7 |
//
|
|
8 |
||
9 |
#import "SUUpdater.h"
|
|
59
by andym
Improved headers from Charles D. H. Williams. |
10 |
|
242.1.12
by Andy Matuschak
Fixes 243884 |
11 |
#import "SUHost.h"
|
12 |
#import "SUUpdatePermissionPrompt.h"
|
|
13 |
||
14 |
#import "SUAutomaticUpdateDriver.h"
|
|
15 |
#import "SUProbingUpdateDriver.h"
|
|
16 |
#import "SUUserInitiatedUpdateDriver.h"
|
|
17 |
#import "SUScheduledUpdateDriver.h"
|
|
18 |
||
1
by andym
Holy restructuring, batman! Watch out for falling folders. |
19 |
@interface SUUpdater (Private) |
264
by Andy Matuschak
Fixes 253145 |
20 |
- initForBundle:(NSBundle *)bundle; |
326
by Andy Matuschak
Fixes Bug #312381: "Bundles can't ask for permission to update; developers have to hard-code YES for SUEnableAutomaticChecks" |
21 |
- (void)startUpdateCycle; |
242.1.12
by Andy Matuschak
Fixes 243884 |
22 |
- (void)checkForUpdatesWithDriver:(SUUpdateDriver *)updateDriver; |
286
by Andy Matuschak
Fixes 258547 |
23 |
- (BOOL)automaticallyDownloadsUpdates; |
197
by Andy Matuschak
Fixed 236240 |
24 |
- (void)scheduleNextUpdateCheck; |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
25 |
- (void)registerAsObserver; |
26 |
- (void)unregisterAsObserver; |
|
27 |
- (void)updateDriverDidFinish:(NSNotification *)note; |
|
28 |
- initForBundle:(NSBundle *)bundle; |
|
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
29 |
- (NSURL *)parameterizedFeedURL; |
1
by andym
Holy restructuring, batman! Watch out for falling folders. |
30 |
@end
|
31 |
||
32 |
@implementation SUUpdater |
|
33 |
||
46
by andym
Reorganized SUUpdater.m; it's in better order now. |
34 |
#pragma mark Initialization
|
35 |
||
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
36 |
static NSMutableDictionary *sharedUpdaters = nil; |
37 |
static NSString *SUUpdaterDefaultsObservationContext = @"SUUpdaterDefaultsObservationContext"; |
|
81
by andym
Made a number of fixes to potentially dangerous singleton behavior as suggested by Christiaan Hofman. |
38 |
|
46
by andym
Reorganized SUUpdater.m; it's in better order now. |
39 |
+ (SUUpdater *)sharedUpdater |
40 |
{
|
|
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
41 |
return [self updaterForBundle:[NSBundle mainBundle]]; |
42 |
}
|
|
43 |
||
44 |
// SUUpdater has a singleton for each bundle. We use the fact that NSBundle instances are also singletons, so we can use them as keys. If you don't trust that you can also use the identifier as key
|
|
45 |
+ (SUUpdater *)updaterForBundle:(NSBundle *)bundle |
|
46 |
{
|
|
47 |
if (bundle == nil) bundle = [NSBundle mainBundle]; |
|
48 |
id updater = [sharedUpdaters objectForKey:[NSValue valueWithNonretainedObject:bundle]]; |
|
49 |
if (updater == nil) |
|
264
by Andy Matuschak
Fixes 253145 |
50 |
updater = [[[self class] alloc] initForBundle:bundle]; |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
51 |
return updater; |
52 |
}
|
|
53 |
||
54 |
// This is the designated initializer for SUUpdater, important for subclasses
|
|
55 |
- initForBundle:(NSBundle *)bundle |
|
1
by andym
Holy restructuring, batman! Watch out for falling folders. |
56 |
{
|
82
by andym
Oops! Committed the last patch with broken code; this code works. |
57 |
self = [super init]; |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
58 |
if (bundle == nil) bundle = [NSBundle mainBundle]; |
59 |
id updater = [sharedUpdaters objectForKey:[NSValue valueWithNonretainedObject:bundle]]; |
|
60 |
if (updater) |
|
83
by andym
Finished cleaning up singleton stuff in SUUpdater.m |
61 |
{
|
62 |
[self release]; |
|
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
63 |
self = [updater retain]; |
83
by andym
Finished cleaning up singleton stuff in SUUpdater.m |
64 |
}
|
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
65 |
else if (self) |
83
by andym
Finished cleaning up singleton stuff in SUUpdater.m |
66 |
{
|
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
67 |
if (sharedUpdaters == nil) |
68 |
sharedUpdaters = [[NSMutableDictionary alloc] init]; |
|
69 |
[sharedUpdaters setObject:self forKey:[NSValue valueWithNonretainedObject:bundle]]; |
|
70 |
host = [[SUHost alloc] initWithBundle:bundle]; |
|
71 |
[self registerAsObserver]; |
|
326
by Andy Matuschak
Fixes Bug #312381: "Bundles can't ask for permission to update; developers have to hard-code YES for SUEnableAutomaticChecks" |
72 |
// This runs the permission prompt if needed, but never before the app has finished launching because the runloop won't run before that
|
73 |
[self performSelector:@selector(startUpdateCycle) withObject:nil afterDelay:0]; |
|
62
by andym
Fixed warnings for missing newlines at the end of the file. |
74 |
}
|
43
by andym
Beware of falling bricks! Huge refactoring commit #1: cleansing Sparkle of the plague that was SUUtilities. |
75 |
return self; |
1
by andym
Holy restructuring, batman! Watch out for falling folders. |
76 |
}
|
77 |
||
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
78 |
// This will be used when the updater is instantiated in a nib such as MainMenu
|
79 |
- (id)init |
|
80 |
{
|
|
81 |
return [self initForBundle:[NSBundle mainBundle]]; |
|
82 |
}
|
|
83 |
||
294
by Andy Matuschak
Partial fix for 245277: basic descriptions for some Sparkle classes. Thanks to Christiaan Hofman for the patch. |
84 |
- (NSString *)description { return [NSString stringWithFormat:@"%@ <%@>", [self class], [host bundlePath]]; } |
85 |
||
326
by Andy Matuschak
Fixes Bug #312381: "Bundles can't ask for permission to update; developers have to hard-code YES for SUEnableAutomaticChecks" |
86 |
- (void)startUpdateCycle |
1
by andym
Holy restructuring, batman! Watch out for falling folders. |
87 |
{
|
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
88 |
BOOL shouldPrompt = NO; |
89 |
||
90 |
// If the user has been asked about automatic checks, don't bother prompting
|
|
91 |
if ([host objectForUserDefaultsKey:SUEnableAutomaticChecksKey]) |
|
92 |
{
|
|
93 |
shouldPrompt = NO; |
|
94 |
}
|
|
95 |
// Does the delegate want to take care of the logic for when we should ask permission to update?
|
|
242.1.4
by Andy Matuschak
Fixes 244857 |
96 |
else if ([delegate respondsToSelector:@selector(updaterShouldPromptForPermissionToCheckForUpdates:)]) |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
97 |
{
|
242.1.4
by Andy Matuschak
Fixes 244857 |
98 |
shouldPrompt = [delegate updaterShouldPromptForPermissionToCheckForUpdates:self]; |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
99 |
}
|
100 |
// Has he been asked already? And don't ask if the host has a default value set in its Info.plist.
|
|
285
by Andy Matuschak
Fixes 245723 |
101 |
else if ([host objectForKey:SUEnableAutomaticChecksKey] == nil) |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
102 |
{
|
103 |
if ([host objectForUserDefaultsKey:SUEnableAutomaticChecksKeyOld]) |
|
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
104 |
[self setAutomaticallyChecksForUpdates:[host boolForUserDefaultsKey:SUEnableAutomaticChecksKeyOld]]; |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
105 |
// Now, we don't want to ask the user for permission to do a weird thing on the first launch.
|
106 |
// We wait until the second launch.
|
|
107 |
else if ([host boolForUserDefaultsKey:SUHasLaunchedBeforeKey] == NO) |
|
108 |
[host setBool:YES forUserDefaultsKey:SUHasLaunchedBeforeKey]; |
|
109 |
else
|
|
110 |
shouldPrompt = YES; |
|
111 |
}
|
|
112 |
||
113 |
if (shouldPrompt) |
|
114 |
{
|
|
282
by Andy Matuschak
Fixes 251968 |
115 |
NSArray *profileInfo = [host systemProfile]; |
116 |
if ([delegate respondsToSelector:@selector(feedParametersForUpdater:sendingSystemProfile:)]) |
|
286
by Andy Matuschak
Fixes 258547 |
117 |
profileInfo = [profileInfo arrayByAddingObjectsFromArray:[delegate feedParametersForUpdater:self sendingSystemProfile:[self sendsSystemProfile]]]; |
282
by Andy Matuschak
Fixes 251968 |
118 |
[SUUpdatePermissionPrompt promptWithHost:host systemProfile:profileInfo delegate:self]; |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
119 |
// We start the update checks and register as observer for changes after the prompt finishes
|
44
by andym
Substantial changes made to how Sparkle works on startup now. SUCheckAtStartup is dead, as are checks on startup. Now Sparkle asks if it can check for updates automatically and does so according to the scheduled check interval, which defaults to a day. Additionally -- THIS IS IMPORTANT -- Sparkle won't prompt the user on the first launch. It waits until the second to improve the first-use experience. |
120 |
}
|
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
121 |
else
|
122 |
{
|
|
123 |
// We check if the user's said they want updates, or they haven't said anything, and the default is set to checking.
|
|
124 |
[self scheduleNextUpdateCheck]; |
|
125 |
}
|
|
90
by andym
Finished integrating SparklePlus profiling! Just set SUEnableSystemProfiling to YES in your info.plist. The Test App has this on by default so you all can see. |
126 |
}
|
127 |
||
128 |
- (void)updatePermissionPromptFinishedWithResult:(SUPermissionPromptResult)result |
|
129 |
{
|
|
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
130 |
[self setAutomaticallyChecksForUpdates:(result == SUAutomaticallyCheck)]; |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
131 |
// Schedule checks, but make sure we ignore the delayed call from KVO
|
242.1.8
by Andy Matuschak
Fixes 245991 |
132 |
[self resetUpdateCycle]; |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
133 |
}
|
134 |
||
135 |
- (void)updateDriverDidFinish:(NSNotification *)note |
|
136 |
{
|
|
137 |
if ([note object] == driver && [driver finished]) |
|
138 |
{
|
|
139 |
[driver release]; driver = nil; |
|
140 |
[self scheduleNextUpdateCheck]; |
|
141 |
}
|
|
90
by andym
Finished integrating SparklePlus profiling! Just set SUEnableSystemProfiling to YES in your info.plist. The Test App has this on by default so you all can see. |
142 |
}
|
143 |
||
295
by Andy Matuschak
Fixes 259062 |
144 |
- (NSDate *)lastUpdateCheckDate |
291.1.1
by Peter Speck
Provide getter for SULastCheckTimeKey |
145 |
{
|
146 |
return [host objectForUserDefaultsKey:SULastCheckTimeKey]; |
|
147 |
}
|
|
148 |
||
197
by Andy Matuschak
Fixed 236240 |
149 |
- (void)scheduleNextUpdateCheck |
145
by Andy Matuschak
Removed the checkInterval IV and factored out its assignment to a checkInterval method in SUUpdater. Now when future updates are scheduled after an initial one exits, they'll use the current interval. |
150 |
{
|
215
by Andy Matuschak
Removed unnecessary @synchronized's. |
151 |
if (checkTimer) |
197
by Andy Matuschak
Fixed 236240 |
152 |
{
|
215
by Andy Matuschak
Removed unnecessary @synchronized's. |
153 |
[checkTimer invalidate]; |
154 |
checkTimer = nil; |
|
197
by Andy Matuschak
Fixed 236240 |
155 |
}
|
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
156 |
if (![self automaticallyChecksForUpdates]) return; |
197
by Andy Matuschak
Fixed 236240 |
157 |
|
90
by andym
Finished integrating SparklePlus profiling! Just set SUEnableSystemProfiling to YES in your info.plist. The Test App has this on by default so you all can see. |
158 |
// How long has it been since last we checked for an update?
|
291.1.1
by Peter Speck
Provide getter for SULastCheckTimeKey |
159 |
NSDate *lastCheckDate = [self lastUpdateCheckDate]; |
90
by andym
Finished integrating SparklePlus profiling! Just set SUEnableSystemProfiling to YES in your info.plist. The Test App has this on by default so you all can see. |
160 |
if (!lastCheckDate) { lastCheckDate = [NSDate distantPast]; } |
161 |
NSTimeInterval intervalSinceCheck = [[NSDate date] timeIntervalSinceDate:lastCheckDate]; |
|
162 |
||
163 |
// Now we want to figure out how long until we check again.
|
|
287
by Andy Matuschak
Fixes 258529 and 257967 |
164 |
NSTimeInterval delayUntilCheck, updateCheckInterval = [self updateCheckInterval]; |
165 |
if (updateCheckInterval < SU_MIN_CHECK_INTERVAL) |
|
166 |
updateCheckInterval = SU_MIN_CHECK_INTERVAL; |
|
167 |
if (intervalSinceCheck < updateCheckInterval) |
|
168 |
delayUntilCheck = (updateCheckInterval - intervalSinceCheck); // It hasn't been long enough. |
|
90
by andym
Finished integrating SparklePlus profiling! Just set SUEnableSystemProfiling to YES in your info.plist. The Test App has this on by default so you all can see. |
169 |
else
|
170 |
delayUntilCheck = 0; // We're overdue! Run one now. |
|
116
by andym
Touched practically every line of code in a super-monster-awesome refactoring. Please read: |
171 |
checkTimer = [NSTimer scheduledTimerWithTimeInterval:delayUntilCheck target:self selector:@selector(checkForUpdatesInBackground) userInfo:nil repeats:NO]; |
1
by andym
Holy restructuring, batman! Watch out for falling folders. |
172 |
}
|
173 |
||
174 |
- (void)checkForUpdatesInBackground |
|
175 |
{
|
|
286
by Andy Matuschak
Fixes 258547 |
176 |
[self checkForUpdatesWithDriver:[[[([self automaticallyDownloadsUpdates] ? [SUAutomaticUpdateDriver class] : [SUScheduledUpdateDriver class]) alloc] initWithUpdater:self] autorelease]]; |
1
by andym
Holy restructuring, batman! Watch out for falling folders. |
177 |
}
|
178 |
||
179 |
- (IBAction)checkForUpdates:sender |
|
180 |
{
|
|
281
by Andy Matuschak
No longer fragile-ly using class method singletons to get to the updater's delegate from within the update driver. Update drivers now have an initWithUpdater: method which I use instead. |
181 |
[self checkForUpdatesWithDriver:[[[SUUserInitiatedUpdateDriver alloc] initWithUpdater:self] autorelease]]; |
116
by andym
Touched practically every line of code in a super-monster-awesome refactoring. Please read: |
182 |
}
|
183 |
||
242.1.12
by Andy Matuschak
Fixes 243884 |
184 |
- (void)checkForUpdateInformation |
185 |
{
|
|
281
by Andy Matuschak
No longer fragile-ly using class method singletons to get to the updater's delegate from within the update driver. Update drivers now have an initWithUpdater: method which I use instead. |
186 |
[self checkForUpdatesWithDriver:[[[SUProbingUpdateDriver alloc] initWithUpdater:self] autorelease]]; |
242.1.12
by Andy Matuschak
Fixes 243884 |
187 |
}
|
188 |
||
116
by andym
Touched practically every line of code in a super-monster-awesome refactoring. Please read: |
189 |
- (void)checkForUpdatesWithDriver:(SUUpdateDriver *)d |
190 |
{
|
|
191 |
if ([self updateInProgress]) { return; } |
|
215
by Andy Matuschak
Removed unnecessary @synchronized's. |
192 |
if (checkTimer) { [checkTimer invalidate]; checkTimer = nil; } |
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
193 |
|
295
by Andy Matuschak
Fixes 259062 |
194 |
[self willChangeValueForKey:@"lastUpdateCheckDate"]; |
195 |
[host setObject:[NSDate date] forUserDefaultsKey:SULastCheckTimeKey]; |
|
196 |
[self didChangeValueForKey:@"lastUpdateCheckDate"]; |
|
197 |
||
116
by andym
Touched practically every line of code in a super-monster-awesome refactoring. Please read: |
198 |
driver = [d retain]; |
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
199 |
[driver checkForUpdatesAtURL:[self parameterizedFeedURL] host:host]; |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
200 |
}
|
201 |
||
202 |
- (void)registerAsObserver |
|
203 |
{
|
|
204 |
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateDriverDidFinish:) name:SUUpdateDriverFinishedNotification object:nil]; |
|
205 |
// No sense observing the shared NSUserDefaultsController when we're not updating the main bundle.
|
|
206 |
if ([host bundle] != [NSBundle mainBundle]) return; |
|
207 |
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:[@"values." stringByAppendingString:SUScheduledCheckIntervalKey] options:0 context:SUUpdaterDefaultsObservationContext]; |
|
208 |
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:[@"values." stringByAppendingString:SUEnableAutomaticChecksKey] options:0 context:SUUpdaterDefaultsObservationContext]; |
|
209 |
}
|
|
210 |
||
211 |
- (void)unregisterAsObserver |
|
212 |
{
|
|
213 |
[[NSNotificationCenter defaultCenter] removeObserver:self]; |
|
214 |
// Removing self as a KVO observer if no observer was registered leads to an NSException. But we don't care.
|
|
215 |
@try
|
|
216 |
{
|
|
217 |
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:[@"values." stringByAppendingString:SUScheduledCheckIntervalKey]]; |
|
218 |
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:[@"values." stringByAppendingString:SUEnableAutomaticChecksKey]]; |
|
219 |
}
|
|
220 |
@catch (NSException *e) { } |
|
116
by andym
Touched practically every line of code in a super-monster-awesome refactoring. Please read: |
221 |
}
|
222 |
||
223 |
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context |
|
224 |
{
|
|
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
225 |
if (context == SUUpdaterDefaultsObservationContext) |
226 |
{
|
|
227 |
// Allow a small delay, because perhaps the user or developer wants to change both preferences. This allows the developer to interpret a zero check interval as a sign to disable automatic checking.
|
|
228 |
// Or we may get this from the developer and from our own KVO observation, this will effectively coalesce them.
|
|
242.1.8
by Andy Matuschak
Fixes 245991 |
229 |
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetUpdateCycle) object:nil]; |
277
by Andy Matuschak
Fixes 255399 |
230 |
[self performSelector:@selector(resetUpdateCycle) withObject:nil afterDelay:1]; |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
231 |
}
|
232 |
else
|
|
233 |
{
|
|
234 |
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; |
|
235 |
}
|
|
197
by Andy Matuschak
Fixed 236240 |
236 |
}
|
237 |
||
242.1.8
by Andy Matuschak
Fixes 245991 |
238 |
- (void)resetUpdateCycle |
197
by Andy Matuschak
Fixed 236240 |
239 |
{
|
242.1.8
by Andy Matuschak
Fixes 245991 |
240 |
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetUpdateCycle) object:nil]; |
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
241 |
[self scheduleNextUpdateCheck]; |
21
by catlan
#77 SUIgnoreChecks to ignore update, needed for Sparkle in large deployments |
242 |
}
|
243 |
||
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
244 |
- (void)setAutomaticallyChecksForUpdates:(BOOL)automaticallyCheckForUpdates |
245 |
{
|
|
246 |
[host setBool:automaticallyCheckForUpdates forUserDefaultsKey:SUEnableAutomaticChecksKey]; |
|
287
by Andy Matuschak
Fixes 258529 and 257967 |
247 |
// Hack to support backwards compatibility with older Sparkle versions, which supported
|
248 |
// disabling updates by setting the check interval to 0.
|
|
249 |
if (automaticallyCheckForUpdates && [self updateCheckInterval] == 0) |
|
250 |
[self setUpdateCheckInterval:SU_DEFAULT_CHECK_INTERVAL]; |
|
251 |
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetUpdateCycle) object:nil]; |
|
252 |
// Provide a small delay in case multiple preferences are being updated simultaneously.
|
|
253 |
[self performSelector:@selector(resetUpdateCycle) withObject:nil afterDelay:1]; |
|
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
254 |
}
|
255 |
||
256 |
- (BOOL)automaticallyChecksForUpdates |
|
143
by Andy Matuschak
Fixed a confounding bug that somehow slipped in: when an update check was aborted, I was calling -automaticallyUpdates to determine whether I should reschedule another update check. |
257 |
{
|
287
by Andy Matuschak
Fixes 258529 and 257967 |
258 |
// Don't automatically update when the check interval is 0, to be compatible with 1.1 settings.
|
259 |
if ([self updateCheckInterval] == 0) |
|
260 |
return NO; |
|
286
by Andy Matuschak
Fixes 258547 |
261 |
return [host boolForKey:SUEnableAutomaticChecksKey]; |
262 |
}
|
|
263 |
||
264 |
- (void)setAutomaticallyDownloadsUpdates:(BOOL)automaticallyUpdates |
|
265 |
{
|
|
266 |
[host setBool:automaticallyUpdates forUserDefaultsKey:SUAutomaticallyUpdateKey]; |
|
267 |
}
|
|
268 |
||
269 |
- (BOOL)automaticallyDownloadsUpdates |
|
46
by andym
Reorganized SUUpdater.m; it's in better order now. |
270 |
{
|
271 |
// If the SUAllowsAutomaticUpdatesKey exists and is set to NO, return NO.
|
|
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
272 |
if ([host objectForInfoDictionaryKey:SUAllowsAutomaticUpdatesKey] && [host boolForInfoDictionaryKey:SUAllowsAutomaticUpdatesKey] == NO) |
46
by andym
Reorganized SUUpdater.m; it's in better order now. |
273 |
return NO; |
274 |
||
286
by Andy Matuschak
Fixes 258547 |
275 |
// Otherwise, automatically downloading updates is allowed. Does the user want it?
|
276 |
return [host boolForUserDefaultsKey:SUAutomaticallyUpdateKey]; |
|
46
by andym
Reorganized SUUpdater.m; it's in better order now. |
277 |
}
|
278 |
||
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
279 |
- (void)setFeedURL:(NSURL *)feedURL |
280 |
{
|
|
281 |
[host setObject:[feedURL absoluteString] forUserDefaultsKey:SUFeedURLKey]; |
|
282 |
}
|
|
283 |
||
284 |
- (NSURL *)feedURL |
|
212
by Andy Matuschak
Killed NSURL+Parameters and moved the relevant code into SUUpdater. |
285 |
{
|
286 |
// A value in the user defaults overrides one in the Info.plist (so preferences panels can be created wherein users choose between beta / release feeds).
|
|
285
by Andy Matuschak
Fixes 245723 |
287 |
NSString *appcastString = [host objectForKey:SUFeedURLKey]; |
212
by Andy Matuschak
Killed NSURL+Parameters and moved the relevant code into SUUpdater. |
288 |
if (!appcastString) // Can't find an appcast string! |
289 |
[NSException raise:@"SUNoFeedURL" format:@"You must specify the URL of the appcast as the SUFeedURLKey in either the Info.plist or the user defaults!"]; |
|
290 |
NSCharacterSet* quoteSet = [NSCharacterSet characterSetWithCharactersInString: @"\"\'"]; // Some feed publishers add quotes; strip 'em. |
|
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
291 |
return [NSURL URLWithString:[appcastString stringByTrimmingCharactersInSet:quoteSet]]; |
212
by Andy Matuschak
Killed NSURL+Parameters and moved the relevant code into SUUpdater. |
292 |
}
|
293 |
||
286
by Andy Matuschak
Fixes 258547 |
294 |
- (void)setSendsSystemProfile:(BOOL)sendsSystemProfile |
295 |
{
|
|
296 |
[host setBool:sendsSystemProfile forUserDefaultsKey:SUSendProfileInfoKey]; |
|
297 |
}
|
|
298 |
||
299 |
- (BOOL)sendsSystemProfile |
|
300 |
{
|
|
301 |
return [host boolForUserDefaultsKey:SUSendProfileInfoKey]; |
|
282
by Andy Matuschak
Fixes 251968 |
302 |
}
|
303 |
||
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
304 |
- (NSURL *)parameterizedFeedURL |
212
by Andy Matuschak
Killed NSURL+Parameters and moved the relevant code into SUUpdater. |
305 |
{
|
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
306 |
NSURL *baseFeedURL = [self feedURL]; |
212
by Andy Matuschak
Killed NSURL+Parameters and moved the relevant code into SUUpdater. |
307 |
|
308 |
// Determine all the parameters we're attaching to the base feed URL.
|
|
286
by Andy Matuschak
Fixes 258547 |
309 |
BOOL sendingSystemProfile = [self sendsSystemProfile]; |
265.1.1
by David Smith
A cleaned up and tested version of the one-submit-per-week code |
310 |
|
268
by Andy Matuschak
As discussed in https://bugs.launchpad.net/sparkle/+bug/243884/comments/11, this patch makes it so that system profiling is only submitted to the server once per week. This will normalize clients' users: those which check daily won't count much more than those which check weekly. Thanks to David Smith for the patch. |
311 |
// Let's only send the system profiling information once per week at most, so we normalize daily-checkers vs. biweekly-checkers and the such.
|
265.1.1
by David Smith
A cleaned up and tested version of the one-submit-per-week code |
312 |
NSDate *lastSubmitDate = [host objectForUserDefaultsKey:SULastProfileSubmitDateKey]; |
313 |
if(!lastSubmitDate) |
|
314 |
lastSubmitDate = [NSDate distantPast]; |
|
268
by Andy Matuschak
As discussed in https://bugs.launchpad.net/sparkle/+bug/243884/comments/11, this patch makes it so that system profiling is only submitted to the server once per week. This will normalize clients' users: those which check daily won't count much more than those which check weekly. Thanks to David Smith for the patch. |
315 |
const NSTimeInterval oneWeek = 60 * 60 * 24 * 7; |
316 |
sendingSystemProfile &= (-[lastSubmitDate timeIntervalSinceNow] >= oneWeek); |
|
265.1.1
by David Smith
A cleaned up and tested version of the one-submit-per-week code |
317 |
|
77
by andym
Made a good deal more progress integrating the profile checking features. It should actually work now. |
318 |
NSArray *parameters = [NSArray array]; |
242.1.4
by Andy Matuschak
Fixes 244857 |
319 |
if ([delegate respondsToSelector:@selector(feedParametersForUpdater:sendingSystemProfile:)]) |
320 |
parameters = [parameters arrayByAddingObjectsFromArray:[delegate feedParametersForUpdater:self sendingSystemProfile:sendingSystemProfile]]; |
|
77
by andym
Made a good deal more progress integrating the profile checking features. It should actually work now. |
321 |
if (sendingSystemProfile) |
268
by Andy Matuschak
As discussed in https://bugs.launchpad.net/sparkle/+bug/243884/comments/11, this patch makes it so that system profiling is only submitted to the server once per week. This will normalize clients' users: those which check daily won't count much more than those which check weekly. Thanks to David Smith for the patch. |
322 |
{
|
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
323 |
parameters = [parameters arrayByAddingObjectsFromArray:[host systemProfile]]; |
268
by Andy Matuschak
As discussed in https://bugs.launchpad.net/sparkle/+bug/243884/comments/11, this patch makes it so that system profiling is only submitted to the server once per week. This will normalize clients' users: those which check daily won't count much more than those which check weekly. Thanks to David Smith for the patch. |
324 |
[host setObject:[NSDate date] forUserDefaultsKey:SULastProfileSubmitDateKey]; |
325 |
}
|
|
212
by Andy Matuschak
Killed NSURL+Parameters and moved the relevant code into SUUpdater. |
326 |
if (parameters == nil || [parameters count] == 0) { return baseFeedURL; } |
327 |
||
328 |
// Build up the parameterized URL.
|
|
329 |
NSMutableArray *parameterStrings = [NSMutableArray array]; |
|
330 |
NSEnumerator *profileInfoEnumerator = [parameters objectEnumerator]; |
|
331 |
NSDictionary *currentProfileInfo; |
|
332 |
while ((currentProfileInfo = [profileInfoEnumerator nextObject])) |
|
333 |
[parameterStrings addObject:[NSString stringWithFormat:@"%@=%@", [currentProfileInfo objectForKey:@"key"], [currentProfileInfo objectForKey:@"value"]]]; |
|
334 |
||
288
by Andy Matuschak
Fixes 258492 |
335 |
NSString *separatorCharacter = @"?"; |
336 |
if ([baseFeedURL query]) |
|
337 |
separatorCharacter = @"&"; // In case the URL is already http://foo.org/baz.xml?bat=4 |
|
290
by Andy Matuschak
Fixed a stupid mistake that prevented my fix for parameterized URLs from actually functioning. |
338 |
NSString *appcastStringWithProfile = [NSString stringWithFormat:@"%@%@%@", [baseFeedURL absoluteString], separatorCharacter, [parameterStrings componentsJoinedByString:@"&"]]; |
212
by Andy Matuschak
Killed NSURL+Parameters and moved the relevant code into SUUpdater. |
339 |
|
340 |
// Clean it up so it's a valid URL
|
|
341 |
return [NSURL URLWithString:[appcastStringWithProfile stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; |
|
77
by andym
Made a good deal more progress integrating the profile checking features. It should actually work now. |
342 |
}
|
343 |
||
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
344 |
- (void)setUpdateCheckInterval:(NSTimeInterval)updateCheckInterval |
345 |
{
|
|
346 |
[host setObject:[NSNumber numberWithDouble:updateCheckInterval] forUserDefaultsKey:SUScheduledCheckIntervalKey]; |
|
287
by Andy Matuschak
Fixes 258529 and 257967 |
347 |
if (updateCheckInterval == 0) // For compatibility with 1.1's settings. |
348 |
[self setAutomaticallyChecksForUpdates:NO]; |
|
349 |
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetUpdateCycle) object:nil]; |
|
350 |
||
351 |
// Provide a small delay in case multiple preferences are being updated simultaneously.
|
|
352 |
[self performSelector:@selector(resetUpdateCycle) withObject:nil afterDelay:1]; |
|
242.1.14
by Andy Matuschak
The Sparkle preference keys are now declared private / deprecated / allowed to change without me receiving hate email. However! SUUpdater is now KVC-compliant for: |
353 |
}
|
354 |
||
355 |
- (NSTimeInterval)updateCheckInterval |
|
145
by Andy Matuschak
Removed the checkInterval IV and factored out its assignment to a checkInterval method in SUUpdater. Now when future updates are scheduled after an initial one exits, they'll use the current interval. |
356 |
{
|
357 |
// Find the stored check interval. User defaults override Info.plist.
|
|
287
by Andy Matuschak
Fixes 258529 and 257967 |
358 |
NSNumber *intervalValue = [host objectForKey:SUScheduledCheckIntervalKey]; |
359 |
if (intervalValue) |
|
360 |
return [intervalValue doubleValue]; |
|
361 |
else
|
|
362 |
return SU_DEFAULT_CHECK_INTERVAL; |
|
145
by Andy Matuschak
Removed the checkInterval IV and factored out its assignment to a checkInterval method in SUUpdater. Now when future updates are scheduled after an initial one exits, they'll use the current interval. |
363 |
}
|
364 |
||
46
by andym
Reorganized SUUpdater.m; it's in better order now. |
365 |
- (void)dealloc |
1
by andym
Holy restructuring, batman! Watch out for falling folders. |
366 |
{
|
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
367 |
[self unregisterAsObserver]; |
368 |
[host release]; |
|
46
by andym
Reorganized SUUpdater.m; it's in better order now. |
369 |
if (checkTimer) { [checkTimer invalidate]; } |
370 |
[super dealloc]; |
|
1
by andym
Holy restructuring, batman! Watch out for falling folders. |
371 |
}
|
372 |
||
116
by andym
Touched practically every line of code in a super-monster-awesome refactoring. Please read: |
373 |
- (BOOL)validateMenuItem:(NSMenuItem *)item |
71
by andym
Restored 10.3.9 compatibility to the system version method. |
374 |
{
|
116
by andym
Touched practically every line of code in a super-monster-awesome refactoring. Please read: |
375 |
if ([item action] == @selector(checkForUpdates:)) |
376 |
return ![self updateInProgress]; |
|
377 |
return YES; |
|
71
by andym
Restored 10.3.9 compatibility to the system version method. |
378 |
}
|
379 |
||
77
by andym
Made a good deal more progress integrating the profile checking features. It should actually work now. |
380 |
- (void)setDelegate:aDelegate |
381 |
{
|
|
184
by Andy Matuschak
Fixes 239512 |
382 |
delegate = aDelegate; |
77
by andym
Made a good deal more progress integrating the profile checking features. It should actually work now. |
383 |
}
|
384 |
||
116
by andym
Touched practically every line of code in a super-monster-awesome refactoring. Please read: |
385 |
- (BOOL)updateInProgress |
386 |
{
|
|
387 |
return driver && ([driver finished] == NO); |
|
388 |
}
|
|
389 |
||
242.1.4
by Andy Matuschak
Fixes 244857 |
390 |
- delegate { return delegate; } |
391 |
- (NSBundle *)hostBundle { return [host bundle]; } |
|
242.1.1
by Andy Matuschak
Beginnings of insane SUHost-based refactoring to get rid of NSBundle+Sparkle. More super-unstable refactorings to come... |
392 |
|
1
by andym
Holy restructuring, batman! Watch out for falling folders. |
393 |
@end
|