Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 198 lines (171 sloc) 6.83 kB
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
1 //
2 // SUHost.m
3 // Sparkle
4 //
5 // Copyright 2008 Andy Matuschak. All rights reserved.
6 //
7
8 #import "Sparkle.h"
3146ffb @andymatuschak Fixes 248929, 244738
andymatuschak authored
9 #import <sys/mount.h> // For statfs for isRunningOnReadOnlyVolume
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
10
11 @implementation SUHost
12
13 - (id)initWithBundle:(NSBundle *)aBundle
14 {
15 if (aBundle == nil) aBundle = [NSBundle mainBundle];
16 if ((self = [super init]))
17 {
18 bundle = [aBundle retain];
19 }
20 return self;
21 }
22
23 - (void)dealloc
24 {
25 [bundle release];
26 [super dealloc];
27 }
28
29 - (NSBundle *)bundle
30 {
31 return bundle;
32 }
33
34 - (NSString *)bundlePath
35 {
36 return [bundle bundlePath];
37 }
38
39 - (NSString *)name
40 {
41 NSString *name = [bundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
42 if (name) return name;
43
44 name = [self objectForInfoDictionaryKey:@"CFBundleName"];
45 if (name) return name;
46
47 return [[[NSFileManager defaultManager] displayNameAtPath:[bundle bundlePath]] stringByDeletingPathExtension];
48 }
49
50 - (NSString *)version
51 {
52 return [bundle objectForInfoDictionaryKey:@"CFBundleVersion"];
53 }
54
55 - (NSString *)displayVersion
56 {
57 NSString *shortVersionString = [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
58 if (shortVersionString)
59 return shortVersionString;
60 else
61 return [self version]; // Fall back on the normal version string.
62 }
63
64 - (NSImage *)icon
65 {
66 // Cache the application icon.
67 NSString *iconPath = [bundle pathForResource:[bundle objectForInfoDictionaryKey:@"CFBundleIconFile"] ofType:@"icns"];
68 // According to the OS X docs, "CFBundleIconFile - This key identifies the file containing
69 // the icon for the bundle. The filename you specify does not need to include the .icns
70 // extension, although it may."
71 //
72 // However, if it *does* include the '.icns' the above method fails (tested on OS X 10.3.9) so we'll also try:
73 if (!iconPath)
74 iconPath = [bundle pathForResource:[bundle objectForInfoDictionaryKey:@"CFBundleIconFile"] ofType: nil];
75 NSImage *icon = [[[NSImage alloc] initWithContentsOfFile:iconPath] autorelease];
76 // Use a default icon if none is defined.
77 if (!icon) { icon = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericApplicationIcon)]; }
78 return icon;
79 }
80
3146ffb @andymatuschak Fixes 248929, 244738
andymatuschak authored
81 - (BOOL)isRunningOnReadOnlyVolume
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
82 {
3146ffb @andymatuschak Fixes 248929, 244738
andymatuschak authored
83 struct statfs statfs_info;
84 statfs([[bundle bundlePath] fileSystemRepresentation], &statfs_info);
85 return (statfs_info.f_flags & MNT_RDONLY);
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
86 }
87
c42e3a3 @andymatuschak Fixed 251010
andymatuschak authored
88 - (BOOL)isBackgroundApplication
89 {
90 return [[bundle objectForInfoDictionaryKey:@"LSUIElement"] doubleValue];
91 }
92
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
93 - (NSString *)publicDSAKey
94 {
95 // Maybe the key is just a string in the Info.plist.
96 NSString *key = [bundle objectForInfoDictionaryKey:SUPublicDSAKeyKey];
97 if (key) { return key; }
98
99 // More likely, we've got a reference to a Resources file by filename:
100 NSString *keyFilename = [self objectForInfoDictionaryKey:SUPublicDSAKeyFileKey];
101 if (!keyFilename) { return nil; }
102 return [NSString stringWithContentsOfFile:[bundle pathForResource:keyFilename ofType:nil]];
103 }
104
105 - (NSArray *)systemProfile
106 {
107 return [[SUSystemProfiler sharedSystemProfiler] systemProfileArrayForHost:self];
108 }
109
110 - (id)objectForInfoDictionaryKey:(NSString *)key
111 {
112 return [bundle objectForInfoDictionaryKey:key];
113 }
114
115 - (BOOL)boolForInfoDictionaryKey:(NSString *)key
116 {
117 return [[self objectForInfoDictionaryKey:key] boolValue];
118 }
119
120 - (id)objectForUserDefaultsKey:(NSString *)defaultName
121 {
122 CFPropertyListRef obj = CFPreferencesCopyAppValue((CFStringRef)defaultName, (CFStringRef)[bundle bundleIdentifier]);
123 // Under Tiger, CFPreferencesCopyAppValue doesn't get values from NSRegistratioDomain, so anything
124 // passed into -[NSUserDefaults registerDefaults:] is ignored. The following line falls
125 // back to using NSUserDefaults, but only if the host bundle is the main bundle, and no value
126 // is found elsewhere.
127 if (obj == NULL && bundle != [NSBundle mainBundle])
128 obj = [[NSUserDefaults standardUserDefaults] objectForKey:defaultName];
129 #if MAC_OS_X_VERSION_MIN_REQUIRED > 1050
130 return [NSMakeCollectable(obj) autorelease];
131 #else
132 return [(id)obj autorelease];
133 #endif
134 }
135
136 - (void)setObject:(id)value forUserDefaultsKey:(NSString *)defaultName;
137 {
138 CFPreferencesSetValue((CFStringRef)defaultName, value, (CFStringRef)[bundle bundleIdentifier], kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
139 CFPreferencesSynchronize((CFStringRef)[bundle bundleIdentifier], kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
140 // If anything's bound to this through an NSUserDefaultsController, it won't know that anything's changed.
141 // We can't get an NSUserDefaults object for anything other than the standard one for the app, so this won't work for bundles.
142 // But it's the best we can do: this will make NSUserDefaultsControllers know about the changes that have been made.
143 [[NSUserDefaults standardUserDefaults] synchronize];
144 }
145
146 - (BOOL)boolForUserDefaultsKey:(NSString *)defaultName
147 {
a31dc3a @andymatuschak Fixes BOOL user defaults lookup for registered defaults on Tiger.
andymatuschak authored
148 if (bundle == [NSBundle mainBundle])
149 return [[NSUserDefaults standardUserDefaults] boolForKey:defaultName];
150
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
151 BOOL value;
152 CFPropertyListRef plr = CFPreferencesCopyAppValue((CFStringRef)defaultName, (CFStringRef)[bundle bundleIdentifier]);
153 if (plr == NULL)
154 value = NO;
a31dc3a @andymatuschak Fixes BOOL user defaults lookup for registered defaults on Tiger.
andymatuschak authored
155 else
156 {
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
157 value = (BOOL)CFBooleanGetValue((CFBooleanRef)plr);
158 CFRelease(plr);
159 }
160 return value;
161 }
162
163 - (void)setBool:(BOOL)value forUserDefaultsKey:(NSString *)defaultName
164 {
165 CFPreferencesSetValue((CFStringRef)defaultName, (CFBooleanRef)[NSNumber numberWithBool:value], (CFStringRef)[bundle bundleIdentifier], kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
166 CFPreferencesSynchronize((CFStringRef)[bundle bundleIdentifier], kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
167 // If anything's bound to this through an NSUserDefaultsController, it won't know that anything's changed.
168 // We can't get an NSUserDefaults object for anything other than the standard one for the app, so this won't work for bundles.
169 // But it's the best we can do: this will make NSUserDefaultsControllers know about the changes that have been made.
170 [[NSUserDefaults standardUserDefaults] synchronize];
171 }
172
de9be8b @andymatuschak Fixes 244428
andymatuschak authored
173 + (NSString *)systemVersionString
174 {
175 // This returns a version string of the form X.Y.Z
176 // There may be a better way to deal with the problem that gestaltSystemVersionMajor
177 // et al. are not defined in 10.3, but this is probably good enough.
178 NSString* verStr = nil;
179 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4
180 SInt32 major, minor, bugfix;
181 OSErr err1 = Gestalt(gestaltSystemVersionMajor, &major);
182 OSErr err2 = Gestalt(gestaltSystemVersionMinor, &minor);
183 OSErr err3 = Gestalt(gestaltSystemVersionBugFix, &bugfix);
184 if (!err1 && !err2 && !err3)
185 {
186 verStr = [NSString stringWithFormat:@"%d.%d.%d", major, minor, bugfix];
187 }
188 else
189 #endif
190 {
191 NSString *versionPlistPath = @"/System/Library/CoreServices/SystemVersion.plist";
192 verStr = [[[NSDictionary dictionaryWithContentsOfFile:versionPlistPath] objectForKey:@"ProductVersion"] retain];
193 }
194 return verStr;
195 }
196
98832c4 @andymatuschak Beginnings of insane SUHost-based refactoring to get rid of NSBundle+…
andymatuschak authored
197 @end
Something went wrong with that request. Please try again.