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

如何为macOS FileProvider API添加自定义动作并在代码中调用

macOS FileProvider API 自定义动作实现指南

1. 添加自定义动作到FileProvider

自定义动作需要先在File Provider扩展的Info.plist中声明,系统会根据配置在Finder右键菜单中展示对应选项。

在扩展的Info.plist中添加NSExtensionFileProviderActions数组,每个数组元素为字典形式,定义单个动作的属性:

<key>NSExtensionFileProviderActions</key>
<array>
    <dict>
        <key>identifier</key>
        <string>com.yourcompany.archive-action</string>
        <key>displayName</key>
        <string>归档到云端</string>
        <key>imageName</key>
        <string>archive</string> <!-- 可使用系统图标名或自定义图标资源名 -->
        <key>supportedItemTypes</key>
        <array>
            <string>public.item</string> <!-- 支持所有文件/文件夹 -->
        </array>
    </dict>
    <dict>
        <key>identifier</key>
        <string>com.yourcompany.share-with-team</string>
        <key>displayName</key>
        <string>分享给团队</string>
        <key>imageName</key>
        <string>square.and.arrow.up</string>
        <key>supportedItemTypes</key>
        <array>
            <string>public.image</string>
            <string>public.text</string>
        </array>
    </dict>
</array>

2. 定义与自定义动作

每个动作的核心配置项说明:

  • identifier:全局唯一标识,建议使用反向域名格式
  • displayName:Finder右键菜单中显示的动作名称
  • imageName:动作图标,可使用SF Symbols名称(如square.and.arrow.up)或扩展内的自定义图标资源名
  • supportedItemTypes:指定动作支持的文件类型UTI(Uniform Type Identifier),如public.image、public.folder等

若需动态控制动作可用性(比如根据文件状态、权限),在FileProviderExtension类中重写supportedActions(for item: NSFileProviderItem)方法:

override func supportedActions(for item: NSFileProviderItem) -> [NSFileProviderActionIdentifier] {
    var actions = super.supportedActions(for: item)
    
    // 仅对已下载完成的文件显示归档动作
    if item.isDownloaded {
        actions.append(NSFileProviderActionIdentifier("com.yourcompany.archive-action"))
    }
    
    // 仅对团队文件夹内的文件显示分享动作
    if item.parentItemIdentifier == teamFolderIdentifier {
        actions.append(NSFileProviderActionIdentifier("com.yourcompany.share-with-team"))
    }
    
    return actions
}

3. 处理动作执行逻辑

用户在Finder中选择动作后,系统会调用FileProviderExtension的performAction(_:for:itemIdentifiers:completionHandler:)方法,在此实现具体业务逻辑:

override func performAction(_ actionIdentifier: NSFileProviderActionIdentifier, for item: NSFileProviderItem, itemIdentifiers: [NSFileProviderItemIdentifier], completionHandler: @escaping (Error?) -> Void) {
    switch actionIdentifier.rawValue {
    case "com.yourcompany.archive-action":
        // 实现归档逻辑:移动文件到归档目录
        let archiveParentIdentifier = NSFileProviderItemIdentifier(domainIdentifier: self.domainIdentifier, rawValue: "archive-folder")
        
        let updatedItem = item.copy() as! NSFileProviderItem
        updatedItem.parentItemIdentifier = archiveParentIdentifier
        
        self.modifyItem(updatedItem, baseVersion: item.version) { error in
            completionHandler(error)
        }
        
    case "com.yourcompany.share-with-team":
        // 实现分享逻辑:调用团队API发送分享通知
        Task {
            do {
                try await TeamShareAPI.shareItem(withIdentifier: item.itemIdentifier.rawValue)
                completionHandler(nil)
            } catch {
                completionHandler(error)
            }
        }
        
    default:
        // 处理未知动作
        completionHandler(NSError(domain: NSFileProviderErrorDomain, code: NSFileProviderError.unsupportedAction.rawValue, userInfo: nil))
    }
}

4. 在代码中访问与触发动作

获取某个Item支持的动作

let item: NSFileProviderItem = // 获取目标Item
guard let extension = NSFileProviderManager.default.providerExtension(for: item.itemIdentifier) else { return }

extension.supportedActions(for: item) { actions, error in
    if let error = error {
        // 处理错误
        return
    }
    // 遍历可用动作
    for actionId in actions {
        print("可用动作:\(actionId.rawValue)")
    }
}

主动触发动作执行

let item: NSFileProviderItem = // 获取目标Item
let actionId = NSFileProviderActionIdentifier("com.yourcompany.archive-action")

NSFileProviderManager.default.performAction(actionId, forItemWithIdentifier: item.itemIdentifier) { error in
    if let error = error {
        // 处理执行错误
    } else {
        // 动作执行成功
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:22:56