@@ -25,14 +25,17 @@ @implementation AppListNode
2525}
2626
2727
28- NSImage * kOSIcon , *kAppIcon , *kDbIcon ;
28+ NSImage * kiOSIcon, * kMacOSIcon , *kAppIcon , *kDbIcon ;
2929
3030
3131+ (void ) initialize {
3232 if (self == [AppListNode class ]) {
3333 NSString * simulatorPath = [[NSWorkspace sharedWorkspace ] absolutePathForAppBundleWithIdentifier: kSimulatorAppID ];
34- kOSIcon = [[[NSWorkspace sharedWorkspace ] iconForFile: simulatorPath] copy ];
35- kOSIcon .size = NSMakeSize (kIconSize , kIconSize );
34+ kiOSIcon = [[[NSWorkspace sharedWorkspace ] iconForFile: simulatorPath] copy ];
35+ kiOSIcon.size = NSMakeSize (kIconSize , kIconSize );
36+
37+ kMacOSIcon = [[[NSWorkspace sharedWorkspace ] iconForFile: @" /System/Library/CoreServices/Finder.app" ] copy ];
38+ kMacOSIcon .size = NSMakeSize (kIconSize , kIconSize );
3639
3740 kAppIcon = [[NSImage imageNamed: @" ios_app.png" ] copy ];
3841 kAppIcon .size = NSMakeSize (kIconSize , kIconSize );
@@ -43,6 +46,7 @@ + (void) initialize {
4346}
4447
4548@synthesize type=_type, path=_path, displayName=_displayName, children=_children;
49+ @synthesize isMacOS=_isMacOS;
4650
4751- (id ) initWithType : (AppListNodeType)type path : (NSString *)path displayName : (NSString *)displayName {
4852 self = [super init ];
@@ -58,7 +62,7 @@ - (id) initWithType: (AppListNodeType)type path: (NSString*)path displayName: (N
5862- (NSImage *) icon {
5963 switch (_type) {
6064 case kOSNode :
61- return kOSIcon ;
65+ return _isMacOS ? kMacOSIcon : kiOSIcon ;
6266 case kAppNode :
6367 if (!_appIcon)
6468 _appIcon = [self findAppIcon ] ?: kAppIcon ;
@@ -96,9 +100,9 @@ - (NSImage*) findAppIcon {
96100
97101
98102// Returns a dictionary mapping display-names -> absolute paths.
99- // Block is given an filename and returns a display-name or nil.
100- static NSDictionary * iterateDir (NSString * dir, NSError ** outError,
101- NSString * (^block)(NSString * filename))
103+ // Block is given a filename and returns a display-name or nil.
104+ static NSMutableDictionary * iterateDir (NSString * dir, NSError ** outError,
105+ NSString * (^block)(NSString * filename))
102106{
103107 NSArray * filenames = [[NSFileManager defaultManager ] contentsOfDirectoryAtPath: dir
104108 error: outError];
@@ -160,7 +164,7 @@ - (NSImage*) findAppIcon {
160164
161165static NSDictionary * findMacAppDirs (NSError ** error) {
162166 NSString * dirName = NSSearchPathForDirectoriesInDomains (NSApplicationSupportDirectory, NSUserDomainMask, YES )[0 ];
163- return iterateDir (dirName, error, ^NSString *(NSString *appDirName) {
167+ NSMutableDictionary * dirs = iterateDir (dirName, error, ^NSString *(NSString *appDirName) {
164168 NSString * appDirPath = [dirName stringByAppendingPathComponent: appDirName];
165169 NSString * cblPath = [appDirPath stringByAppendingPathComponent: kDbDirName ];
166170 BOOL isDir;
@@ -169,6 +173,29 @@ - (NSImage*) findAppIcon {
169173 return nil ;
170174 return [[appDirName componentsSeparatedByString: @" ." ] lastObject ];
171175 });
176+
177+ #if 1
178+ // Now look for sandboxed apps:
179+ dirName = NSSearchPathForDirectoriesInDomains (NSLibraryDirectory, NSUserDomainMask, YES )[0 ];
180+ dirName = [dirName stringByAppendingPathComponent: @" Containers" ];
181+
182+ NSArray * filenames = [[NSFileManager defaultManager ] contentsOfDirectoryAtPath: dirName
183+ error: NULL ];
184+ for (NSString * appDirName in filenames) {
185+ NSString * appDirPath = [[[dirName stringByAppendingPathComponent: appDirName]
186+ stringByAppendingPathComponent: @" Data/Library/Application Support" ]
187+ stringByAppendingPathComponent: appDirName];
188+ NSString * cblPath = [appDirPath stringByAppendingPathComponent: kDbDirName ];
189+ BOOL isDir;
190+ if ([[NSFileManager defaultManager ] fileExistsAtPath: cblPath isDirectory: &isDir]
191+ && isDir) {
192+ NSString * displayName = [[appDirName componentsSeparatedByString: @" ." ] lastObject ];
193+ dirs[displayName] = appDirPath;
194+ }
195+ }
196+ #endif
197+
198+ return dirs;
172199}
173200
174201
@@ -216,26 +243,27 @@ - (NSImage*) findAppIcon {
216243 [versNode.children addObject: appNode];
217244 }
218245 if (versNode.children .count > 0 )
219- [root.children addObject : versNode];
246+ [root.children insertObject : versNode atIndex: 0 ]; // reverse order (newest OS first)
220247 }
221248
222249 // Now find Mac apps:
223250 AppListNode* versNode = [[AppListNode alloc ] initWithType: kOSNode path: @" " displayName: @" Mac OS" ];
251+ versNode.isMacOS = YES ;
224252 NSDictionary * apps = findMacAppDirs (outError);
225253 if (!apps)
226254 return nil ;
227255 for (NSString * app in sortedKeys (apps)) {
228256 AppListNode* appNode = [[AppListNode alloc ] initWithType: kAppNode path: apps[app] displayName: app];
229257
230258 NSDictionary * dbs = findMacAppDatabases (apps[app], outError);
231- if (!dbs)
232- return nil ;
233- for (NSString * db in sortedKeys (dbs)) {
234- AppListNode* dbNode = [[AppListNode alloc ] initWithType: kDbNode path: dbs[db] displayName: db];
235- [appNode.children addObject: dbNode];
259+ if (dbs) {
260+ for (NSString * db in sortedKeys (dbs)) {
261+ AppListNode* dbNode = [[AppListNode alloc ] initWithType: kDbNode path: dbs[db] displayName: db];
262+ [appNode.children addObject: dbNode];
263+ }
264+ if (appNode.children .count > 0 )
265+ [versNode.children addObject: appNode];
236266 }
237- if (appNode.children .count > 0 )
238- [versNode.children addObject: appNode];
239267 }
240268 if (versNode.children .count > 0 )
241269 [root.children addObject: versNode];
0 commit comments