App Intents และ Siri Shortcuts: ระบบอัตโนมัติ iOS ขั้นสูงปี 2026
คู่มือฉบับสมบูรณ์เกี่ยวกับ App Intents และ Siri Shortcuts สำหรับ iOS 18+ สร้างคำสั่ง Siri ที่กำหนดเอง รวม Apple Intelligence และทำให้แอป Swift เป็นอัตโนมัติในปี 2026

ในปี 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
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<TaskEntity> {
// สร้างงานผ่าน 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 เข้าใจและจัดการข้อมูลของแอปได้
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 และทางลัด
ใช้ AppEnum สำหรับประเภทที่มีชุดค่าคงที่ (ลำดับความสำคัญ สถานะ) และ AppEntity สำหรับประเภทไดนามิกที่ผู้ใช้สร้าง (งาน บันทึก รายชื่อติดต่อ)
สร้าง App Enums สำหรับค่าคงที่
App Enums เปิดเผยประเภทแบบ enumerated ต่อระบบ ช่วยให้ Siri เสนอตัวเลือกตามบริบท
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
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 App Shortcuts ควรจัดลำดับความสำคัญของคำสั่งที่ใช้บ่อยและเป็นประโยชน์ที่สุดสำหรับผู้ใช้
Intents ที่มีพารามิเตอร์ซับซ้อน
Intents สามารถรับพารามิเตอร์ที่ซับซ้อนได้ รวมถึง entity และตัวเลือกการกำหนดค่า
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 ในระหว่างการดำเนินการด้วยเสียง โดยให้ฟีดแบ็กที่เป็นธรรมชาติ
พร้อมที่จะพิชิตการสัมภาษณ์ iOS แล้วหรือยังครับ?
ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ
การรวมกับ Apple Intelligence
iOS 18 เปิดตัว App Intent Domains ซึ่งเป็นชุด API ที่ออกแบบมาสำหรับฟังก์ชันเฉพาะ Domain เหล่านี้ทำให้ Apple Intelligence เข้าใจและดำเนินการคำสั่งได้แม่นยำยิ่งขึ้น
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 ที่ต้องยืนยันจากผู้ใช้
สำหรับคำสั่งที่ละเอียดอ่อน ระบบสามารถขอการยืนยันก่อนดำเนินการได้
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+
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 ได้โดยตรง
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
iOS 18 เปิดตัว macro @DeferredProperty และ @ComputedProperty เพื่อลด boilerplate App Intents ยังสามารถอยู่ใน Swift Packages เพื่อใช้ซ้ำข้ามแพลตฟอร์มได้
Intents ใน Swift Packages
App Intents สามารถกำหนดได้ใน Swift Packages เพื่อใช้ร่วมกันระหว่าง iOS, macOS และ watchOS
// 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 ใด ๆ
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 มีประสิทธิภาพและประสบการณ์ผู้ใช้ที่ดีที่สุด
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 ด้วยการทดสอบหน่วย
- ✅ แปลชื่อและคำอธิบาย
เริ่มฝึกซ้อมเลย!
ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ
แท็ก
แชร์
บทความที่เกี่ยวข้อง

WidgetKit iOS 17+: Widget แบบโต้ตอบด้วย App Intents
คู่มือฉบับสมบูรณ์ในการสร้าง iOS widget แบบโต้ตอบด้วย WidgetKit และ App Intents ปุ่ม สวิตช์ แอนิเมชัน และแนวปฏิบัติที่ดีที่สุดสำหรับ iOS 17+ ในปี 2026

Combine vs async/await ใน Swift: รูปแบบการย้ายระบบแบบค่อยเป็นค่อยไป
คู่มือฉบับสมบูรณ์สำหรับการย้ายจาก Combine ไปยัง async/await ใน Swift: กลยุทธ์แบบค่อยเป็นค่อยไป รูปแบบการเชื่อมโยง และการอยู่ร่วมกันของกระบวนทัศน์ในโค้ดเบส iOS

คำถามสัมภาษณ์การเข้าถึง iOS ในปี 2026: VoiceOver และ Dynamic Type
เตรียมตัวสัมภาษณ์ iOS ด้วยคำถามสำคัญเรื่องการเข้าถึง: VoiceOver, Dynamic Type, traits เชิงความหมาย และการตรวจสอบ.