自定义AppEntity的Siri Shortcut AppIntent重复请求输入问题求助
Siri快捷指令自定义AppEntity异常问题解决
我用SwiftUI开发应用,想实现自定义Siri快捷指令,为此创建了专属的BookEntity,但遇到问题:当选择建议列表里除首个之外的条目时,Siri会持续要求输入。我尝试复刻WWDC的示例代码,问题依然存在,相关代码如下:
struct BookEntity: AppEntity, Identifiable { var id: UUID var title : String var displayRepresentation: DisplayRepresentation { DisplayRepresentation(stringLiteral: "\(title)") } static var typeDisplayRepresentation: TypeDisplayRepresentation = "Book" static var defaultQuery = BookQuery() } struct BookQuery: EntityStringQuery { func entities(for identifiers: [UUID]) async throws -> [BookEntity] { let entries = try await suggestedEntities() return identifiers.compactMap { identifier in entries.filter{$0.id == identifier}.first } } func suggestedEntities() async throws -> [BookEntity] { let titles = ["Hallo","Du","Schöne","Welt"] return titles.map{BookEntity(id: UUID(), title: $0)} } func entities(matching string: String) async throws -> [BookEntity] { return try await suggestedEntities() } } struct OpenBook: AppIntent { @Parameter(title: "Book") var book: BookEntity static var title: LocalizedStringResource = "Open Book" static var openAppWhenRun = true @MainActor func perform() async throws -> some IntentResult { guard try await $book.requestConfirmation(for: book, dialog: "Are you sure you want to clear read state for \(book)?") else { return .result() } return .result() } static var parameterSummary: some ParameterSummary { Summary("Open \(\.$book)") } init() {} init(book: BookEntity) { self.book = book } }
问题根源
你的BookQuery中,每次调用suggestedEntities()都会生成全新的UUID,导致entities(for identifiers:)方法里,传入的identifiers无法匹配到任何实体——因为每次生成的BookEntity都是新ID,Siri找不到对应实体,就会反复请求用户确认。
修正后的代码
把建议实体的UUID固定下来,或者缓存实体列表,确保每次查询时ID一致:
struct BookEntity: AppEntity, Identifiable { var id: UUID var title : String var displayRepresentation: DisplayRepresentation { DisplayRepresentation(stringLiteral: "\(title)") } static var typeDisplayRepresentation: TypeDisplayRepresentation = "Book" static var defaultQuery = BookQuery() // 预定义固定ID的书籍实体 static let sampleBooks: [BookEntity] = [ BookEntity(id: UUID(uuidString: "00000000-0000-0000-0000-000000000001")!, title: "Hallo"), BookEntity(id: UUID(uuidString: "00000000-0000-0000-0000-000000000002")!, title: "Du"), BookEntity(id: UUID(uuidString: "00000000-0000-0000-0000-000000000003")!, title: "Schöne"), BookEntity(id: UUID(uuidString: "00000000-0000-0000-0000-000000000004")!, title: "Welt") ] } struct BookQuery: EntityStringQuery { func entities(for identifiers: [UUID]) async throws -> [BookEntity] { // 直接从预定义样本中匹配ID return BookEntity.sampleBooks.filter { identifiers.contains($0.id) } } func suggestedEntities() async throws -> [BookEntity] { return BookEntity.sampleBooks } func entities(matching string: String) async throws -> [BookEntity] { // 根据输入字符串过滤实体(示例保留全匹配逻辑) return BookEntity.sampleBooks.filter { $0.title.localizedCaseInsensitiveContains(string) } } } struct OpenBook: AppIntent { @Parameter(title: "Book") var book: BookEntity static var title: LocalizedStringResource = "打开书籍" static var openAppWhenRun = true @MainActor func perform() async throws -> some IntentResult { guard try await $book.requestConfirmation(for: book, dialog: "确定要清除《\(book.title)》的阅读状态吗?") else { return .result() } // 此处添加实际打开书籍的业务逻辑 return .result() } static var parameterSummary: some ParameterSummary { Summary("打开 \(\.$book)") } init() {} init(book: BookEntity) { self.book = book } }
额外注意事项
- 确保
Info.plist中配置了Siri权限描述(NSSiriUsageDescription) - 测试前重启Siri和应用,避免缓存导致的异常
- 如果实体从网络/本地数据库获取,需保证每次查询返回的实体ID一致,不要动态生成新ID
内容的提问来源于stack exchange,提问作者Foaly333
相关产品推荐
相关产品推荐

