You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MacOS Swift:如何读取第三方.app的Info.plist并获取Bundle ID

解决方案

1. 更新Application结构体

首先扩展Application结构体,添加你需要的字段:

struct Application {
    var name: String
    var url: String
    var isRunning: Bool
    var bundleIdentifier: String? // 例如 com.apple.xcode
    var registeredFileTypes: [String]? // 注册的文件扩展名或UTI
    var associatedDomains: [String]? // 关联域名(如 applinks:example.com)
}

2. 通过Bundle读取Info.plist信息

利用Bundle(url:)可以直接从.app包URL初始化Bundle实例,它会自动处理Info.plist的路径和解析,比手动读取plist文件更简便。在遍历应用URL的循环中添加以下逻辑:

修改getAllApplications()方法中的循环部分:

for url in allApplicationUrls {
    let resourceKeys: [URLResourceKey] = [.isExecutableKey, .isApplicationKey]
    let resourceValues = try url.resourceValues(forKeys: Set(resourceKeys))
    guard resourceValues.isExecutable ?? false else { continue }
    
    let name = url.deletingPathExtension().lastPathComponent
    let urlStr = url.absoluteString
    let isRunning = runningApps.contains { $0.bundleURL?.absoluteString == urlStr }
    
    // 初始化Bundle并读取Info.plist信息
    var bundleId: String?
    var fileTypes: [String]?
    var domains: [String]?
    
    if let bundle = Bundle(url: url) {
        // 获取Bundle ID
        bundleId = bundle.bundleIdentifier
        
        // 获取注册的文件类型
        var types = Set<String>()
        if let docTypes = bundle.infoDictionary?["CFBundleDocumentTypes"] as? [[String: Any]] {
            docTypes.forEach { typeDict in
                // 提取文件扩展名
                if let extensions = typeDict["CFBundleTypeExtensions"] as? [String] {
                    types.formUnion(extensions)
                }
                // 若需要UTI类型,可替换为以下代码
                // if let uti = typeDict["CFBundleTypeIdentifier"] as? String {
                //     types.insert(uti)
                // }
            }
        }
        fileTypes = types.isEmpty ? nil : Array(types)
        
        // 获取关联域名
        if let associatedDomains = bundle.infoDictionary?["NSAssociatedDomains"] as? [String] {
            domains = associatedDomains.isEmpty ? nil : associatedDomains
        }
    }
    
    applications.append(Application(
        name: name,
        url: urlStr,
        isRunning: isRunning,
        bundleIdentifier: bundleId,
        registeredFileTypes: fileTypes,
        associatedDomains: domains
    ))
}

关键说明

  • Bundle初始化:Bundle(url: url)仅对合法的.app包有效,配合之前的isApplicationKey判断,可以确保只处理有效的应用包。
  • Info.plist字段映射:
    • Bundle ID:直接通过bundle.bundleIdentifier获取,比读取infoDictionary更可靠。
    • 注册文件类型:对应Info.plist中的CFBundleDocumentTypes数组,可根据需求提取扩展名(CFBundleTypeExtensions)或UTI(CFBundleTypeIdentifier)。
    • 关联域名:对应Info.plist中的NSAssociatedDomains数组,通常格式为applinks:xxx.com、webcredentials:xxx.com等。
  • 空值处理:对空数组或空值返回nil,避免存储无意义的空数据。

内容的提问来源于stack exchange,提问作者Oscar Franco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 03:32:10