Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 426 lines (360 sloc) 16.93 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;
91c242a @andymatuschak Fixes Bug #312381: "Bundles can't ask for permission to update; devel…
andymatuschak authored
21 - (void)startUpdateCycle;
f815eec @andymatuschak Fixes 243884
andymatuschak authored
22 - (void)checkForUpdatesWithDriver:(SUUpdateDriver *)updateDriver;
ec7f38d @andymatuschak Fixes 258547
andymatuschak authored
23 - (BOOL)automaticallyDownloadsUpdates;
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
24 - (void)scheduleNextUpdateCheck;
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
25 - (void)registerAsObserver;
26 - (void)unregisterAsObserver;
27 - (void)updateDriverDidFinish:(NSNotification *)note;
28 - initForBundle:(NSBundle *)bundle;
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
29 - (NSURL *)parameterizedFeedURL;
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
30 @end
31
32 @implementation SUUpdater
33
bbedfa1 Reorganized SUUpdater.m; it's in better order now.
andym authored
34 #pragma mark Initialization
35
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
36 static NSMutableDictionary *sharedUpdaters = nil;
d7774c0 performed a code review, specifically:
Sean McBride authored
37 static NSString * const SUUpdaterDefaultsObservationContext = @"SUUpdaterDefaultsObservationContext";
5b76530 Made a number of fixes to potentially dangerous singleton behavior as…
andym authored
38
bbedfa1 Reorganized SUUpdater.m; it's in better order now.
andym authored
39 + (SUUpdater *)sharedUpdater
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
40 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
41 return [self updaterForBundle:[NSBundle mainBundle]];
63011aa Beware of falling bricks! Huge refactoring commit #1: cleansing Spark…
andym authored
42 }
43
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
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)
36b7d43 fixed extra ref count, half of bug #502212
Sean McBride authored
50 updater = [[[[self class] alloc] initForBundle:bundle] autorelease];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
51 return updater;
52 }
53
54 // This is the designated initializer for SUUpdater, important for subclasses
55 - initForBundle:(NSBundle *)bundle
63011aa Beware of falling bricks! Huge refactoring commit #1: cleansing Spark…
andym authored
56 {
5bf76dd Oops! Committed the last patch with broken code; this code works.
andym authored
57 self = [super init];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
58 if (bundle == nil) bundle = [NSBundle mainBundle];
561bbbe @andymatuschak Because of the way Sparkle forces SUUpdaters to be per-bundle singlet…
andymatuschak authored
59
60 // Register as observer straight away to avoid exceptions on -dealloc when -unregisterAsObserver is called:
61 if (self)
62 [self registerAsObserver];
63
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
64 id updater = [sharedUpdaters objectForKey:[NSValue valueWithNonretainedObject:bundle]];
65 if (updater)
2ec35ae Finished cleaning up singleton stuff in SUUpdater.m
andym authored
66 {
67 [self release];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
68 self = [updater retain];
2ec35ae Finished cleaning up singleton stuff in SUUpdater.m
andym authored
69 }
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
70 else if (self)
5bf76dd Oops! Committed the last patch with broken code; this code works.
andym authored
71 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
72 if (sharedUpdaters == nil)
73 sharedUpdaters = [[NSMutableDictionary alloc] init];
74 [sharedUpdaters setObject:self forKey:[NSValue valueWithNonretainedObject:bundle]];
75 host = [[SUHost alloc] initWithBundle:bundle];
d62e47c @andymatuschak Fixing Bug #416798: "Sparkle should warn developers if the app has no…
andymatuschak authored
76
77 // Saving-the-developer-from-a-stupid-mistake-check:
78 if (![[[self feedURL] scheme] isEqualToString:@"https"] && ![host publicDSAKey])
79 NSRunAlertPanel(@"Insecure update error!", @"For security reasons, you need to distribute your appcast over SSL or sign your updates. See Sparkle's documentation for more information.", @"OK", nil, nil);
80
91c242a @andymatuschak Fixes Bug #312381: "Bundles can't ask for permission to update; devel…
andymatuschak authored
81 // This runs the permission prompt if needed, but never before the app has finished launching because the runloop won't run before that
82 [self performSelector:@selector(startUpdateCycle) withObject:nil afterDelay:0];
87f2893 Fixed warnings for missing newlines at the end of the file.
andym authored
83 }
5e05339 #76 Support for Plug-ins
catlan authored
84 return self;
85 }
86
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
87 // This will be used when the updater is instantiated in a nib such as MainMenu
88 - (id)init
89 {
90 return [self initForBundle:[NSBundle mainBundle]];
91 }
92
c386b70 @andymatuschak Partial fix for 245277: basic descriptions for some Sparkle classes. …
andymatuschak authored
93 - (NSString *)description { return [NSString stringWithFormat:@"%@ <%@>", [self class], [host bundlePath]]; }
94
91c242a @andymatuschak Fixes Bug #312381: "Bundles can't ask for permission to update; devel…
andymatuschak authored
95 - (void)startUpdateCycle
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
96 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
97 BOOL shouldPrompt = NO;
98
99 // If the user has been asked about automatic checks, don't bother prompting
100 if ([host objectForUserDefaultsKey:SUEnableAutomaticChecksKey])
101 {
102 shouldPrompt = NO;
103 }
104 // Does the delegate want to take care of the logic for when we should ask permission to update?
b3f3944 @andymatuschak Fixes 244857
andymatuschak authored
105 else if ([delegate respondsToSelector:@selector(updaterShouldPromptForPermissionToCheckForUpdates:)])
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
106 {
b3f3944 @andymatuschak Fixes 244857
andymatuschak authored
107 shouldPrompt = [delegate updaterShouldPromptForPermissionToCheckForUpdates:self];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
108 }
109 // Has he been asked already? And don't ask if the host has a default value set in its Info.plist.
5b38483 @andymatuschak Fixes 245723
andymatuschak authored
110 else if ([host objectForKey:SUEnableAutomaticChecksKey] == nil)
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
111 {
112 if ([host objectForUserDefaultsKey:SUEnableAutomaticChecksKeyOld])
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
113 [self setAutomaticallyChecksForUpdates:[host boolForUserDefaultsKey:SUEnableAutomaticChecksKeyOld]];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
114 // Now, we don't want to ask the user for permission to do a weird thing on the first launch.
115 // We wait until the second launch.
116 else if ([host boolForUserDefaultsKey:SUHasLaunchedBeforeKey] == NO)
117 [host setBool:YES forUserDefaultsKey:SUHasLaunchedBeforeKey];
118 else
119 shouldPrompt = YES;
120 }
121
122 if (shouldPrompt)
123 {
4da902b @andymatuschak Fixes 251968
andymatuschak authored
124 NSArray *profileInfo = [host systemProfile];
f95cf64 @andymatuschak A little cleanup on bricooke's patch.
andymatuschak authored
125 // Always say we're sending the system profile here so that the delegate displays the parameters it would send.
827c6ad when about to show the user what will be anonymously sent, make sure …
Brian Cooke authored
126 if ([delegate respondsToSelector:@selector(feedParametersForUpdater:sendingSystemProfile:)])
127 profileInfo = [profileInfo arrayByAddingObjectsFromArray:[delegate feedParametersForUpdater:self sendingSystemProfile:YES]];
4da902b @andymatuschak Fixes 251968
andymatuschak authored
128 [SUUpdatePermissionPrompt promptWithHost:host systemProfile:profileInfo delegate:self];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
129 // 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
130 }
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
131 else
132 {
133 // We check if the user's said they want updates, or they haven't said anything, and the default is set to checking.
134 [self scheduleNextUpdateCheck];
135 }
8c3960f Finished integrating SparklePlus profiling! Just set SUEnableSystemPr…
andym authored
136 }
137
138 - (void)updatePermissionPromptFinishedWithResult:(SUPermissionPromptResult)result
139 {
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
140 [self setAutomaticallyChecksForUpdates:(result == SUAutomaticallyCheck)];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
141 // Schedule checks, but make sure we ignore the delayed call from KVO
ac4e4e4 @andymatuschak Fixes 245991
andymatuschak authored
142 [self resetUpdateCycle];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
143 }
144
145 - (void)updateDriverDidFinish:(NSNotification *)note
146 {
147 if ([note object] == driver && [driver finished])
148 {
149 [driver release]; driver = nil;
150 [self scheduleNextUpdateCheck];
151 }
8c3960f Finished integrating SparklePlus profiling! Just set SUEnableSystemPr…
andym authored
152 }
153
42cda2d @andymatuschak Fixes 259062
andymatuschak authored
154 - (NSDate *)lastUpdateCheckDate
c71bf3c Provide getter for SULastCheckTimeKey
Peter Speck authored
155 {
156 return [host objectForUserDefaultsKey:SULastCheckTimeKey];
157 }
158
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
159 - (void)scheduleNextUpdateCheck
ebb1f01 @andymatuschak Removed the checkInterval IV and factored out its assignment to a che…
andymatuschak authored
160 {
4b6fc55 @andymatuschak Removed unnecessary @synchronized's.
andymatuschak authored
161 if (checkTimer)
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
162 {
4b6fc55 @andymatuschak Removed unnecessary @synchronized's.
andymatuschak authored
163 [checkTimer invalidate];
164 checkTimer = nil;
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
165 }
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
166 if (![self automaticallyChecksForUpdates]) return;
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
167
8c3960f Finished integrating SparklePlus profiling! Just set SUEnableSystemPr…
andym authored
168 // How long has it been since last we checked for an update?
c71bf3c Provide getter for SULastCheckTimeKey
Peter Speck authored
169 NSDate *lastCheckDate = [self lastUpdateCheckDate];
8c3960f Finished integrating SparklePlus profiling! Just set SUEnableSystemPr…
andym authored
170 if (!lastCheckDate) { lastCheckDate = [NSDate distantPast]; }
171 NSTimeInterval intervalSinceCheck = [[NSDate date] timeIntervalSinceDate:lastCheckDate];
172
173 // Now we want to figure out how long until we check again.
c21e1ab @andymatuschak Fixes 258529 and 257967
andymatuschak authored
174 NSTimeInterval delayUntilCheck, updateCheckInterval = [self updateCheckInterval];
175 if (updateCheckInterval < SU_MIN_CHECK_INTERVAL)
176 updateCheckInterval = SU_MIN_CHECK_INTERVAL;
177 if (intervalSinceCheck < updateCheckInterval)
178 delayUntilCheck = (updateCheckInterval - intervalSinceCheck); // It hasn't been long enough.
8c3960f Finished integrating SparklePlus profiling! Just set SUEnableSystemPr…
andym authored
179 else
180 delayUntilCheck = 0; // We're overdue! Run one now.
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
181 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
182 }
183
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
184 - (void)checkForUpdatesInBackground
dc147ec Continued incremental refactoring; things seem to still be holding to…
andym authored
185 {
9b5b541 Fix for Sparkle crasher in scheduleNextUpdateCheck. Originally by lap…
Simone Manganelli authored
186 checkTimer = nil; // Timer doesn't repeat, so it's invalid, just needs to be set to nil.
187
ec7f38d @andymatuschak Fixes 258547
andymatuschak authored
188 [self checkForUpdatesWithDriver:[[[([self automaticallyDownloadsUpdates] ? [SUAutomaticUpdateDriver class] : [SUScheduledUpdateDriver class]) alloc] initWithUpdater:self] autorelease]];
dc147ec Continued incremental refactoring; things seem to still be holding to…
andym authored
189 }
190
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
191 - (IBAction)checkForUpdates:sender
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
192 {
7b39268 @andymatuschak No longer fragile-ly using class method singletons to get to the upda…
andymatuschak authored
193 [self checkForUpdatesWithDriver:[[[SUUserInitiatedUpdateDriver alloc] initWithUpdater:self] autorelease]];
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
194 }
195
f815eec @andymatuschak Fixes 243884
andymatuschak authored
196 - (void)checkForUpdateInformation
197 {
7b39268 @andymatuschak No longer fragile-ly using class method singletons to get to the upda…
andymatuschak authored
198 [self checkForUpdatesWithDriver:[[[SUProbingUpdateDriver alloc] initWithUpdater:self] autorelease]];
f815eec @andymatuschak Fixes 243884
andymatuschak authored
199 }
200
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
201 - (void)checkForUpdatesWithDriver:(SUUpdateDriver *)d
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
202 {
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
203 if ([self updateInProgress]) { return; }
4b6fc55 @andymatuschak Removed unnecessary @synchronized's.
andymatuschak authored
204 if (checkTimer) { [checkTimer invalidate]; checkTimer = nil; }
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
205
42cda2d @andymatuschak Fixes 259062
andymatuschak authored
206 [self willChangeValueForKey:@"lastUpdateCheckDate"];
207 [host setObject:[NSDate date] forUserDefaultsKey:SULastCheckTimeKey];
208 [self didChangeValueForKey:@"lastUpdateCheckDate"];
209
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
210 driver = [d retain];
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
211 [driver checkForUpdatesAtURL:[self parameterizedFeedURL] host:host];
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
212 }
213
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
214 - (void)registerAsObserver
6a7c8b3 Substantial changes made to how Sparkle works on startup now. SUCheck…
andym authored
215 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
216 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateDriverDidFinish:) name:SUUpdateDriverFinishedNotification object:nil];
217 [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:[@"values." stringByAppendingString:SUScheduledCheckIntervalKey] options:0 context:SUUpdaterDefaultsObservationContext];
218 [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:[@"values." stringByAppendingString:SUEnableAutomaticChecksKey] options:0 context:SUUpdaterDefaultsObservationContext];
219 }
220
221 - (void)unregisterAsObserver
222 {
223 @try
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
224 {
fba7231 @andymatuschak We used to not register SUUpdater as an observer of the shared user d…
andymatuschak authored
225 [[NSNotificationCenter defaultCenter] removeObserver:self];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
226 [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:[@"values." stringByAppendingString:SUScheduledCheckIntervalKey]];
227 [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:[@"values." stringByAppendingString:SUEnableAutomaticChecksKey]];
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
228 }
fba7231 @andymatuschak We used to not register SUUpdater as an observer of the shared user d…
andymatuschak authored
229 @catch (NSException *e)
230 {
231 NSLog(@"Sparkle Error: [SUUpdater unregisterAsObserver] called, but the updater wasn't registered as an observer.");
232 }
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
233 }
234
235 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
236 {
237 if (context == SUUpdaterDefaultsObservationContext)
238 {
239 // 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.
240 // 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
241 [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetUpdateCycle) object:nil];
f9dda21 @andymatuschak Fixes 255399
andymatuschak authored
242 [self performSelector:@selector(resetUpdateCycle) withObject:nil afterDelay:1];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
243 }
244 else
245 {
246 [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
247 }
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
248 }
249
ac4e4e4 @andymatuschak Fixes 245991
andymatuschak authored
250 - (void)resetUpdateCycle
a55f11d @andymatuschak Fixed 236240
andymatuschak authored
251 {
ac4e4e4 @andymatuschak Fixes 245991
andymatuschak authored
252 [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetUpdateCycle) object:nil];
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
253 [self scheduleNextUpdateCheck];
1c1bb3a #77 SUIgnoreChecks to ignore update, needed for Sparkle in large depl…
catlan authored
254 }
255
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
256 - (void)setAutomaticallyChecksForUpdates:(BOOL)automaticallyCheckForUpdates
257 {
258 [host setBool:automaticallyCheckForUpdates forUserDefaultsKey:SUEnableAutomaticChecksKey];
c21e1ab @andymatuschak Fixes 258529 and 257967
andymatuschak authored
259 // Hack to support backwards compatibility with older Sparkle versions, which supported
260 // disabling updates by setting the check interval to 0.
261 if (automaticallyCheckForUpdates && [self updateCheckInterval] == 0)
262 [self setUpdateCheckInterval:SU_DEFAULT_CHECK_INTERVAL];
263 [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetUpdateCycle) object:nil];
264 // Provide a small delay in case multiple preferences are being updated simultaneously.
265 [self performSelector:@selector(resetUpdateCycle) withObject:nil afterDelay:1];
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
266 }
267
268 - (BOOL)automaticallyChecksForUpdates
49cfd57 @andymatuschak Fixed a confounding bug that somehow slipped in: when an update check…
andymatuschak authored
269 {
c21e1ab @andymatuschak Fixes 258529 and 257967
andymatuschak authored
270 // Don't automatically update when the check interval is 0, to be compatible with 1.1 settings.
271 if ([self updateCheckInterval] == 0)
272 return NO;
ec7f38d @andymatuschak Fixes 258547
andymatuschak authored
273 return [host boolForKey:SUEnableAutomaticChecksKey];
49cfd57 @andymatuschak Fixed a confounding bug that somehow slipped in: when an update check…
andymatuschak authored
274 }
275
ec7f38d @andymatuschak Fixes 258547
andymatuschak authored
276 - (void)setAutomaticallyDownloadsUpdates:(BOOL)automaticallyUpdates
277 {
278 [host setBool:automaticallyUpdates forUserDefaultsKey:SUAutomaticallyUpdateKey];
279 }
280
281 - (BOOL)automaticallyDownloadsUpdates
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
282 {
283 // 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
284 if ([host objectForInfoDictionaryKey:SUAllowsAutomaticUpdatesKey] && [host boolForInfoDictionaryKey:SUAllowsAutomaticUpdatesKey] == NO)
6a7c8b3 Substantial changes made to how Sparkle works on startup now. SUCheck…
andym authored
285 return NO;
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
286
ec7f38d @andymatuschak Fixes 258547
andymatuschak authored
287 // Otherwise, automatically downloading updates is allowed. Does the user want it?
288 return [host boolForUserDefaultsKey:SUAutomaticallyUpdateKey];
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
289 }
290
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
291 - (void)setFeedURL:(NSURL *)feedURL
292 {
293 [host setObject:[feedURL absoluteString] forUserDefaultsKey:SUFeedURLKey];
294 }
295
296 - (NSURL *)feedURL
645a96e Made a good deal more progress integrating the profile checking featu…
andym authored
297 {
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
298 // 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).
5b38483 @andymatuschak Fixes 245723
andymatuschak authored
299 NSString *appcastString = [host objectForKey:SUFeedURLKey];
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
300 if (!appcastString) // Can't find an appcast string!
ffc44bb @fspeirs Added a space in the description of the SUNoFeedURL exception becuase…
fspeirs authored
301 [NSException raise:@"SUNoFeedURL" format:@"You must specify the URL of the appcast as the SUFeedURL key in either the Info.plist or the user defaults!"];
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
302 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
303 return [NSURL URLWithString:[appcastString stringByTrimmingCharactersInSet:quoteSet]];
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
304 }
305
dfe0eff Provide the ability to set a custom user agent string on all HTTP req…
Mark Rowe authored
306 - (void)setUserAgentString:(NSString *)userAgent
307 {
308 if (customUserAgentString == userAgent)
309 return;
310
311 [customUserAgentString release];
312 customUserAgentString = [userAgent copy];
313 }
314
315 - (NSString *)userAgentString
316 {
317 if (customUserAgentString)
318 return customUserAgentString;
319
a032358 @andymatuschak Removing GNU-style ?: operators. Thanks for the report, Uli.
andymatuschak authored
320 NSString *version = [SPARKLE_BUNDLE objectForInfoDictionaryKey:@"CFBundleVersion"];
321 NSString *userAgent = [NSString stringWithFormat:@"%@/%@ Sparkle/%@", [host name], [host displayVersion], version ? version : @"?"];
dfe0eff Provide the ability to set a custom user agent string on all HTTP req…
Mark Rowe authored
322 NSData *cleanedAgent = [userAgent dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
323 return [[[NSString alloc] initWithData:cleanedAgent encoding:NSASCIIStringEncoding] autorelease];
324 }
325
ec7f38d @andymatuschak Fixes 258547
andymatuschak authored
326 - (void)setSendsSystemProfile:(BOOL)sendsSystemProfile
327 {
328 [host setBool:sendsSystemProfile forUserDefaultsKey:SUSendProfileInfoKey];
329 }
330
331 - (BOOL)sendsSystemProfile
4da902b @andymatuschak Fixes 251968
andymatuschak authored
332 {
ec7f38d @andymatuschak Fixes 258547
andymatuschak authored
333 return [host boolForUserDefaultsKey:SUSendProfileInfoKey];
4da902b @andymatuschak Fixes 251968
andymatuschak authored
334 }
335
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
336 - (NSURL *)parameterizedFeedURL
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
337 {
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
338 NSURL *baseFeedURL = [self feedURL];
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
339
340 // Determine all the parameters we're attaching to the base feed URL.
ec7f38d @andymatuschak Fixes 258547
andymatuschak authored
341 BOOL sendingSystemProfile = [self sendsSystemProfile];
e3226d3 A cleaned up and tested version of the one-submit-per-week code
David Smith authored
342
d1c0978 @andymatuschak As discussed in https://bugs.launchpad.net/sparkle/+bug/243884/commen…
andymatuschak authored
343 // 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
344 NSDate *lastSubmitDate = [host objectForUserDefaultsKey:SULastProfileSubmitDateKey];
345 if(!lastSubmitDate)
346 lastSubmitDate = [NSDate distantPast];
d1c0978 @andymatuschak As discussed in https://bugs.launchpad.net/sparkle/+bug/243884/commen…
andymatuschak authored
347 const NSTimeInterval oneWeek = 60 * 60 * 24 * 7;
348 sendingSystemProfile &= (-[lastSubmitDate timeIntervalSinceNow] >= oneWeek);
e3226d3 A cleaned up and tested version of the one-submit-per-week code
David Smith authored
349
645a96e Made a good deal more progress integrating the profile checking featu…
andym authored
350 NSArray *parameters = [NSArray array];
b3f3944 @andymatuschak Fixes 244857
andymatuschak authored
351 if ([delegate respondsToSelector:@selector(feedParametersForUpdater:sendingSystemProfile:)])
352 parameters = [parameters arrayByAddingObjectsFromArray:[delegate feedParametersForUpdater:self sendingSystemProfile:sendingSystemProfile]];
645a96e Made a good deal more progress integrating the profile checking featu…
andym authored
353 if (sendingSystemProfile)
d1c0978 @andymatuschak As discussed in https://bugs.launchpad.net/sparkle/+bug/243884/commen…
andymatuschak authored
354 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
355 parameters = [parameters arrayByAddingObjectsFromArray:[host systemProfile]];
d1c0978 @andymatuschak As discussed in https://bugs.launchpad.net/sparkle/+bug/243884/commen…
andymatuschak authored
356 [host setObject:[NSDate date] forUserDefaultsKey:SULastProfileSubmitDateKey];
357 }
d7774c0 performed a code review, specifically:
Sean McBride authored
358 if ([parameters count] == 0) { return baseFeedURL; }
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
359
360 // Build up the parameterized URL.
361 NSMutableArray *parameterStrings = [NSMutableArray array];
362 NSEnumerator *profileInfoEnumerator = [parameters objectEnumerator];
363 NSDictionary *currentProfileInfo;
364 while ((currentProfileInfo = [profileInfoEnumerator nextObject]))
2768e60 Properly escapes the GET parameters in the appcast string with profile.
Lukhnos D. Liu authored
365 [parameterStrings addObject:[NSString stringWithFormat:@"%@=%@", [[[currentProfileInfo objectForKey:@"key"] description] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], [[[currentProfileInfo objectForKey:@"value"] description] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
366
68e2cd6 @andymatuschak Fixes 258492
andymatuschak authored
367 NSString *separatorCharacter = @"?";
368 if ([baseFeedURL query])
369 separatorCharacter = @"&"; // In case the URL is already http://foo.org/baz.xml?bat=4
444b0a9 @andymatuschak Fixed a stupid mistake that prevented my fix for parameterized URLs f…
andymatuschak authored
370 NSString *appcastStringWithProfile = [NSString stringWithFormat:@"%@%@%@", [baseFeedURL absoluteString], separatorCharacter, [parameterStrings componentsJoinedByString:@"&"]];
b2145b6 @andymatuschak Killed NSURL+Parameters and moved the relevant code into SUUpdater.
andymatuschak authored
371
372 // Clean it up so it's a valid URL
2768e60 Properly escapes the GET parameters in the appcast string with profile.
Lukhnos D. Liu authored
373 return [NSURL URLWithString:appcastStringWithProfile];
645a96e Made a good deal more progress integrating the profile checking featu…
andym authored
374 }
375
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
376 - (void)setUpdateCheckInterval:(NSTimeInterval)updateCheckInterval
377 {
378 [host setObject:[NSNumber numberWithDouble:updateCheckInterval] forUserDefaultsKey:SUScheduledCheckIntervalKey];
c21e1ab @andymatuschak Fixes 258529 and 257967
andymatuschak authored
379 if (updateCheckInterval == 0) // For compatibility with 1.1's settings.
380 [self setAutomaticallyChecksForUpdates:NO];
381 [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetUpdateCycle) object:nil];
382
383 // Provide a small delay in case multiple preferences are being updated simultaneously.
384 [self performSelector:@selector(resetUpdateCycle) withObject:nil afterDelay:1];
1aea1b6 @andymatuschak The Sparkle preference keys are now declared private / deprecated / a…
andymatuschak authored
385 }
386
387 - (NSTimeInterval)updateCheckInterval
ebb1f01 @andymatuschak Removed the checkInterval IV and factored out its assignment to a che…
andymatuschak authored
388 {
389 // Find the stored check interval. User defaults override Info.plist.
c21e1ab @andymatuschak Fixes 258529 and 257967
andymatuschak authored
390 NSNumber *intervalValue = [host objectForKey:SUScheduledCheckIntervalKey];
391 if (intervalValue)
392 return [intervalValue doubleValue];
393 else
394 return SU_DEFAULT_CHECK_INTERVAL;
ebb1f01 @andymatuschak Removed the checkInterval IV and factored out its assignment to a che…
andymatuschak authored
395 }
396
bbedfa1 Reorganized SUUpdater.m; it's in better order now.
andym authored
397 - (void)dealloc
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
398 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
399 [self unregisterAsObserver];
400 [host release];
bbedfa1 Reorganized SUUpdater.m; it's in better order now.
andym authored
401 if (checkTimer) { [checkTimer invalidate]; }
402 [super dealloc];
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
403 }
404
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
405 - (BOOL)validateMenuItem:(NSMenuItem *)item
66bbbed Restored 10.3.9 compatibility to the system version method.
andym authored
406 {
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
407 if ([item action] == @selector(checkForUpdates:))
408 return ![self updateInProgress];
409 return YES;
66bbbed Restored 10.3.9 compatibility to the system version method.
andym authored
410 }
411
645a96e Made a good deal more progress integrating the profile checking featu…
andym authored
412 - (void)setDelegate:aDelegate
413 {
cd4addb @andymatuschak Fixes 239512
andymatuschak authored
414 delegate = aDelegate;
645a96e Made a good deal more progress integrating the profile checking featu…
andym authored
415 }
416
bc3be9a Touched practically every line of code in a super-monster-awesome ref…
andym authored
417 - (BOOL)updateInProgress
418 {
419 return driver && ([driver finished] == NO);
420 }
421
b3f3944 @andymatuschak Fixes 244857
andymatuschak authored
422 - delegate { return delegate; }
423 - (NSBundle *)hostBundle { return [host bundle]; }
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
424
9fa3da5 Holy restructuring, batman! Watch out for falling folders.
andym authored
425 @end
Something went wrong with that request. Please try again.