Files
2019-06-17 00:51:05 -04:00

134 lines
5.0 KiB
Swift

/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <g.litenstein@gmail.com> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return., Gregorio Litenstein.
* ----------------------------------------------------------------------------
*/
import AppKit
/** Represents information about an application and its associated URI Schemes and UTIs as an object. */
class SWDAApplicationInfo: NSObject {
var displayName: String?
var appPath: String?
var appURL: String?
var appDescription: String?
var appVersion: String?
var appBundleID: String?
var appIcon: NSImage?
lazy var handlers: [SWDAContentHandler] = { return [] }()
lazy var handledContent: [String: [String:[SWDAContentHandler]?]] = {
var wrappedHandlers: [String: [String:[SWDAContentHandler]?]] = [:]
if let handlers = LSWrappers.copySchemesAndUTIsForApp(self.appPath!) {
var wrappedURIHandlers: [String:[SWDAContentHandler]] = ["Viewer":[]]
var wrappedUTIHandlers: [String:[SWDAContentHandler]] = ["Viewer":[],"Editor":[],"Shell":[]]
for handlerRole in handlers["UTIs"]! {
let role = String(describing:handlerRole.key)
var handler: SWDAContentHandler?
for utiHandler in handlerRole.value {
handler = SWDAContentHandler(SWDAContentItem(type:SWDAContentType(rawValue:"UTI")!, utiHandler), appName: self.appBundleID!, role: SourceListRoleTypes(rawValue:role)!)
if let handler = handler {
wrappedUTIHandlers[role]!.append(handler)
}
}
}
for handlerRole in handlers["URIs"]! {
let role = String(describing:handlerRole.key)
var handler: SWDAContentHandler?
for urlHandler in handlerRole.value {
handler = SWDAContentHandler(SWDAContentItem(type:SWDAContentType(rawValue:"URI")!, urlHandler), appName: self.appBundleID!, role: SourceListRoleTypes(rawValue:role)!)
if let handler = handler {
wrappedURIHandlers[role]!.append(handler)
}
}
}
wrappedHandlers["UTIs"] = wrappedUTIHandlers
wrappedHandlers["URIs"] = wrappedURIHandlers
return wrappedHandlers
}
else { return ["URIs":["Viewer":[]],"UTIs":["Editor":[], "Viewer":[], "Shell":[]]] }
}()
/** Only applications that handle at least one URI Scheme or UTI will show up in the "Applications" tab. */
lazy var handlesURIs: Bool = {
for role in (self.handledContent["URIs"]!).values {
if !(role!.isEmpty) { return true }
}
return false
}()
lazy var handlesUTIs: Bool = {
for role in (self.handledContent["UTIs"]!).values {
if !(role!.isEmpty) { return true }
}
return false
}()
init?(_ inParam: String) {
var bundleID: String?
switch inParam {
case "Other...":
self.displayName = "Other..."
self.appVersion = ""
self.appPath = ""
self.appIcon = NSImage(byReferencingFile: "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericApplicationIcon.icns")
default:
let result = LSWrappers.getBundleID(inParam, outBundleID: &bundleID)
if (result == 0) {
let appURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleID!)
guard appURL != nil else { return nil }
if let bundle = Bundle(url: appURL!) {
guard bundle.bundleIdentifier != nil else {
NSLog(LSWrappers.LSErrors.invalidBundle.print(argument: (app: inParam, content:"")))
return nil;
}
self.appBundleID = bundle.bundleIdentifier!
let name = (bundle.object(forInfoDictionaryKey: "CFBundleName") as? String)
let displayName = (bundle.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String)
var tempName: String?
if let displayName = displayName {
tempName = displayName
}
sanity: if let name = bundle.object(forInfoDictionaryKey: "CFBundleName") as? String { // Theoretically, apps should always have a CFBundleName and most of the time, also a CFBundleDisplayName. In practice? Not so much. We should be prepared to handle broken apps.
guard (tempName == nil || tempName == "") else { break sanity }
tempName = name
}
else {
tempName = FileManager.default.displayName(atPath: bundle.bundlePath)
}
self.displayName = tempName
self.appURL = String(describing:bundle.bundleURL)
if let version = bundle.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String {
self.appVersion = version
}
else if let version = bundle.object(forInfoDictionaryKey: "CFBundleVersion") as? String {
self.appVersion = version
}
else { self.appVersion = nil }
self.appPath = bundle.bundlePath
self.appIcon = NSWorkspace.shared.icon(forFile: bundle.bundlePath)
}
else {
NSLog(LSWrappers.LSErrors.init(value:result).print(argument: (app: inParam, content:"")))
return nil
}
}
else {
NSLog(LSWrappers.LSErrors.init(value:result).print(argument: (app: inParam, content:"")))
return nil
}
}
super.init()
}
}