# App Intents และ Siri Shortcuts: ระบบอัตโนมัติ iOS ขั้นสูงปี 2026 > คู่มือฉบับสมบูรณ์เกี่ยวกับ App Intents และ Siri Shortcuts สำหรับ iOS 18+ สร้างคำสั่ง Siri ที่กำหนดเอง รวม Apple Intelligence และทำให้แอป Swift เป็นอัตโนมัติในปี 2026 - Published: 2026-03-08 - Updated: 2026-04-29 - Author: SharpSkill - Tags: app-intents, siri-shortcuts, ios, swift, apple-intelligence - Reading time: 15 min --- ในปี 2026 ด้วย Apple Intelligence และเฟรมเวิร์ก App Intents แอป iOS ก้าวเข้าสู่ยุคที่เจตนาของผู้ใช้สำคัญกว่าหน้าจอกราฟิก แอปที่ไม่เปิดเผย intents จะมองไม่เห็นในระบบปฏิบัติการที่เน้น AI App Intents เป็นรากฐานที่ทำให้ Siri, Spotlight, วิดเจ็ต และ Action Button สามารถโต้ตอบกับฟังก์ชันของแอปได้ > **สิ่งที่บทความนี้ครอบคลุม** > > บทความนี้นำเสนอการสร้าง App Intents และ Siri Shortcuts สำหรับ iOS 18+ อย่างครบถ้วน ตั้งแต่แนวคิดพื้นฐานไปจนถึงการรวมกับ Apple Intelligence และ App Intent Domains ## ทำความเข้าใจเฟรมเวิร์ก App Intents เฟรมเวิร์ก App Intents ที่เปิดตัวพร้อม iOS 16 ปรับปรุงการสร้าง intents ใน Swift โดยแทนที่เฟรมเวิร์ก SiriKit Intents เดิม สถาปัตยกรรมเชิงประกาศนี้ทำให้สามารถสร้างคำสั่งที่ระบบค้นพบได้ ได้แก่ Spotlight, แอปทางลัด, Siri และ Action Button ```swift // TaskIntent.swift import AppIntents // AppIntent แทนคำสั่งที่ผู้ใช้สามารถดำเนินการได้ struct CreateTaskIntent: AppIntent { // ชื่อที่แสดงในทางลัดและ Siri static var title: LocalizedStringResource = "สร้างงาน" // คำอธิบายสำหรับการเข้าถึงและคำแนะนำ static var description = IntentDescription( "สร้างงานใหม่ในแอปพลิเคชัน" ) // พารามิเตอร์ที่มีการตรวจสอบอัตโนมัติ @Parameter(title: "ชื่องาน") var taskTitle: String // พารามิเตอร์เสริมพร้อมค่าเริ่มต้น @Parameter(title: "ลำดับความสำคัญ", default: .medium) var priority: TaskPriority // การดำเนินการคำสั่ง func perform() async throws -> some IntentResult & ReturnsValue { // สร้างงานผ่าน service let task = TaskService.shared.createTask( title: taskTitle, priority: priority ) // ส่งคืน entity ที่สร้างขึ้นเพื่อทำ chaining return .result(value: TaskEntity(task: task)) } } ``` Intent ประกาศพารามิเตอร์ผ่าน property wrapper `@Parameter` ซึ่งช่วยให้ Siri สามารถถามค่าที่ขาดได้ เมธอด `perform()` เรียกใช้ตรรกะทางธุรกิจและส่งคืนผลลัพธ์ที่กำหนดประเภท ## กำหนด App Entities สำหรับข้อมูล App Entities แทน "คำนาม" ของแอป: วัตถุที่ intents ทำงานด้วย ทำให้ Siri เข้าใจและจัดการข้อมูลของแอปได้ ```swift // TaskEntity.swift import AppIntents // โมเดลข้อมูลภายใน struct Task: Identifiable, Codable { let id: UUID var title: String var priority: TaskPriority var isCompleted: Bool var dueDate: Date? } // Entity ที่เปิดเผยต่อระบบ struct TaskEntity: AppEntity { // ตัวระบุที่ไม่ซ้ำกันที่จำเป็น var id: UUID // คุณสมบัติที่แสดงได้ var title: String var priority: TaskPriority var isCompleted: Bool // การกำหนดค่าการแสดงผลในระบบ static var typeDisplayRepresentation: TypeDisplayRepresentation = "งาน" // การแสดงผลภาพของอินสแตนซ์ var displayRepresentation: DisplayRepresentation { DisplayRepresentation( title: "\(title)", subtitle: "\(priority.rawValue)", image: .init(systemName: isCompleted ? "checkmark.circle.fill" : "circle") ) } // Query เริ่มต้นสำหรับค้นหา entity static var defaultQuery = TaskEntityQuery() // Initializer จากโมเดลภายใน init(task: Task) { self.id = task.id self.title = task.title self.priority = task.priority self.isCompleted = task.isCompleted } } // Query เพื่อค้นหาและกรอง entity struct TaskEntityQuery: EntityQuery { // ค้นหาตามตัวระบุ func entities(for identifiers: [UUID]) async throws -> [TaskEntity] { TaskService.shared.fetchTasks() .filter { identifiers.contains($0.id) } .map { TaskEntity(task: $0) } } // คำแนะนำที่แสดงในอินเทอร์เฟซ func suggestedEntities() async throws -> [TaskEntity] { TaskService.shared.fetchTasks() .filter { !$0.isCompleted } .prefix(5) .map { TaskEntity(task: $0) } } } ``` `EntityQuery` กำหนดวิธีที่ระบบค้นหาและแนะนำ entity เมธอด `entities(for:)` และ `suggestedEntities()` ป้อนข้อมูลให้กับอินเทอร์เฟซ Siri และทางลัด > **App Enums vs App Entities** > > ใช้ `AppEnum` สำหรับประเภทที่มีชุดค่าคงที่ (ลำดับความสำคัญ สถานะ) และ `AppEntity` สำหรับประเภทไดนามิกที่ผู้ใช้สร้าง (งาน บันทึก รายชื่อติดต่อ) ## สร้าง App Enums สำหรับค่าคงที่ App Enums เปิดเผยประเภทแบบ enumerated ต่อระบบ ช่วยให้ Siri เสนอตัวเลือกตามบริบท ```swift // TaskPriority.swift import AppIntents // Enum ที่เปิดเผยต่อระบบ enum TaskPriority: String, AppEnum, Codable { case low case medium case high // ชื่อประเภทที่แสดง static var typeDisplayRepresentation: TypeDisplayRepresentation = "ลำดับความสำคัญ" // การแสดงผลของแต่ละกรณี static var caseDisplayRepresentations: [TaskPriority: DisplayRepresentation] = [ .low: DisplayRepresentation( title: "ต่ำ", image: .init(systemName: "arrow.down.circle") ), .medium: DisplayRepresentation( title: "ปานกลาง", image: .init(systemName: "minus.circle") ), .high: DisplayRepresentation( title: "สูง", image: .init(systemName: "exclamationmark.circle") ) ] } // Enum สำหรับสถานะของงาน enum TaskStatus: String, AppEnum, Codable { case pending case inProgress case completed static var typeDisplayRepresentation: TypeDisplayRepresentation = "สถานะ" static var caseDisplayRepresentations: [TaskStatus: DisplayRepresentation] = [ .pending: "รอดำเนินการ", .inProgress: "กำลังดำเนินการ", .completed: "เสร็จสิ้น" ] } ``` การแสดงผลภาพ (ไอคอน SF Symbols) ทำให้การแสดงผลในทางลัดและคำแนะนำของ Siri สมบูรณ์ยิ่งขึ้น ## ใช้งาน AppShortcutsProvider `AppShortcutsProvider` เปิดเผย App Shortcuts ต่อระบบ ทำให้พร้อมใช้งานทันทีโดยไม่ต้องตั้งค่าจากผู้ใช้ ทางลัดเหล่านี้จะปรากฏใน Spotlight, Siri และ Action Button ```swift // ShortcutsProvider.swift import AppIntents // Provider ที่ประกาศทางลัดทั้งหมดของแอป struct TaskAppShortcutsProvider: AppShortcutsProvider { // สูงสุด 10 ทางลัดต่อแอปพลิเคชัน @AppShortcutsBuilder static var appShortcuts: [AppShortcut] { // ทางลัดสำหรับสร้างงาน AppShortcut( intent: CreateTaskIntent(), phrases: [ // Placeholder .applicationName เป็นข้อบังคับ "สร้างงานด้วย \(.applicationName)", "งานใหม่ใน \(.applicationName)", "เพิ่มงานใน \(.applicationName)" ], shortTitle: "สร้างงาน", systemImageName: "plus.circle" ) // ทางลัดสำหรับแสดงรายการงาน AppShortcut( intent: ListTasksIntent(), phrases: [ "แสดงงานของฉันใน \(.applicationName)", "แสดงงานจาก \(.applicationName)", "งานของฉันมีอะไรบ้าง \(.applicationName)" ], shortTitle: "งานของฉัน", systemImageName: "list.bullet" ) // ทางลัดที่มีพารามิเตอร์ไดนามิก AppShortcut( intent: CompleteTaskIntent(), phrases: [ "ทำ \(\.$taskName) ใน \(.applicationName) ให้เสร็จ", "ทำเครื่องหมาย \(\.$taskName) เสร็จด้วย \(.applicationName)" ], shortTitle: "ทำงานให้เสร็จ", systemImageName: "checkmark.circle" ) } } ``` วลีเสียงต้องประกอบด้วย placeholder `\(.applicationName)` เพื่อให้ Siri ระบุแอปเป้าหมายได้ พารามิเตอร์ไดนามิกอย่าง `\(\.$taskName)` ช่วยให้คำสั่งตามบริบทเป็นไปได้ > **ข้อจำกัด 10 ทางลัด** > > แอปสามารถประกาศได้สูงสุด 10 App Shortcuts ควรจัดลำดับความสำคัญของคำสั่งที่ใช้บ่อยและเป็นประโยชน์ที่สุดสำหรับผู้ใช้ ## Intents ที่มีพารามิเตอร์ซับซ้อน Intents สามารถรับพารามิเตอร์ที่ซับซ้อนได้ รวมถึง entity และตัวเลือกการกำหนดค่า ```swift // CompleteTaskIntent.swift import AppIntents struct CompleteTaskIntent: AppIntent { static var title: LocalizedStringResource = "ทำงานให้เสร็จ" static var description = IntentDescription( "ทำเครื่องหมายงานว่าเสร็จสิ้น" ) // พารามิเตอร์ entity ที่มีการค้นหาอัตโนมัติ @Parameter(title: "งาน") var task: TaskEntity // พารามิเตอร์เสริมพร้อมวันที่ @Parameter(title: "วันที่เสร็จสิ้น") var completionDate: Date? // การกำหนดค่ากล่องโต้ตอบ Siri static var parameterSummary: some ParameterSummary { Summary("ทำ \(\.$task) ให้เสร็จ") { \.$completionDate } } func perform() async throws -> some IntentResult & ProvidesDialog { // อัปเดตงาน TaskService.shared.completeTask( id: task.id, completionDate: completionDate ?? Date() ) // ฟีดแบ็กเสียงสำหรับ Siri return .result( dialog: "งาน \(task.title) ถูกทำเครื่องหมายเสร็จแล้ว" ) } } // Intent ที่ส่งคืนรายการ entity struct ListTasksIntent: AppIntent { static var title: LocalizedStringResource = "แสดงรายการงาน" // ตัวกรองเสริม @Parameter(title: "สถานะ", default: nil) var statusFilter: TaskStatus? @Parameter(title: "ลำดับความสำคัญ", default: nil) var priorityFilter: TaskPriority? func perform() async throws -> some IntentResult & ReturnsValue<[TaskEntity]> { var tasks = TaskService.shared.fetchTasks() // ใช้ตัวกรอง if let status = statusFilter { tasks = tasks.filter { switch status { case .completed: return $0.isCompleted case .pending, .inProgress: return !$0.isCompleted } } } if let priority = priorityFilter { tasks = tasks.filter { $0.priority == priority } } let entities = tasks.map { TaskEntity(task: $0) } return .result(value: entities) } } ``` `ParameterSummary` กำหนดวิธีที่ Siri นำเสนอ intent ในระหว่างการดำเนินการด้วยเสียง โดยให้ฟีดแบ็กที่เป็นธรรมชาติ ## การรวมกับ Apple Intelligence iOS 18 เปิดตัว App Intent Domains ซึ่งเป็นชุด API ที่ออกแบบมาสำหรับฟังก์ชันเฉพาะ Domain เหล่านี้ทำให้ Apple Intelligence เข้าใจและดำเนินการคำสั่งได้แม่นยำยิ่งขึ้น ```swift // BookmarkDomainIntents.swift import AppIntents // ปฏิบัติตามโดเมน Bookmarks สำหรับการรวม Apple Intelligence struct SaveBookmarkIntent: AppIntent { static var title: LocalizedStringResource = "บันทึกบุ๊กมาร์ก" // พารามิเตอร์ URL พร้อมการตรวจสอบอัตโนมัติ @Parameter(title: "URL") var url: URL @Parameter(title: "ชื่อ", default: nil) var title: String? @Parameter(title: "โฟลเดอร์", default: nil) var folder: BookmarkFolderEntity? // เปิดแอปเมื่อจำเป็น static var openAppWhenRun: Bool = false func perform() async throws -> some IntentResult & ProvidesDialog { let bookmark = BookmarkService.shared.save( url: url, title: title, folder: folder?.id ) return .result( dialog: "บันทึกบุ๊กมาร์กแล้ว: \(bookmark.title)" ) } } // Intent ที่รับรู้เนื้อหาบนหน้าจอ (iOS 18.4+) struct AnalyzeScreenContentIntent: AppIntent { static var title: LocalizedStringResource = "วิเคราะห์เนื้อหา" // เข้าถึงบริบทหน้าจอผ่าน Apple Intelligence @Parameter(title: "บริบท") var screenContext: String? func perform() async throws -> some IntentResult & ProvidesDialog { guard let context = screenContext else { return .result(dialog: "ไม่มีเนื้อหาให้วิเคราะห์") } // ประมวลผลเนื้อหาที่ Apple Intelligence ดึงออกมา let analysis = ContentAnalyzer.analyze(context) return .result(dialog: analysis.summary) } } ``` โดเมนที่กำหนดไว้ล่วงหน้า (Books, Camera, Spreadsheets) ช่วยให้ Siri ตอบสนองต่อคำขอได้แม่นยำด้วยโมเดลที่ฝึกมาสำหรับงานเฉพาะเหล่านี้ ## คำสั่ง Siri ที่ต้องยืนยันจากผู้ใช้ สำหรับคำสั่งที่ละเอียดอ่อน ระบบสามารถขอการยืนยันก่อนดำเนินการได้ ```swift // DeleteTaskIntent.swift import AppIntents struct DeleteTaskIntent: AppIntent { static var title: LocalizedStringResource = "ลบงาน" @Parameter(title: "งาน") var task: TaskEntity // ต้องการการยืนยันจากผู้ใช้ static var isDiscoverable: Bool = true func perform() async throws -> some IntentResult & ProvidesDialog { // ขอการยืนยันผ่านกล่องโต้ตอบ try await requestConfirmation( result: .result( dialog: "ยืนยันการลบ \(task.title) หรือไม่?" ) ) // ลบหลังจากยืนยัน TaskService.shared.deleteTask(id: task.id) return .result( dialog: "งาน \(task.title) ถูกลบแล้ว" ) } } // Intent ที่มีหลายขั้นตอนการสนทนา struct ScheduleTaskIntent: AppIntent { static var title: LocalizedStringResource = "กำหนดการงาน" @Parameter(title: "งาน") var task: TaskEntity @Parameter(title: "วันที่") var scheduledDate: Date @Parameter(title: "การแจ้งเตือน", default: true) var setReminder: Bool static var parameterSummary: some ParameterSummary { When(\.$setReminder, .equalTo, true) { Summary("กำหนด \(\.$task) เวลา \(\.$scheduledDate) พร้อมการแจ้งเตือน") } otherwise: { Summary("กำหนด \(\.$task) เวลา \(\.$scheduledDate)") } } func perform() async throws -> some IntentResult & ProvidesDialog { TaskService.shared.schedule( taskId: task.id, date: scheduledDate, reminder: setReminder ) let dateFormatter = DateFormatter() dateFormatter.dateStyle = .medium dateFormatter.timeStyle = .short let formattedDate = dateFormatter.string(from: scheduledDate) return .result( dialog: "กำหนดงานเวลา \(formattedDate) แล้ว" ) } } ``` เมธอด `requestConfirmation` หยุดการดำเนินการชั่วคราวจนกว่าผู้ใช้จะยืนยัน ป้องกันคำสั่งที่ดำเนินการโดยไม่ได้ตั้งใจ ## Intents ในวิดเจ็ตแบบโต้ตอบ App Intents รวมเข้ากับ WidgetKit ได้อย่างเป็นธรรมชาติ เพื่อสร้างวิดเจ็ตแบบโต้ตอบบน iOS 17+ ```swift // TaskWidgetIntents.swift import AppIntents import WidgetKit // Intent ที่ปรับให้เหมาะกับวิดเจ็ต (ดำเนินการรวดเร็ว) struct ToggleTaskFromWidgetIntent: AppIntent { static var title: LocalizedStringResource = "สลับงาน" @Parameter(title: "ID งาน") var taskID: String init() {} init(taskID: UUID) { self.taskID = taskID.uuidString } // ไม่มีกล่องโต้ตอบสำหรับวิดเจ็ต func perform() async throws -> some IntentResult { guard let uuid = UUID(uuidString: taskID) else { return .result() } TaskService.shared.toggleCompletion(taskId: uuid) // รีเฟรชวิดเจ็ตทันที WidgetCenter.shared.reloadTimelines(ofKind: "TaskWidget") return .result() } } // View ของวิดเจ็ตพร้อมปุ่มโต้ตอบ import SwiftUI struct TaskWidgetView: View { let task: Task var body: some View { Button(intent: ToggleTaskFromWidgetIntent(taskID: task.id)) { HStack { Image(systemName: task.isCompleted ? "checkmark.circle.fill" : "circle") .foregroundStyle(task.isCompleted ? .green : .secondary) Text(task.title) .strikethrough(task.isCompleted) } .padding() } .buttonStyle(.plain) } } ``` วิดเจ็ตใช้ไวยากรณ์ `Button(intent:)` เพื่อเชื่อมโต้ตอบเข้ากับ App Intent โดยตรงโดยไม่ต้องเปิดแอป ## การกำหนดค่า Action Button Action Button บน iPhone 15 Pro และรุ่นใหม่กว่าสามารถเรียกใช้ App Shortcuts ได้โดยตรง ```swift // ActionButtonIntent.swift import AppIntents // Intent ที่ปรับให้เหมาะกับ Action Button struct QuickCaptureIntent: AppIntent { static var title: LocalizedStringResource = "บันทึกด่วน" static var description = IntentDescription( "สร้างงานพร้อมชื่ออย่างรวดเร็ว" ) // เปิดแอปเพื่อรับอินพุต static var openAppWhenRun: Bool = true func perform() async throws -> some IntentResult & OpensIntent { // การแจ้งเตือนเพื่อเปิดหน้าจอบันทึกด่วน NotificationCenter.default.post( name: .quickCaptureTriggered, object: nil ) return .result(opensIntent: ShowQuickCaptureViewIntent()) } } // ประกาศใน AppShortcutsProvider สำหรับ Action Button extension TaskAppShortcutsProvider { @AppShortcutsBuilder static var appShortcuts: [AppShortcut] { // ... ทางลัดอื่น ๆ AppShortcut( intent: QuickCaptureIntent(), phrases: [ "บันทึกด่วน \(.applicationName)", "บันทึกย่อด่วน \(.applicationName)" ], shortTitle: "บันทึก", systemImageName: "bolt.circle" ) } } ``` ผู้ใช้สามารถกำหนดค่า Action Button ให้เรียกใช้ทางลัดนี้ได้ผ่าน การตั้งค่า > Action Button > **Macros iOS 18+** > > iOS 18 เปิดตัว macro `@DeferredProperty` และ `@ComputedProperty` เพื่อลด boilerplate App Intents ยังสามารถอยู่ใน Swift Packages เพื่อใช้ซ้ำข้ามแพลตฟอร์มได้ ## Intents ใน Swift Packages App Intents สามารถกำหนดได้ใน Swift Packages เพื่อใช้ร่วมกันระหว่าง iOS, macOS และ watchOS ```swift // Package.swift // swift-tools-version: 5.9 import PackageDescription let package = Package( name: "TaskIntents", platforms: [ .iOS(.v17), .macOS(.v14), .watchOS(.v10) ], products: [ .library(name: "TaskIntents", targets: ["TaskIntents"]) ], dependencies: [], targets: [ .target( name: "TaskIntents", dependencies: [] ) ] ) // Sources/TaskIntents/SharedIntents.swift import AppIntents // Intent ที่ใช้ร่วมกันข้ามแพลตฟอร์ม public struct SharedCreateTaskIntent: AppIntent { public static var title: LocalizedStringResource = "สร้างงาน" @Parameter(title: "ชื่อ") public var taskTitle: String public init() {} public func perform() async throws -> some IntentResult { // ตรรกะที่ใช้ร่วมกัน await TaskRepository.shared.create(title: taskTitle) return .result() } } // ส่วนขยายเฉพาะแพลตฟอร์มในแอป #if os(iOS) extension SharedCreateTaskIntent { // พฤติกรรมเฉพาะ iOS static var openAppWhenRun: Bool = false } #endif ``` สถาปัตยกรรมนี้รักษาฐานโค้ดเดียวสำหรับ intents ในขณะที่ปรับพฤติกรรมตามแพลตฟอร์ม ## ทดสอบ App Intents App Intents สามารถทดสอบหน่วยได้เช่นเดียวกับโค้ด Swift ใด ๆ ```swift // TaskIntentTests.swift import XCTest import AppIntents @testable import TaskApp final class TaskIntentTests: XCTestCase { override func setUp() { super.setUp() // รีเซ็ต service สำหรับการทดสอบที่แยกอิสระ TaskService.shared.reset() } func testCreateTaskIntent() async throws { // Given var intent = CreateTaskIntent() intent.taskTitle = "งานทดสอบ" intent.priority = .high // When let result = try await intent.perform() // Then let tasks = TaskService.shared.fetchTasks() XCTAssertEqual(tasks.count, 1) XCTAssertEqual(tasks.first?.title, "งานทดสอบ") XCTAssertEqual(tasks.first?.priority, .high) } func testCompleteTaskIntent() async throws { // Given let task = TaskService.shared.createTask( title: "งานที่ต้องทำให้เสร็จ", priority: .medium ) var intent = CompleteTaskIntent() intent.task = TaskEntity(task: task) // When _ = try await intent.perform() // Then let updatedTask = TaskService.shared.fetchTask(id: task.id) XCTAssertTrue(updatedTask?.isCompleted ?? false) } func testEntityQuery() async throws { // Given let task1 = TaskService.shared.createTask(title: "งาน 1", priority: .low) let task2 = TaskService.shared.createTask(title: "งาน 2", priority: .high) let query = TaskEntityQuery() // When let entities = try await query.entities(for: [task1.id, task2.id]) // Then XCTAssertEqual(entities.count, 2) } } ``` การทดสอบยืนยันพฤติกรรมของ intents โดยอิสระจากอินเทอร์เฟซระบบ ## แนวทางปฏิบัติที่ดีที่สุดและการเพิ่มประสิทธิภาพ หลายรูปแบบช่วยให้ App Intents มีประสิทธิภาพและประสบการณ์ผู้ใช้ที่ดีที่สุด ```swift // BestPractices.swift import AppIntents // 1. วลีที่แปลแล้ว struct LocalizedTaskIntent: AppIntent { static var title: LocalizedStringResource = "task.create.title" static var description = IntentDescription( "task.create.description", categoryName: "task.category" ) @Parameter(title: "task.parameter.title") var taskTitle: String func perform() async throws -> some IntentResult { // ... return .result() } } // 2. การจัดการข้อผิดพลาดที่เหมาะสม enum TaskIntentError: Error, CustomLocalizedStringResourceConvertible { case taskNotFound case invalidInput case serviceUnavailable var localizedStringResource: LocalizedStringResource { switch self { case .taskNotFound: return "ไม่พบงาน" case .invalidInput: return "ข้อมูลไม่ถูกต้อง" case .serviceUnavailable: return "บริการไม่พร้อมใช้งานชั่วคราว" } } } struct RobustTaskIntent: AppIntent { static var title: LocalizedStringResource = "Intent ที่แข็งแกร่ง" @Parameter(title: "ID") var taskId: String func perform() async throws -> some IntentResult & ProvidesDialog { guard let uuid = UUID(uuidString: taskId) else { throw TaskIntentError.invalidInput } guard let task = TaskService.shared.fetchTask(id: uuid) else { throw TaskIntentError.taskNotFound } return .result(dialog: "พบงาน: \(task.title)") } } // 3. การเพิ่มประสิทธิภาพ EntityQuery struct OptimizedTaskQuery: EntityStringQuery { // การค้นหาข้อความที่ปรับปรุง func entities(matching string: String) async throws -> [TaskEntity] { // ค้นหาฝั่ง service พร้อมขีดจำกัด TaskService.shared.search(query: string, limit: 10) .map { TaskEntity(task: $0) } } // คำแนะนำที่จำกัดเพื่อประสิทธิภาพ func suggestedEntities() async throws -> [TaskEntity] { TaskService.shared.fetchRecentTasks(limit: 5) .map { TaskEntity(task: $0) } } } // 4. Focus Filter สำหรับโหมดสมาธิ struct TaskFocusFilter: SetFocusFilterIntent { static var title: LocalizedStringResource = "กรองงาน" @Parameter(title: "แสดงเฉพาะลำดับความสำคัญสูง") var showHighPriorityOnly: Bool func perform() async throws -> some IntentResult { TaskService.shared.setFocusFilter(highPriorityOnly: showHighPriorityOnly) return .result() } } ``` รูปแบบเหล่านี้รับประกันการรวมที่ราบรื่นกับระบบในขณะที่รักษาประสิทธิภาพที่ดีที่สุด ## บทสรุป App Intents และ Siri Shortcuts เปลี่ยนวิธีที่ผู้ใช้โต้ตอบกับแอป iOS ในปี 2026 ด้วย Apple Intelligence การเปิดเผย intents ไม่ใช่ทางเลือกอีกต่อไปแต่เป็นสิ่งจำเป็นในการมอบประสบการณ์ที่ทันสมัยและใช้งานง่าย ### รายการตรวจสอบ App Intents iOS 18+ - ✅ สร้าง AppIntents สำหรับคำสั่งหลักของแอป - ✅ กำหนด AppEntities สำหรับข้อมูลที่จัดการได้ - ✅ ใช้ AppEnum สำหรับประเภทแบบ enumerated - ✅ ใช้งาน AppShortcutsProvider พร้อมวลีเสียง - ✅ ปฏิบัติตามขีดจำกัดสูงสุด 10 App Shortcuts - ✅ รวม `\(.applicationName)` ในทุกวลี - ✅ กำหนดค่า ParameterSummary สำหรับฟีดแบ็ก Siri - ✅ รวมโดเมน Apple Intelligence เมื่อเหมาะสม - ✅ ทดสอบ intents ด้วยการทดสอบหน่วย - ✅ แปลชื่อและคำอธิบาย --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/th/blog/ios/app-intents-siri-shortcuts-advanced-ios-automation