From bc1f93ea7cd97f2bdaafffa3812f8540cc5098ad Mon Sep 17 00:00:00 2001 From: Gregorio Litenstein Date: Fri, 3 Feb 2017 14:05:02 -0300 Subject: [PATCH] Implement getBundleID() Exhaustive function to get a valid Bundle ID for an application either by URL, by Path, by Bundle ID or by App display name. Outputs appropriate errors on failure. --- Sources/LSWrappers.swift | 76 +++++++++++++++++++++++++++++++++++++++ Sources/commonFuncs.swift | 12 +++++++ 2 files changed, 88 insertions(+) diff --git a/Sources/LSWrappers.swift b/Sources/LSWrappers.swift index 868cef6..394e11c 100644 --- a/Sources/LSWrappers.swift +++ b/Sources/LSWrappers.swift @@ -160,4 +160,80 @@ class LSWrappers { } } + func getBundleID (_ inParam: String, outBundleID: inout String?) -> OSStatus { + outBundleID = nil + var errCode = OSStatus() + let inURL: URL + let filemanager = FileManager.default + if (inParam == "None") { // None is a valid value to remove a handler, so we'll allow it. + outBundleID = inParam + return 0 + } + if let appPath = NSWorkspace.shared().absolutePathForApplication(withBundleIdentifier: inParam) { // Check whether we have a valid Bundle ID for an application. + outBundleID = inParam + return 0 + } + else if let appPath = NSWorkspace.shared().fullPath(forApplication: inParam) { // Or an application designed by name + if let bundle = Bundle(path:appPath) { + if let type = bundle.getType(outError: &errCode) { + if (type == "APPL") { + outBundleID = bundle.bundleIdentifier! + return 0 + } + else { return kLSNotAnApplicationErr } + } + else { return errCode } + } + if (filemanager.fileExists(atPath: inParam) == true) { return kLSNotAnApplicationErr } + else { return kLSApplicationNotFoundErr } + } + + else { + if let bundle = Bundle(path: inParam) { // Is it a valid bundle path? + if let type = bundle.getType(outError: &errCode) { + if (type == "APPL") { + outBundleID = bundle.bundleIdentifier! + return 0 + } + else { return kLSNotAnApplicationErr } + } + else { return errCode } + } + else { + if (filemanager.fileExists(atPath: inParam) == true) { // Maybe it's a valid file path, but not an app bundle? + return kLSNotAnApplicationErr + } + if let url = URL(string: inParam) { // Let's fallback to an URL. + if (url.path != "") { + if (url.isFileURL == true) { + if (filemanager.fileExists(atPath: url.path) == true) { //Is it a valid app URL? + if let bundle = Bundle(url: url) { + if let type = bundle.getType(outError: &errCode) { + if (type == "APPL") { + outBundleID = bundle.bundleIdentifier! + return 0 + } + else { return kLSNotAnApplicationErr } + } + else { return errCode } + } + else { return kLSNotAnApplicationErr } // Maybe it's a valid file URL, but not an app bundle? + } + else { + return kLSApplicationNotFoundErr + } // No application found at this location. + } + else { return kLSNotAnApplicationErr } + } + else { + if (url.isFileURL == false) { return Int32(NSFileReadUnsupportedSchemeError) } + } + } + else { + return kLSNotAnApplicationErr + } + } + } + return kLSUnknownErr + } } diff --git a/Sources/commonFuncs.swift b/Sources/commonFuncs.swift index 26dad36..1a13466 100644 --- a/Sources/commonFuncs.swift +++ b/Sources/commonFuncs.swift @@ -75,3 +75,15 @@ prefix func /(pattern:String) -> NSRegularExpression? { options:options) else { return nil } return retval } + +extension Bundle { + func getType (outError: inout OSStatus) -> String? { + if let info = self.infoDictionary { + if let type = info["CFBundlePackageType"] { + return String(describing: type) + } + else { outError = kLSNotAnApplicationErr; return nil } + } + else { outError = kLSUnknownErr; return nil } + } +}