Section 14/181 menit

14. Troubleshooting & Kesalahan Umum

14. Troubleshooting & Kesalahan Umum

Intent Tidak Muncul di Shortcuts/Siri

swift
// Pastikan intent ter-register di build time — cek apakah struct public/internal
// App Intents extractor hanya menemukan tipe yang bisa diakses

// ❌ Salah: private struct tidak ditemukan extractor
private struct MyIntent: AppIntent { /* ... */ }

// ✓ Benar: internal (default) atau public
struct MyIntent: AppIntent { /* ... */ }

// Juga pastikan semua required properties di-implement:
struct MyIntent: AppIntent {
    static var title: LocalizedStringResource = "..."  // ← wajib
    func perform() async throws -> some IntentResult { .result() }  // ← wajib
}

AppShortcut Phrase Tidak Dikenali Siri

swift
// Phrase wajib mengandung \(.applicationName) — tanpanya Siri tidak bisa associate ke app
AppShortcut(
    intent: MyIntent(),
    phrases: [
        // ❌ Salah: tidak ada applicationName
        "Buka menu",
        
        // ✓ Benar: ada applicationName
        "Buka menu di \(.applicationName)",
        "Tampilkan menu \(.applicationName)"
    ],
    shortTitle: "Buka Menu",
    systemImageName: "list.bullet"
)

Entity Query Tidak Sinkron

swift
// Setelah data berubah, panggil updateAppShortcutParameters() agar sistem tahu
// Ini penting untuk Spotlight indexing dan Siri suggestions

class TaskRepository {
    func create(title: String) async throws -> Task {
        let task = Task(/* ... */)
        try await save(task)
        
        // ← Ini yang sering dilupakan
        await AppShortcuts.updateAppShortcutParameters()
        
        return task
    }
}

Compile Error: "Type does not conform to IntentResult"

swift
// IntentResult harus return protocol composition — bukan concrete type
// ❌ Salah
func perform() async throws -> IntentResultContainer {
    return IntentResultContainer()
}

// ✓ Benar: gunakan some + protocol composition
func perform() async throws -> some IntentResult {
    return .result()
}

func perform() async throws -> some IntentResult & ProvidesDialog {
    return .result(dialog: "Berhasil!")
}

func perform() async throws -> some IntentResult & ReturnsValue<String> & ProvidesDialog {
    return .result(value: "output", dialog: "Selesai!")
}

Performance: Hindari Heavy Work di suggestedEntities()

swift
// suggestedEntities() dipanggil saat user tap parameter picker — harus cepat
// ❌ Salah: fetch semua data dari network
func suggestedEntities() async throws -> [TaskEntity] {
    let all = try await APIClient.shared.fetchAllTasksFromServer()  // bisa 2–5 detik
    return all.map { TaskEntity(task: $0) }
}

// ✓ Benar: fetch dari local cache, limit jumlah
func suggestedEntities() async throws -> [TaskEntity] {
    let recent = try await TaskRepository.shared.fetchRecent(limit: 20)  // local, cepat
    return recent.map { TaskEntity(task: $0) }
}