mirror of
https://github.com/MioMioOS/mio-plugin-music.git
synced 2026-06-11 03:44:31 +00:00
65 lines
2.3 KiB
Swift
65 lines
2.3 KiB
Swift
|
|
//
|
||
|
|
// ChineseAppDetector.swift
|
||
|
|
// MioIsland Music Plugin
|
||
|
|
//
|
||
|
|
// Detects whether a Chinese desktop music app (QQ 音乐 / 网易云音乐 / 酷狗)
|
||
|
|
// is currently running. These apps do not publish their Now Playing state
|
||
|
|
// to MediaRemote and do not expose a scripting dictionary, so we cannot
|
||
|
|
// read tracks from them. When detected, the UI surfaces a polite message
|
||
|
|
// telling the user to switch to the web player instead of showing an empty
|
||
|
|
// or misleading Now Playing view.
|
||
|
|
//
|
||
|
|
|
||
|
|
import AppKit
|
||
|
|
|
||
|
|
struct ChineseAppDetector {
|
||
|
|
private struct Rule {
|
||
|
|
let bundleIDs: [String]
|
||
|
|
let nameFragments: [String]
|
||
|
|
let displayName: String
|
||
|
|
}
|
||
|
|
|
||
|
|
// Bundle IDs are the primary key; localized name fragments are a fallback
|
||
|
|
// in case the vendor ships a repackaged build with a different bundle ID.
|
||
|
|
private static let rules: [Rule] = [
|
||
|
|
Rule(
|
||
|
|
bundleIDs: ["com.tencent.qqmusicmac", "com.tencent.QQMusicMac"],
|
||
|
|
nameFragments: ["QQ音乐", "QQ 音乐", "QQMusic"],
|
||
|
|
displayName: "QQ 音乐"
|
||
|
|
),
|
||
|
|
Rule(
|
||
|
|
bundleIDs: ["com.netease.163music", "com.netease.cloudmusicmac"],
|
||
|
|
nameFragments: ["网易云音乐", "网易云", "NeteaseMusic", "CloudMusic"],
|
||
|
|
displayName: "网易云音乐"
|
||
|
|
),
|
||
|
|
Rule(
|
||
|
|
bundleIDs: ["com.kugou.mac", "com.kugou.KuGouMusic"],
|
||
|
|
nameFragments: ["酷狗", "KuGou"],
|
||
|
|
displayName: "酷狗音乐"
|
||
|
|
)
|
||
|
|
]
|
||
|
|
|
||
|
|
/// Return the display name of the first matching running app, or nil.
|
||
|
|
static func detectRunning() -> String? {
|
||
|
|
let apps = NSWorkspace.shared.runningApplications
|
||
|
|
for rule in rules {
|
||
|
|
for app in apps {
|
||
|
|
if app.isTerminated { continue }
|
||
|
|
|
||
|
|
if let bid = app.bundleIdentifier,
|
||
|
|
rule.bundleIDs.contains(where: { bid.caseInsensitiveCompare($0) == .orderedSame }) {
|
||
|
|
return rule.displayName
|
||
|
|
}
|
||
|
|
|
||
|
|
if let name = app.localizedName {
|
||
|
|
for frag in rule.nameFragments
|
||
|
|
where name.range(of: frag, options: .caseInsensitive) != nil {
|
||
|
|
return rule.displayName
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
}
|