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

macOS 13 Focus系统扩展perform()函数未执行及功能疑问

Focus系统扩展perform()函数问题排查与功能说明

一、perform()函数未执行的排查方案

  • 检查Info.plist配置
    确认NSExtension字典内的关键配置:
    • NSExtensionPointIdentifier必须设为com.apple.focus-filter
    • 如果关联特定专注模式,NSExtensionAttributes下的FocusBundleIdentifiers或FocusFilterModeIdentifiers要和目标模式的ID完全匹配,自定义模式需确保ID一致。
  • 验证沙箱权限
    沙箱化扩展需配置必要权限:
    • 确保com.apple.security.app-sandbox设为YES
    • 添加com.apple.security.temporary-exception.apple-events权限并包含com.apple.systempreferences,保证扩展能响应系统专注状态变更。
  • 核对方法签名
    perform()必须是异步方法且返回正确类型,签名错误会导致系统不调用:
    override func perform(context: FocusFilterContext) async -> FocusFilterResult {
        // 业务逻辑
        return .allow
    }
    
  • 更换调试方式
    NSLog和NSSound在系统扩展环境中无法正常工作,改用os_log输出日志,在Console.app中通过子系统和类别过滤查看:
    import os.log
    private let logger = OSLog(subsystem: "com.yourteam.yourextension", category: "FocusFilter")
    
    override func perform(context: FocusFilterContext) async -> FocusFilterResult {
        os_log("perform() triggered", log: logger, type: .info)
        return .allow
    }
    

二、perform()函数的功能范围与实践示例

核心功能定位

perform()是Focus扩展的核心回调,当关联的专注模式激活、变更时触发,主要用于实现内容过滤逻辑(比如拦截通知、调整应用显示内容),通过返回.allow或.deny控制内容是否放行。

写入文件的实现

沙箱化扩展仅能写入自身容器目录或用户授权的路径,通过应用组可与宿主应用共享文件:

// 需先配置应用组权限(com.apple.security.application-groups)
let groupContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.yourteam.yourapp")!
let logFileURL = groupContainerURL.appendingPathComponent("focus_log.txt")
try "Focus mode activated: \(context.mode.identifier)".write(to: logFileURL, atomically: true, encoding: .utf8)

与宿主应用通信的两种方式

  1. 应用组+UserDefaults
// 扩展中写入状态
let sharedDefaults = UserDefaults(suiteName: "group.com.yourteam.yourapp")!
sharedDefaults.set(Date(), forKey: "LastFocusActivationTime")

// 宿主应用中监听变更
NotificationCenter.default.addObserver(forName: UserDefaults.didChangeNotification, object: sharedDefaults, queue: .main) { _ in
    if let activationTime = sharedDefaults.object(forKey: "LastFocusActivationTime") as? Date {
        // 处理逻辑
    }
}
  1. 分布式通知中心
// 扩展中发送通知
DistributedNotificationCenter.default().post(
    name: NSNotification.Name("FocusExtensionDidTrigger"),
    object: nil,
    userInfo: ["modeID": context.mode.identifier.rawValue],
    deliverImmediately: true
)

// 宿主应用中监听
DistributedNotificationCenter.default().addObserver(
    forName: NSNotification.Name("FocusExtensionDidTrigger"),
    object: nil,
    queue: .main
) { notification in
    if let modeID = notification.userInfo?["modeID"] as? String {
        // 处理逻辑
    }
}

注:使用分布式通知需在沙箱权限中添加com.apple.security.temporary-exception.apple-events。

内容的提问来源于stack exchange,提问作者John M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:15:31