ce55be4a-fb5f-4981-b507-0f4.../Sources/support/HostVersionCheck.swift
徐翔宇 c4080b5cb9 v1.0.0: initial AirDrop plugin for MioIsland
Quick-access AirDrop from the notch panel. Tap the card body, pick
files via NSOpenPanel, hand off to NSSharingService(.sendViaAirDrop).
No private APIs, no entitlements, no network — just a thin wrapper
around the same AirDrop API Finder uses.

Design constraint: drag-and-drop is intentionally not implemented.
MioIsland's notch panel auto-collapses on click-outside, which
breaks the Cmd-Tab-to-Finder / grab / drag-back workflow before
the drop target reaches. Tap-to-choose is rock solid by comparison.

Requires MioIsland host v2.2.0+ (panel size clamp floor was
lowered to 120pt in that release).
2026-04-22 08:20:47 +08:00

47 lines
1.5 KiB
Swift

//
// HostVersionCheck.swift
// MioIsland AirDrop Plugin
//
// Gates the plugin against a minimum host version. Plugin relies on
// the v2.2.0 panel-sizing rules (min height 120, floating back chip,
// no chrome header), so older hosts would render this plugin wrong.
//
import Foundation
enum HostVersionCheck {
static let minHost = "2.2.0"
/// Bundle.main inside a plugin dylib points to the *host* app, so
/// we can read its CFBundleShortVersionString to gate features.
static func isOK() -> Bool {
let host = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "0.0.0"
return compare(host, ">=", minHost)
}
static func hostVersion() -> String {
Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "?"
}
// MARK: - Pure semver compare
private static func compare(_ a: String, _ op: String, _ b: String) -> Bool {
let aParts = parts(a)
let bParts = parts(b)
let maxLen = max(aParts.count, bParts.count)
let ap = aParts + Array(repeating: 0, count: maxLen - aParts.count)
let bp = bParts + Array(repeating: 0, count: maxLen - bParts.count)
switch op {
case ">=": return !ap.lexicographicallyPrecedes(bp)
case "<": return ap.lexicographicallyPrecedes(bp)
case "==": return ap == bp
default: return false
}
}
private static func parts(_ s: String) -> [Int] {
s.split(separator: ".").compactMap { Int($0) }
}
}