在 iOS AppIntent 参数中设置默认值(自定义值)

问题描述 投票:0回答:1

我正在尝试创建一些快捷方式,其中我将设置我的设备名称的快捷方式之一。 我将在另一个快捷方式中对所选设备(在我的第一个快捷方式上设置)执行一些操作。

为此,我尝试创建一个自定义 AppIntent,其中我的参数值之一是

string
。 我想从之前存储的 UserDefault 中设置参数的默认值。 但是,默认值不采用任何
let\var
值。我尝试了以下

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
}
 

现在我从编译器中收到以下错误

期望编译时常量文字

从错误中,我了解到默认值采用编译时常量值。

有什么方法可以将AppIntent

parameter
默认值设置为自定义值吗?

或者我可以实现主要目标的其他方法是设置一个快捷方式并在另一个快捷方式中使用该值。

ios swift shortcut appintents
1个回答
0
投票

由于没有人回答我的问题,我已经找到了我的问题的解决方案。该解决方案可能并不完美,但解决了需求。

要在 AppIntent 参数中设置

custom default value
, 我们需要创建一个自定义 AppEnity 它将用作参数类型。

自定义AppEnity,

defaultQuery
需要确认
EntityQuery
支持
func defaultResult()

通过确认

defaultResult()
,我们可以在运行时为 AppIntent 参数提供默认值。

要将一个AppIntent选定的属性用于另一个AppIntent,我们需要在参数值选择期间将第一个AppIntent参数值保存到任意存储中。 我们可以通过在内部保存价值来实现这一点

func entities(for identifiers: [*.ID])

要获取另一个 AppIntent 保存值,我们可以使用

defaultResult()
函数。

我的示例代码如下

import AppIntents

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


struct DeviceAppEntity: AppEntity {
    static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Device entity")
    static var defaultQuery = DeviceAppEntityQuery()
    
    var id: String
    var displayString: String
    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(title: "\(displayString)")
    }
}

struct DeviceAppEntityQuery: EntityQuery {
    func entities(for identifiers: [DeviceAppEntity.ID]) async throws -> [DeviceAppEntity] {
        let result = try await suggestedEntities().filter { identifiers.contains($0.id) }
        // Saving device in storage
        saveDeviceInStorage(result.first)
        return result
    }
    
    func suggestedEntities() async throws -> [DeviceAppEntity] {
        deviceList
    }
    
    func defaultResult() async -> DeviceAppEntity? {
        //getting device from storage
        _ = deviceInStorage()
        
        try? await suggestedEntities().first
    }
    
    func saveDeviceInStorage(_ device: DeviceAppEntity?) {
        // Save device in storage
    }
    
    func deviceInStorage() -> DeviceAppEntity? {
        // fetch device from storage
    }
}

let deviceList: [DeviceAppEntity] = [
    .init(id: "\(UUID().uuidString)", displayString: "One 1"),
    .init(id: "\(UUID().uuidString)", displayString: "One 2"),
    .init(id: "\(UUID().uuidString)", displayString: "One 3")
]
© www.soinside.com 2019 - 2024. All rights reserved.