1919import AppKit
2020import Foundation
2121
22- public protocol AppInfoRetrieveing {
22+ /// Protocol to provide a mechanism to query information about installed Applications.
23+ ///
24+ public protocol AppInfoRetrieving {
2325
24- /// Provides a structure featuring commonly-used app info.
26+ /// Provides a structure featuring commonly-used app info given the Application's bundleID .
2527 ///
26- /// It's also possible to retrieve the individual information directly by calling other methods in this class.
28+ /// - Parameters:
29+ /// - bundleID: the bundleID of the target Application.
2730 ///
2831 func getAppInfo ( bundleID : String ) -> AppInfo ?
32+
33+ /// Provides a structure featuring commonly-used app info, given the Application's URL.
34+ ///
35+ /// - Parameters:
36+ /// - appURL: the URL where the target Application is installed.
37+ ///
2938 func getAppInfo ( appURL : URL ) -> AppInfo ?
39+
40+ /// Obtains the icon for a specified application.
41+ ///
42+ /// - Parameters:
43+ /// - bundleID: the bundleID of the target Application.
44+ ///
3045 func getAppIcon ( bundleID : String ) -> NSImage ?
46+
47+ /// Obtains the URL for a specified application.
48+ ///
49+ /// - Parameters:
50+ /// - bundleID: the bundleID of the target Application.
51+ ///
52+ func getAppURL ( bundleID : String ) -> URL ?
53+
54+ /// Obtains the visible name for a specified application.
55+ ///
56+ /// - Parameters:
57+ /// - bundleID: the bundleID of the target Application.
58+ ///
3159 func getAppName ( bundleID : String ) -> String ?
60+
61+ /// Obtains the bundleID for a specified application.
62+ ///
63+ /// - Parameters:
64+ /// - appURL: the URL where the target Application is installed.
65+ ///
3266 func getBundleID ( appURL : URL ) -> String ?
3367
68+ /// Obtains the bundleIDs for all Applications embedded within a speciried application.
69+ ///
70+ /// - Parameters:
71+ /// - bundleURL: the URL where the parent Application is installed.
72+ ///
73+ func findEmbeddedBundleIDs ( in bundleURL : URL ) -> Set < String >
3474}
3575
36- public class AppInfoRetriever : AppInfoRetrieveing {
76+ /// Provides a mechanism to query information about installed Applications.
77+ ///
78+ public class AppInfoRetriever : AppInfoRetrieving {
3779
3880 public init ( ) { }
3981
82+ /// Provides a structure featuring commonly-used app info given the Application's bundleID.
83+ ///
84+ /// - Parameters:
85+ /// - bundleID: the bundleID of the target Application.
86+ ///
4087 public func getAppInfo ( bundleID : String ) -> AppInfo ? {
4188 guard let appName = getAppName ( bundleID : bundleID ) else {
4289 return nil
@@ -46,6 +93,11 @@ public class AppInfoRetriever: AppInfoRetrieveing {
4693 return AppInfo ( bundleID : bundleID , name : appName , icon : appIcon )
4794 }
4895
96+ /// Provides a structure featuring commonly-used app info, given the Application's URL.
97+ ///
98+ /// - Parameters:
99+ /// - appURL: the URL where the target Application is installed.
100+ ///
49101 public func getAppInfo ( appURL : URL ) -> AppInfo ? {
50102 guard let bundleID = getBundleID ( appURL : appURL ) else {
51103 return nil
@@ -54,6 +106,11 @@ public class AppInfoRetriever: AppInfoRetrieveing {
54106 return getAppInfo ( bundleID : bundleID )
55107 }
56108
109+ /// Obtains the icon for a specified application.
110+ ///
111+ /// - Parameters:
112+ /// - bundleID: the bundleID of the target Application.
113+ ///
57114 public func getAppIcon ( bundleID : String ) -> NSImage ? {
58115 guard let appURL = NSWorkspace . shared . urlForApplication ( withBundleIdentifier : bundleID ) else {
59116 return nil
@@ -72,6 +129,11 @@ public class AppInfoRetriever: AppInfoRetrieveing {
72129 return NSImage ( contentsOf : iconURL )
73130 }
74131
132+ /// Obtains the visible name for a specified application.
133+ ///
134+ /// - Parameters:
135+ /// - bundleID: the bundleID of the target Application.
136+ ///
75137 public func getAppName ( bundleID : String ) -> String ? {
76138 if let appURL = NSWorkspace . shared . urlForApplication ( withBundleIdentifier : bundleID ) {
77139 // Try reading from Info.plist
@@ -86,6 +148,20 @@ public class AppInfoRetriever: AppInfoRetrieveing {
86148 return nil
87149 }
88150
151+ /// Obtains the URL for a specified application.
152+ ///
153+ /// - Parameters:
154+ /// - bundleID: the bundleID of the target Application.
155+ ///
156+ public func getAppURL ( bundleID : String ) -> URL ? {
157+ NSWorkspace . shared . urlForApplication ( withBundleIdentifier : bundleID )
158+ }
159+
160+ /// Obtains the bundleID for a specified application.
161+ ///
162+ /// - Parameters:
163+ /// - appURL: the URL where the target Application is installed.
164+ ///
89165 public func getBundleID ( appURL : URL ) -> String ? {
90166 let infoPlistURL = appURL . appendingPathComponent ( " Contents/Info.plist " )
91167 if let plist = NSDictionary ( contentsOf : infoPlistURL ) ,
@@ -94,4 +170,32 @@ public class AppInfoRetriever: AppInfoRetrieveing {
94170 }
95171 return nil
96172 }
173+
174+ // MARK: - Embedded Bundle IDs
175+
176+ /// Obtains the bundleIDs for all Applications embedded within a speciried application.
177+ ///
178+ /// - Parameters:
179+ /// - bundleURL: the URL where the parent Application is installed.
180+ ///
181+ public func findEmbeddedBundleIDs ( in bundleURL : URL ) -> Set < String > {
182+ var bundleIDs : [ String ] = [ ]
183+ let fileManager = FileManager . default
184+
185+ guard let enumerator = fileManager . enumerator ( at : bundleURL ,
186+ includingPropertiesForKeys : nil ,
187+ options : [ . skipsHiddenFiles ] ,
188+ errorHandler : nil ) else {
189+ return [ ]
190+ }
191+
192+ for case let fileURL as URL in enumerator where fileURL . pathExtension == " app " {
193+ let embeddedBundle = Bundle ( url : fileURL )
194+ if let bundleID = embeddedBundle ? . bundleIdentifier {
195+ bundleIDs . append ( bundleID )
196+ }
197+ }
198+
199+ return Set ( bundleIDs )
200+ }
97201}
0 commit comments