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

iOS AppIntent参数如何设置自定义默认值?跨快捷复用方案

问题

我正在创建一组快捷指令,其中一个用于设置设备名称,另一个对已设置的设备执行操作。为此我创建了自定义AppIntent,其中一个参数为string类型,希望将其默认值设为之前存储在UserDefaults中的值,但尝试以下代码时:

struct AppIntentSetUp: AppIntent {
    @Parameter(title: "DeviceName", description: "The device name", default: deviceName, inputOptions: String.IntentInputOptions(capitalizationType: .words), requestValueDialog: IntentDialog("What is the device name?"))
    var device: String
    
    static var parameterSummary: some ParameterSummary {
        Summary("Select the device \(\.$device)  ")
    }
    
    static var title: LocalizedStringResource {
        .init(stringLiteral: "AppIntentSetUp")
    }
    
    func perform() async throws -> some IntentResult {
        //do my action
        return .result(value: "")
    }
}

var deviceName: String? {
    UserDefaults(suiteName: "MyDeviceName")?.object(forKey: "MyDevice") as? String
}

编译器报错:

Expect a compile-time constant literal

我理解默认值需要编译时常量,请问是否有方法为AppIntent参数设置自定义默认值?或有其他方式实现跨快捷指令复用参数值的目标?

解决方案

方法一:在perform方法中处理默认值逻辑

既然@Parameter的default参数只能用编译时常量,你可以把参数设为可选类型,然后在perform方法里判断如果参数为空,就从UserDefaults读取存储的值:

struct AppIntentSetUp: AppIntent {
    @Parameter(title: "DeviceName", description: "The device name", inputOptions: String.IntentInputOptions(capitalizationType: .words), requestValueDialog: IntentDialog("What is the device name?"))
    var device: String? // 改为可选类型
    
    static var parameterSummary: some ParameterSummary {
        Summary("Select the device \(\.$device)  ")
    }
    
    static var title: LocalizedStringResource {
        .init(stringLiteral: "AppIntentSetUp")
    }
    
    func perform() async throws -> some IntentResult {
        // 处理默认值:如果device为空,读取UserDefaults中的值
        let targetDevice = device ?? UserDefaults(suiteName: "MyDeviceName")?.string(forKey: "MyDevice") ?? ""
        // 使用targetDevice执行操作
        return .result(value: "")
    }
}

方法二:使用DynamicOptionsProvider提供动态选项(适合需要让用户选择的场景)

如果希望用户能直接选择之前存储的设备名称,同时支持输入新名称,可以用DynamicOptionsProvider来动态生成选项列表:

struct AppIntentSetUp: AppIntent {
    @Parameter(title: "DeviceName", description: "The device name", inputOptions: String.IntentInputOptions(capitalizationType: .words), requestValueDialog: IntentDialog("What is the device name?"), optionsProvider: DeviceOptionsProvider())
    var device: String
    
    static var parameterSummary: some ParameterSummary {
        Summary("Select the device \(\.$device)  ")
    }
    
    static var title: LocalizedStringResource {
        .init(stringLiteral: "AppIntentSetUp")
    }
    
    func perform() async throws -> some IntentResult {
        // 保存或使用device值
        UserDefaults(suiteName: "MyDeviceName")?.set(device, forKey: "MyDevice")
        return .result(value: "")
    }
}

// 自定义动态选项提供者
struct DeviceOptionsProvider: DynamicOptionsProvider {
    func results() async throws -> [String] {
        // 返回存储的设备名称作为选项,可添加其他默认选项
        if let savedDevice = UserDefaults(suiteName: "MyDeviceName")?.string(forKey: "MyDevice") {
            return [savedDevice, "输入新设备名称"]
        }
        return ["输入新设备名称"]
    }
}

方法三:跨快捷指令复用参数的其他思路

  • 用UserDefaults作为全局存储中心,所有需要复用参数的AppIntent都直接从这里读取和写入,无需依赖参数默认值。
  • 如果是更复杂的场景,可以创建一个单例类来管理设备名称的存储和读取,封装UserDefaults的操作,让各个AppIntent统一调用这个类的方法获取值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 05:12:43