You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何避免快捷指令自动化(Shortcut Automation)引发的无限循环问题

如何避免快捷指令自动化(Shortcut Automation)引发的无限循环问题

我之前也踩过一模一样的坑!你遇到的这种无限循环,本质是系统在你从自己的APP切回原APP(比如Instagram)时,又误判成了一次“打开原APP”的事件,导致自动化指令被重复触发。下面给你几个实用的解决思路,你可以根据自己的场景选:

  • openAppWhenRun禁用自动启动(适合后台任务)
    你提到的static let openAppWhenRun: Bool = false是个非常直接的方案!把这个静态常量设为false,就能阻止自动化触发时自动拉起你的APP。不过这个方法只适合你的任务不需要前台运行的情况——比如只是后台同步数据、发送个通知这类轻量操作。如果你的任务必须让APP前台展示给用户操作,那得用下面的方法。

  • 时间窗口过滤法(简单易实现)
    核心思路是:从自己APP切回原APP的重复触发,通常都发生在第一次触发后的短时间内。我们可以记录上次Intent触发的时间,过滤掉短时间内的重复请求。修改你的perform()方法就行:

    @MainActor func perform() async throws -> some IntentResult {
        // 静态变量存储上次触发的时间戳
        static var lastTriggeredTime: Date?
        
        let currentTime = Date()
        // 这里设置30秒的阈值,你可以根据实际情况调整
        if let lastTime = lastTriggeredTime, currentTime.timeIntervalSince(lastTime) < 30 {
            return .result()
        }
        lastTriggeredTime = currentTime
        
        // 这里写你原本的任务逻辑
        // ...
        
        return .result()
    }
    

    这样一来,切回原APP时的重复触发会因为时间间隔太短被直接跳过,循环自然就断了。

  • 任务状态标记法(更精准)
    我们可以在APP里存一个“任务是否正在处理”的标记,当Intent触发时,如果检测到标记为“正在处理”,就说明是切回导致的重复触发,直接返回不执行任务。用UserDefaults来存标记就很方便:

    @MainActor func perform() async throws -> some IntentResult {
        let defaults = UserDefaults.standard
        
        // 检查是否是切回导致的重复触发
        if defaults.bool(forKey: "isCurrentTaskRunning") {
            // 重置标记,避免影响下一次正常触发
            defaults.set(false, forKey: "isCurrentTaskRunning")
            return .result()
        }
        
        // 标记任务开始处理
        defaults.set(true, forKey: "isCurrentTaskRunning")
        
        // 执行你的核心任务逻辑
        // ...
        
        // 任务完成后一定要重置标记(异步任务要确保在任务结束时执行)
        defaults.set(false, forKey: "isCurrentTaskRunning")
        
        return .result()
    }
    

    注意如果你的任务是异步的,一定要在任务真正完成(比如网络请求结束、用户操作完成)后再重置标记,不然可能会漏掉正常的触发请求。

备注:内容来源于stack exchange,提问作者かいせい

火山引擎 最新活动