Skip to content

HTTPS clone URL

Subversion checkout URL

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