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

如何基于SwiftUI创建macOS Droplet应用?能否使用SPM实现?

如何用SwiftUI+SPM创建macOS Droplet应用(实现VLC多实例启动功能)

核心思路

Droplet本质是能响应文件拖放/「打开方式」请求的macOS应用,我们可以通过SwiftUI的App协议结合SPM构建可执行应用包,同时通过NSApplicationDelegate处理启动和文件打开事件,完全替代Cocoa或AppleScript方案。


1. 创建SPM可执行包

首先初始化一个SPM可执行项目:

mkdir VLCLauncherDroplet && cd VLCLauncherDroplet
swift package init --type executable

2. 配置Package.swift

修改Package.swift,指定macOS平台、应用bundle配置(必须添加Info.plist键值对来支持文件关联和UI行为):

// swift-tools-version: 5.9
import PackageDescription

let package = Package(
    name: "VLCLauncherDroplet",
    platforms: [
        .macOS(.v13) // 适配SwiftUI 3+特性
    ],
    products: [
        .executable(
            name: "VLCLauncherDroplet",
            targets: ["VLCLauncherDroplet"]
        ),
    ],
    targets: [
        .executableTarget(
            name: "VLCLauncherDroplet",
            dependencies: [],
            // 配置应用Info.plist
            infoPlist: [
                "CFBundleName": "VLCLauncherDroplet",
                "CFBundleIdentifier": "com.yourdomain.VLCLauncherDroplet",
                "CFBundleVersion": "1.0",
                "CFBundleShortVersionString": "1.0",
                "LSUIElement": false, // 设为false才能在Dock显示,否则后台运行
                "NSAppleEventsUsageDescription": "需要启动VLC并打开指定文件",
                // 配置支持的文件类型(这里设为所有文件,可按需修改UTI)
                "CFBundleDocumentTypes": [
                    [
                        "CFBundleTypeName": "All Files",
                        "CFBundleTypeRole": "Viewer",
                        "LSItemContentTypes": ["public.item"],
                        "LSHandlerRank": "Alternate"
                    ]
                ]
            ]
        )
    ]
)

3. 编写SwiftUI应用代码

替换Sources/VLCLauncherDroplet/main.swift的内容,通过NSApplicationDelegateAdaptor处理启动和文件打开事件:

import SwiftUI
import AppKit

// 自定义Delegate处理应用事件
class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ notification: Notification) {
        // 对应AppleScript的`run` handler:无文件时启动新VLC实例
        let process = Process()
        process.executableURL = URL(filePath: "/usr/bin/open")
        process.arguments = ["-n", "/Applications/VLC.app"]
        try? process.run()
        process.waitUntilExit()
        
        // 启动后退出Droplet(可选,保持后台也可以)
        NSApplication.shared.terminate(nil)
    }
    
    func application(_ application: NSApplication, open urls: [URL]) {
        // 对应AppleScript的`open` handler:处理拖入/打开方式的文件
        for url in urls {
            let escapedPath = url.path.replacingOccurrences(of: "'", with: "\\'")
            let process = Process()
            process.executableURL = URL(filePath: "/usr/bin/open")
            process.arguments = ["-na", "/Applications/VLC.app", "'\(escapedPath)'"]
            try? process.run()
            process.waitUntilExit()
        }
        
        // 激活VLC并退出Droplet
        NSWorkspace.shared.launchApplication(at: URL(filePath: "/Applications/VLC.app"), options: .activateAllWindows, configuration: [:])
        NSApplication.shared.terminate(nil)
    }
}

@main
struct VLCLauncherDropletApp: App {
    // 注入Delegate
    @NSApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
    var body: some Scene {
        // SwiftUI需要至少一个Scene,这里用空WindowGroup(不会显示窗口)
        WindowGroup {
            EmptyView()
                .frame(width: 0, height: 0)
                .hidden()
        }
        .windowStyle(.hiddenTitleBar)
    }
}

4. 构建并部署

执行构建命令生成Release版本的应用包:

swift build -c release

构建完成后,将产物从.build/release/VLCLauncherDroplet.app移动到/Applications文件夹。

5. 配置Finder「打开方式」

在Finder中选中任意文件,右键选择「显示简介」→「打开方式」→选择VLCLauncherDroplet,点击「全部更改」即可将该Droplet设为默认打开工具(或按需选择)。


注意事项

  • 如果需要限制支持的文件类型,修改CFBundleDocumentTypes中的LSItemContentTypes(例如public.movie对应视频文件)。
  • 若不需要Droplet在Dock显示,可将LSUIElement设为true,此时应用会后台运行。
  • 测试时可直接将文件拖到Dock上的Droplet图标,验证多实例启动功能。

内容的提问来源于stack exchange,提问作者marc-medley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:25:27