Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 364 lines (311 sloc) 14.267 kB
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
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"
5aa1e18 Improved headers from Charles D. H. Williams.
andym authored
10
f815eec @andymatuschak Fixes 243884
andymatuschak authored
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
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
19 @interface SUUpdater (Private)
d8149e9 @andymatuschak Fixes 253145
andymatuschak authored
20 - initForBundle:(NSBundle *)bundle;
f815eec @andymatuschak Fixes 243884
andymatuschak authored
21 - (void)checkForUpdatesWithDriver:(SUUpdateDriver *)updateDriver;
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
22 - (BOOL)automaticallyUpdates;
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
23 - (void)scheduleNextUpdateCheck;
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
24 - (void)registerAsObserver;
25 - (void)unregisterAsObserver;
26 - (void)updateDriverDidFinish:(NSNotification *)note;
27 - initForBundle:(NSBundle *)bundle;
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
28 - (NSURL *)parameterizedFeedURL;
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
29 @end
30
31 @implementation SUUpdater
32
bbedfa1 Reorganized SUUpdater.m; it's in better order now.
andym authored
33 #pragma mark Initialization
34
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
35 static NSMutableDictionary *sharedUpdaters = nil;
36 static NSString *SUUpdaterDefaultsObservationContext = @"SUUpdaterDefaultsObservationContext";
5b76530 Made a number of fixes to potentially dangerous singleton behavior as…
andym authored
37
bbedfa1 Reorganized SUUpdater.m; it's in better order now.
andym authored
38 + (SUUpdater *)sharedUpdater
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
39 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
40 return [self updaterForBundle:[NSBundle mainBundle]];
63011aa Beware of falling bricks! Huge refactoring commit #1: cleansing Spark…
andym authored
41 }
42
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
43 // 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
44 + (SUUpdater *)updaterForBundle:(NSBundle *)bundle
45 {
46 if (bundle == nil) bundle = [NSBundle mainBundle];
47 id updater = [sharedUpdaters objectForKey:[NSValue valueWithNonretainedObject:bundle]];
48 if (updater == nil)
d8149e9 @andymatuschak Fixes 253145
andymatuschak authored
49 updater = [[[self class] alloc] initForBundle:bundle];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
50 return updater;
51 }
52
53 // This is the designated initializer for SUUpdater, important for subclasses
54 - initForBundle:(NSBundle *)bundle
63011aa Beware of falling bricks! Huge refactoring commit #1: cleansing Spark…
andym authored
55 {
5bf76dd Oops! Committed the last patch with broken code; this code works.
andym authored
56 self = [super init];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
57 if (bundle == nil) bundle = [NSBundle mainBundle];
58 id updater = [sharedUpdaters objectForKey:[NSValue valueWithNonretainedObject:bundle]];
59 if (updater)
2ec35ae Finished cleaning up singleton stuff in SUUpdater.m
andym authored
60 {
61 [self release];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
62 self = [updater retain];
2ec35ae Finished cleaning up singleton stuff in SUUpdater.m
andym authored
63 }
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
64 else if (self)
5bf76dd Oops! Committed the last patch with broken code; this code works.
andym authored
65 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
66 if (sharedUpdaters == nil)
67 sharedUpdaters = [[NSMutableDictionary alloc] init];
68 [sharedUpdaters setObject:self forKey:[NSValue valueWithNonretainedObject:bundle]];
69 host = [[SUHost alloc] initWithBundle:bundle];
70 [self registerAsObserver];
87f2893 Fixed warnings for missing newlines at the end of the file.
andym authored
71 }
5e05339 #76 Support for Plug-ins
catlan authored
72 return self;
73 }
74
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
75 // This will be used when the updater is instantiated in a nib such as MainMenu
76 - (id)init
77 {
78 return [self initForBundle:[NSBundle mainBundle]];
79 }
80
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
81 - (void)applicationDidFinishLaunching:(NSNotification *)note
82 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
83 BOOL shouldPrompt = NO;
84
85 // If the user has been asked about automatic checks, don't bother prompting
86 if ([host objectForUserDefaultsKey:SUEnableAutomaticChecksKey])
87 {
88 shouldPrompt = NO;
89 }
90 // Does the delegate want to take care of the logic for when we should ask permission to update?
b3f3944 @andymatuschak Fixes 244857
andymatuschak authored
91 else if ([delegate respondsToSelector:@selector(updaterShouldPromptForPermissionToCheckForUpdates:)])
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
92 {
b3f3944 @andymatuschak Fixes 244857
andymatuschak authored
93 shouldPrompt = [delegate updaterShouldPromptForPermissionToCheckForUpdates:self];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
94 }
95 // Has he been asked already? And don't ask if the host has a default value set in its Info.plist.
96 else if ([host objectForUserDefaultsKey:SUEnableAutomaticChecksKey] == nil &&
97 [host objectForInfoDictionaryKey:SUEnableAutomaticChecksKey] == nil)
98 {
99 if ([host objectForUserDefaultsKey:SUEnableAutomaticChecksKeyOld])
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
100 [self setAutomaticallyChecksForUpdates:[host boolForUserDefaultsKey:SUEnableAutomaticChecksKeyOld]];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
101 // Now, we don't want to ask the user for permission to do a weird thing on the first launch.
102 // We wait until the second launch.
103 else if ([host boolForUserDefaultsKey:SUHasLaunchedBeforeKey] == NO)
104 [host setBool:YES forUserDefaultsKey:SUHasLaunchedBeforeKey];
105 else
106 shouldPrompt = YES;
107 }
108
109 if (shouldPrompt)
110 {
111 [SUUpdatePermissionPrompt promptWithHost:host delegate:self];
112 // We start the update checks and register as observer for changes after the prompt finishes
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
113 }
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
114 else
115 {
116 // We check if the user's said they want updates, or they haven't said anything, and the default is set to checking.
117 [self scheduleNextUpdateCheck];
118 }
8c3960f Finished integrating SparklePlus profiling! Just set SUEnableSystemPr…
andym authored
119 }
120
121 - (void)updatePermissionPromptFinishedWithResult:(SUPermissionPromptResult)result
122 {
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
123 [self setAutomaticallyChecksForUpdates:(result == SUAutomaticallyCheck)];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
124 // Schedule checks, but make sure we ignore the delayed call from KVO
ac4e4e4 @andymatuschak Fixes 245991
andymatuschak authored
125 [self resetUpdateCycle];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
126 }
127
128 - (void)updateDriverDidFinish:(NSNotification *)note
129 {
130 if ([note object] == driver && [driver finished])
131 {
132 [driver release]; driver = nil;
133 [self scheduleNextUpdateCheck];
134 }
8c3960f Finished integrating SparklePlus profiling! Just set SUEnableSystemPr…
andym authored
135 }
136
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
137 - (void)scheduleNextUpdateCheck
ebb1f01 @andymatuschak Removed the checkInterval IV and factored out its assignment to a che…
andymatuschak authored
138 {
4b6fc55 @andymatuschak Removed unnecessary @synchronized's.
andymatuschak authored
139 if (checkTimer)
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
140 {
4b6fc55 @andymatuschak Removed unnecessary @synchronized's.
andymatuschak authored
141 [checkTimer invalidate];
142 checkTimer = nil;
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
143 }
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
144 if (![self automaticallyChecksForUpdates]) return;
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
145
8c3960f Finished integrating SparklePlus profiling! Just set SUEnableSystemPr…
andym authored
146 // How long has it been since last we checked for an update?
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
147 NSDate *lastCheckDate = [host objectForUserDefaultsKey:SULastCheckTimeKey];
8c3960f Finished integrating SparklePlus profiling! Just set SUEnableSystemPr…
andym authored
148 if (!lastCheckDate) { lastCheckDate = [NSDate distantPast]; }
149 NSTimeInterval intervalSinceCheck = [[NSDate date] timeIntervalSinceDate:lastCheckDate];
150
151 // Now we want to figure out how long until we check again.
152 NSTimeInterval delayUntilCheck;
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
153 if (intervalSinceCheck < [self updateCheckInterval])
154 delayUntilCheck = ([self updateCheckInterval] - intervalSinceCheck); // It hasn't been long enough.
8c3960f Finished integrating SparklePlus profiling! Just set SUEnableSystemPr…
andym authored
155 else
156 delayUntilCheck = 0; // We're overdue! Run one now.
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
157 checkTimer = [NSTimer scheduledTimerWithTimeInterval:delayUntilCheck target:self selector:@selector(checkForUpdatesInBackground) userInfo:nil repeats:NO];
dc147ec Continued incremental refactoring; things seem to still be holding to…
andym authored
158 }
159
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
160 - (void)checkForUpdatesInBackground
dc147ec Continued incremental refactoring; things seem to still be holding to…
andym authored
161 {
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
162 [self checkForUpdatesWithDriver:[[[([self automaticallyUpdates] ? [SUAutomaticUpdateDriver class] : [SUScheduledUpdateDriver class]) alloc] init] autorelease]];
dc147ec Continued incremental refactoring; things seem to still be holding to…
andym authored
163 }
164
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
165 - (IBAction)checkForUpdates:sender
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
166 {
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
167 [self checkForUpdatesWithDriver:[[[SUUserInitiatedUpdateDriver alloc] init] autorelease]];
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
168 }
169
f815eec @andymatuschak Fixes 243884
andymatuschak authored
170 - (void)checkForUpdateInformation
171 {
172 [self checkForUpdatesWithDriver:[[[SUProbingUpdateDriver alloc] init] autorelease]];
173 }
174
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
175 - (void)checkForUpdatesWithDriver:(SUUpdateDriver *)d
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
176 {
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
177 if ([self updateInProgress]) { return; }
4b6fc55 @andymatuschak Removed unnecessary @synchronized's.
andymatuschak authored
178 if (checkTimer) { [checkTimer invalidate]; checkTimer = nil; }
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
179
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
180 driver = [d retain];
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
181 [driver checkForUpdatesAtURL:[self parameterizedFeedURL] host:host];
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
182 }
183
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
184 - (void)registerAsObserver
6a7c8b3 Substantial changes made to how Sparkle works on startup now. SUCheck…
andym authored
185 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
186 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidFinishLaunching:) name:NSApplicationDidFinishLaunchingNotification object:NSApp];
187 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateDriverDidFinish:) name:SUUpdateDriverFinishedNotification object:nil];
188 // No sense observing the shared NSUserDefaultsController when we're not updating the main bundle.
189 if ([host bundle] != [NSBundle mainBundle]) return;
190 [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:[@"values." stringByAppendingString:SUScheduledCheckIntervalKey] options:0 context:SUUpdaterDefaultsObservationContext];
191 [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:[@"values." stringByAppendingString:SUEnableAutomaticChecksKey] options:0 context:SUUpdaterDefaultsObservationContext];
192 }
193
194 - (void)unregisterAsObserver
195 {
196 [[NSNotificationCenter defaultCenter] removeObserver:self];
197 // Removing self as a KVO observer if no observer was registered leads to an NSException. But we don't care.
198 @try
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
199 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
200 [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:[@"values." stringByAppendingString:SUScheduledCheckIntervalKey]];
201 [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:[@"values." stringByAppendingString:SUEnableAutomaticChecksKey]];
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
202 }
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
203 @catch (NSException *e) { }
204 }
205
206 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
207 {
208 if (context == SUUpdaterDefaultsObservationContext)
209 {
210 // 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.
211 // Or we may get this from the developer and from our own KVO observation, this will effectively coalesce them.
ac4e4e4 @andymatuschak Fixes 245991
andymatuschak authored
212 [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetUpdateCycle) object:nil];
213 [self performSelector:@selector(resetUpdateCycle) withObject:nil afterDelay:15];
214 [self resetUpdateCycle];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
215 }
216 else
217 {
218 [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
219 }
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
220 }
221
ac4e4e4 @andymatuschak Fixes 245991
andymatuschak authored
222 - (void)resetUpdateCycle
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
223 {
ac4e4e4 @andymatuschak Fixes 245991
andymatuschak authored
224 [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetUpdateCycle) object:nil];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
225 [self scheduleNextUpdateCheck];
1c1bb3a #77 SUIgnoreChecks to ignore update, needed for Sparkle in large depl…
catlan authored
226 }
227
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
228 - (void)setAutomaticallyChecksForUpdates:(BOOL)automaticallyCheckForUpdates
229 {
230 [host setBool:automaticallyCheckForUpdates forUserDefaultsKey:SUEnableAutomaticChecksKey];
231 }
232
233 - (BOOL)automaticallyChecksForUpdates
49cfd57 @andymatuschak Fixed a confounding bug that somehow slipped in: when an update check…
andymatuschak authored
234 {
235 // Breaking this down for readability:
236 // If the user says he wants automatic update checks, let's do it.
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
237 if ([host boolForUserDefaultsKey:SUEnableAutomaticChecksKey] == YES)
49cfd57 @andymatuschak Fixed a confounding bug that somehow slipped in: when an update check…
andymatuschak authored
238 return YES;
239 // If the user hasn't said anything, but the developer says we should do it, let's do it.
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
240 if ([host objectForUserDefaultsKey:SUEnableAutomaticChecksKey] == nil && [host boolForInfoDictionaryKey:SUEnableAutomaticChecksKey] == YES)
49cfd57 @andymatuschak Fixed a confounding bug that somehow slipped in: when an update check…
andymatuschak authored
241 return YES;
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
242 return NO; // Otherwise, don't bother.
49cfd57 @andymatuschak Fixed a confounding bug that somehow slipped in: when an update check…
andymatuschak authored
243 }
244
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
245 - (BOOL)automaticallyUpdates
246 {
247 // If the SUAllowsAutomaticUpdatesKey exists and is set to NO, return NO.
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
248 if ([host objectForInfoDictionaryKey:SUAllowsAutomaticUpdatesKey] && [host boolForInfoDictionaryKey:SUAllowsAutomaticUpdatesKey] == NO)
6a7c8b3 Substantial changes made to how Sparkle works on startup now. SUCheck…
andym authored
249 return NO;
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
250
251 // If we're not using DSA signatures, we aren't going to trust any updates automatically.
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
252 if ([host boolForInfoDictionaryKey:SUExpectsDSASignatureKey] != YES)
6a7c8b3 Substantial changes made to how Sparkle works on startup now. SUCheck…
andym authored
253 return NO;
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
254
6a7c8b3 Substantial changes made to how Sparkle works on startup now. SUCheck…
andym authored
255 // If there's no setting, or it's set to no, we're not automatically updating.
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
256 if ([host boolForUserDefaultsKey:SUAutomaticallyUpdateKey] != YES)
6a7c8b3 Substantial changes made to how Sparkle works on startup now. SUCheck…
andym authored
257 return NO;
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
258
6a7c8b3 Substantial changes made to how Sparkle works on startup now. SUCheck…
andym authored
259 return YES; // Otherwise, we're good to go.
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
260 }
261
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
262 - (void)setFeedURL:(NSURL *)feedURL
263 {
264 [host setObject:[feedURL absoluteString] forUserDefaultsKey:SUFeedURLKey];
265 }
266
267 - (NSURL *)feedURL
645a96e Made a good deal more progress integrating the profile checking featu…
andym authored
268 {
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
269 // 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).
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
270 NSString *appcastString = [host objectForUserDefaultsKey:SUFeedURLKey];
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
271 if (!appcastString)
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
272 appcastString = [host objectForInfoDictionaryKey:SUFeedURLKey];
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
273 if (!appcastString) // Can't find an appcast string!
274 [NSException raise:@"SUNoFeedURL" format:@"You must specify the URL of the appcast as the SUFeedURLKey in either the Info.plist or the user defaults!"];
275 NSCharacterSet* quoteSet = [NSCharacterSet characterSetWithCharactersInString: @"\"\'"]; // Some feed publishers add quotes; strip 'em.
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
276 return [NSURL URLWithString:[appcastString stringByTrimmingCharactersInSet:quoteSet]];
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
277 }
278
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
279 - (NSURL *)parameterizedFeedURL
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
280 {
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
281 NSURL *baseFeedURL = [self feedURL];
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
282
283 // Determine all the parameters we're attaching to the base feed URL.
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
284 BOOL sendingSystemProfile = ([host boolForUserDefaultsKey:SUSendProfileInfoKey] == YES);
e3226d3 A cleaned up and tested version of the one-submit-per-week code
David Smith authored
285
d1c0978 @andymatuschak As discussed in https://bugs.launchpad.net/sparkle/+bug/243884/commen…
andymatuschak authored
286 // Let's only send the system profiling information once per week at most, so we normalize daily-checkers vs. biweekly-checkers and the such.
e3226d3 A cleaned up and tested version of the one-submit-per-week code
David Smith authored
287 NSDate *lastSubmitDate = [host objectForUserDefaultsKey:SULastProfileSubmitDateKey];
288 if(!lastSubmitDate)
289 lastSubmitDate = [NSDate distantPast];
d1c0978 @andymatuschak As discussed in https://bugs.launchpad.net/sparkle/+bug/243884/commen…
andymatuschak authored
290 const NSTimeInterval oneWeek = 60 * 60 * 24 * 7;
291 sendingSystemProfile &= (-[lastSubmitDate timeIntervalSinceNow] >= oneWeek);
e3226d3 A cleaned up and tested version of the one-submit-per-week code
David Smith authored
292
645a96e Made a good deal more progress integrating the profile checking featu…
andym authored
293 NSArray *parameters = [NSArray array];
b3f3944 @andymatuschak Fixes 244857
andymatuschak authored
294 if ([delegate respondsToSelector:@selector(feedParametersForUpdater:sendingSystemProfile:)])
295 parameters = [parameters arrayByAddingObjectsFromArray:[delegate feedParametersForUpdater:self sendingSystemProfile:sendingSystemProfile]];
645a96e Made a good deal more progress integrating the profile checking featu…
andym authored
296 if (sendingSystemProfile)
d1c0978 @andymatuschak As discussed in https://bugs.launchpad.net/sparkle/+bug/243884/commen…
andymatuschak authored
297 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
298 parameters = [parameters arrayByAddingObjectsFromArray:[host systemProfile]];
d1c0978 @andymatuschak As discussed in https://bugs.launchpad.net/sparkle/+bug/243884/commen…
andymatuschak authored
299 [host setObject:[NSDate date] forUserDefaultsKey:SULastProfileSubmitDateKey];
300 }
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
301 if (parameters == nil || [parameters count] == 0) { return baseFeedURL; }
302
303 // Build up the parameterized URL.
304 NSMutableArray *parameterStrings = [NSMutableArray array];
305 NSEnumerator *profileInfoEnumerator = [parameters objectEnumerator];
306 NSDictionary *currentProfileInfo;
307 while ((currentProfileInfo = [profileInfoEnumerator nextObject]))
308 [parameterStrings addObject:[NSString stringWithFormat:@"%@=%@", [currentProfileInfo objectForKey:@"key"], [currentProfileInfo objectForKey:@"value"]]];
309
310 NSString *appcastStringWithProfile = [NSString stringWithFormat:@"%@?%@", [baseFeedURL absoluteString], [parameterStrings componentsJoinedByString:@"&"]];
311
312 // Clean it up so it's a valid URL
313 return [NSURL URLWithString:[appcastStringWithProfile stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
645a96e Made a good deal more progress integrating the profile checking featu…
andym authored
314 }
315
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
316 - (void)setUpdateCheckInterval:(NSTimeInterval)updateCheckInterval
317 {
318 [host setObject:[NSNumber numberWithDouble:updateCheckInterval] forUserDefaultsKey:SUScheduledCheckIntervalKey];
319 }
320
321 - (NSTimeInterval)updateCheckInterval
ebb1f01 @andymatuschak Removed the checkInterval IV and factored out its assignment to a che…
andymatuschak authored
322 {
323 NSTimeInterval checkInterval = 0;
324 // Find the stored check interval. User defaults override Info.plist.
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
325 if ([host objectForUserDefaultsKey:SUScheduledCheckIntervalKey])
326 checkInterval = [[host objectForUserDefaultsKey:SUScheduledCheckIntervalKey] doubleValue];
327 else if ([host objectForInfoDictionaryKey:SUScheduledCheckIntervalKey])
328 checkInterval = [[host objectForInfoDictionaryKey:SUScheduledCheckIntervalKey] doubleValue];
ebb1f01 @andymatuschak Removed the checkInterval IV and factored out its assignment to a che…
andymatuschak authored
329
330 if (checkInterval < SU_MIN_CHECK_INTERVAL) // This can also mean one that isn't set.
331 checkInterval = SU_DEFAULT_CHECK_INTERVAL;
332 return checkInterval;
333 }
334
bbedfa1 Reorganized SUUpdater.m; it's in better order now.
andym authored
335 - (void)dealloc
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
336 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
337 [self unregisterAsObserver];
338 [host release];
bbedfa1 Reorganized SUUpdater.m; it's in better order now.
andym authored
339 if (checkTimer) { [checkTimer invalidate]; }
340 [super dealloc];
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
341 }
342
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
343 - (BOOL)validateMenuItem:(NSMenuItem *)item
66bbbed Restored 10.3.9 compatibility to the system version method.
andym authored
344 {
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
345 if ([item action] == @selector(checkForUpdates:))
346 return ![self updateInProgress];
347 return YES;
66bbbed Restored 10.3.9 compatibility to the system version method.
andym authored
348 }
349
645a96e Made a good deal more progress integrating the profile checking featu…
andym authored
350 - (void)setDelegate:aDelegate
351 {
cd4addb @andymatuschak Fixes 239512
andymatuschak authored
352 delegate = aDelegate;
645a96e Made a good deal more progress integrating the profile checking featu…
andym authored
353 }
354
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
355 - (BOOL)updateInProgress
356 {
357 return driver && ([driver finished] == NO);
358 }
359
b3f3944 @andymatuschak Fixes 244857
andymatuschak authored
360 - delegate { return delegate; }
361 - (NSBundle *)hostBundle { return [host bundle]; }
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
362
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
363 @end
Something went wrong with that request. Please try again.