mirror of
https://github.com/somegeekintn/SimDirs.git
synced 2026-03-25 08:55:54 +00:00
80 lines
3.5 KiB
Swift
80 lines
3.5 KiB
Swift
//
|
|
// SimApp.swift
|
|
// SimDirs
|
|
//
|
|
// Created by Casey Fleser on 6/1/22.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct SimApp: Equatable {
|
|
let identifier : String
|
|
let bundleID : String
|
|
let bundleName : String
|
|
let displayName : String
|
|
let version : String
|
|
let minOSVersion : String
|
|
let bundlePath : String
|
|
let sandboxPath : String?
|
|
let nsIcon : NSImage?
|
|
|
|
init(bundlePath: URL, sandboxPaths: [String : URL]) throws {
|
|
guard let infoPList = PropertyListSerialization.propertyList(from: bundlePath.appendingPathComponent("Info.plist")) else { throw SimError.invalidApp }
|
|
guard let bundleID = infoPList[kCFBundleIdentifierKey as String] as? String else { throw SimError.invalidApp }
|
|
|
|
self.bundlePath = bundlePath.path
|
|
self.bundleID = bundleID
|
|
bundleName = (infoPList[kCFBundleNameKey as String] as? String) ?? "<missing>"
|
|
displayName = (infoPList["CFBundleDisplayName"] as? String) ?? bundleName
|
|
version = (infoPList["CFBundleShortVersionString"] as? String) ?? "<missing>"
|
|
minOSVersion = (infoPList["MinimumOSVersion"] as? String) ?? "<missing>"
|
|
sandboxPath = sandboxPaths[bundleID]?.path
|
|
identifier = bundlePath.deletingLastPathComponent().lastPathComponent
|
|
|
|
// Currently using the biggest image we can find in pixels. Maybe there's a better way?
|
|
nsIcon = (infoPList["CFBundleIcons"] as? [String : AnyObject]).flatMap { bundleIcons -> NSImage? in
|
|
guard let iconFiles = bundleIcons["CFBundlePrimaryIcon"].map({ iconEntry -> [String] in
|
|
switch iconEntry {
|
|
case let primaryDict as [String : AnyObject]: return primaryDict["CFBundleIconFiles"] as? [String] ?? []
|
|
case let str as String: return [str]
|
|
default: return []
|
|
}
|
|
}) else { return nil }
|
|
var icon = NSImage()
|
|
var pixelWidth = 0
|
|
var validIcon = false
|
|
|
|
for iconFile in iconFiles {
|
|
let iconPathComps : [String] = [iconFile, "\(iconFile)@2x", "\(iconFile)@3x"]
|
|
|
|
for pathComp in iconPathComps {
|
|
var iconURL = bundlePath.appendingPathComponent(pathComp)
|
|
|
|
if iconURL.pathExtension.isEmpty {
|
|
iconURL.appendPathExtension("png")
|
|
}
|
|
|
|
if let testIcon = NSImage(contentsOf: iconURL) {
|
|
for imageRep in testIcon.representations {
|
|
if pixelWidth < imageRep.pixelsWide {
|
|
icon = testIcon
|
|
pixelWidth = imageRep.pixelsWide
|
|
validIcon = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return validIcon ? icon : nil
|
|
}
|
|
}
|
|
}
|
|
|
|
extension SimApp: SourceItemData {
|
|
var title : String { return displayName }
|
|
var headerTitle : String { "App: \(title)" }
|
|
var imageDesc : SourceImageDesc { nsIcon.map { .icon(nsImage: $0) } ?? .symbol(systemName: "questionmark.app.dashed") }
|
|
|
|
var optionTrait : SourceFilter.Options { .withApps }
|
|
}
|