Code Block // // IntentHandler.swift // SiriExtension import Intents class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessagesIntentHandling { override func handler(for intent: INIntent) -> Any { // This is the default implementation. If you want different objects to handle different intents, // you can override this and return the handler you want for that particular intent. switch intent { case is AddAttendeeIntent: return AddAttendeeIntentHandler() case is RemoveAttendeeIntent: return RemoveAttendeeIntentHandler() case is StartMeetingIntent: return StartMeetingIntentHandler() case is EndMeetingIntent: return EndMeetingIntent() case is ResetMeetingIntent: return ResetMeetingIntent() case is QuorumReachedIntent: return QuorumReachedIntent() default: fatalError("No handler for this intent") } } func resolveRecipients(for intent: INSendMessageIntent, with completion: @escaping ([INSendMessageRecipientResolutionResult]) -> Void) { if let recipients = intent.recipients { // If no recipients were provided we'll need to prompt for a value. if recipients.count == 0 { completion([INSendMessageRecipientResolutionResult.needsValue()]) return } var resolutionResults = [INSendMessageRecipientResolutionResult]() for recipient in recipients { let matchingContacts = [recipient] // Implement your contact matching logic here to create an array of matching contacts switch matchingContacts.count { case 2 ... Int.max: // We need Siri's help to ask user to pick one from the matches. resolutionResults += [INSendMessageRecipientResolutionResult.disambiguation(with: matchingContacts)] case 1: // We have exactly one matching contact resolutionResults += [INSendMessageRecipientResolutionResult.success(with: recipient)] case 0: // We have no contacts matching the description provided resolutionResults += [INSendMessageRecipientResolutionResult.unsupported()] default: break } } completion(resolutionResults) } } func resolveContent(for intent: INSendMessageIntent, with completion: @escaping (INStringResolutionResult) -> Void) { if let text = intent.content, !text.isEmpty { completion(INStringResolutionResult.success(with: text)) } else { completion(INStringResolutionResult.needsValue()) } } // Once resolution is completed, perform validation on the intent and provide confirmation (optional). func confirm(intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) { // Verify user is authenticated and your app is ready to send a message. let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self)) let response = INSendMessageIntentResponse(code: .ready, userActivity: userActivity) completion(response) } // Handle the completed intent (required). func handle(intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) { // Implement your application logic to send a message here. let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self)) let response = INSendMessageIntentResponse(code: .success, userActivity: userActivity) completion(response) } // MARK: - INSearchForMessagesIntentHandling func handle(intent: INSearchForMessagesIntent, completion: @escaping (INSearchForMessagesIntentResponse) -> Void) { // Return success to launch your Watch application with userActivity containing information for the message search on the interaction. let userActivity = NSUserActivity(activityType: NSStringFromClass(INSearchForMessagesIntent.self)) let response = INSearchForMessagesIntentResponse(code: .success, userActivity: userActivity) completion(response) } }
App crashes Springboard when IntentHandler embedded
import Intents import IntentsUI import os
// MARK: - IntentHandler Class
class IntentHandler: INExtension {
// MARK: - Providing the Handler for a Specific Intent
override func handler(for intent: INIntent) -> Any {
os_log("IntentHandler: Checking intent type...", log: .default, type: .info)
print("IntentHandler: Received intent: \(intent)")
if intent is QuickViewSearchIntent {
os_log("IntentHandler: Handling QuickViewSearchIntent", log: .default, type: .info)
print("IntentHandler: QuickViewSearchIntent identified.")
return self
}
print("IntentHandler: No matching intent found.")
return self // Handle other intents if necessary
}
}
// MARK: - QuickViewSearchIntent Handling Extension
extension IntentHandler: QuickViewSearchIntentHandling {
// MARK: - Resolve ID (Sync and Async)
func resolveId(for intent: QuickViewSearchIntent, with completion: @escaping (INStringResolutionResult) -> Void) {
print("IntentHandler: resolveId() invoked with ID: \(String(describing: intent.id))")
os_log("IntentHandler: Resolving ID...", log: .default, type: .info)
if let id = intent.id, !id.isEmpty {
print("IntentHandler: ID resolved successfully.")
completion(.success(with: id))
} else {
print("IntentHandler: No ID provided, prompting for value.")
completion(.needsValue())
}
}
// MARK: - Handle Method
func handle(intent: QuickViewSearchIntent, completion: @escaping (QuickViewSearchIntentResponse) -> Void) {
guard let id = intent.id, !id.isEmpty else {
let response = QuickViewSearchIntentResponse(code: .failure, userActivity: nil)
completion(response)
return
}
let listSize = addBill(id: id) // This method will return the number of invoices
let successMessage = "Total invoices: \(listSize)"
// Create a user activity to pass to the app
let userActivity = NSUserActivity(activityType: "group.com.gis247.QuickViewSearch")
userActivity.userInfo = ["id": id, "invoiceCount": listSize] // Include invoice count
let response = QuickViewSearchIntentResponse.success(searchProduct: successMessage)
response.userActivity = userActivity
completion(response)
}
// MARK: - Helper Method to Add Bill
private func addBill(id: String) -> Int {
let newBill = ["id": id]
print("IntentHandler: Adding new bill: \(newBill)")
guard let userDefaults = UserDefaults(suiteName: "group.com.gis247.SiriExtension") else {
print("IntentHandler: Failed to access UserDefaults.")
return 0
}
var data: [[String: Any]] = userDefaults.array(forKey: "BillData") as? [[String: Any]] ?? []
data.append(newBill)
userDefaults.set(data, forKey: "BillData")
print("IntentHandler: BillData saved. New data: \(data)")
return data.count
}
// private func addBill(id: String) -> Int { // var data: [[String: Any]] = [] // let newBill = ["id": id] // // print("IntentHandler: Adding new bill: (newBill)") // os_log("IntentHandler: Adding new bill...", log: .default, type: .info) // // guard let userDefaults = UserDefaults(suiteName: "group.com.gis247.SiriExtension") else { // print("IntentHandler: Failed to access UserDefaults.") // return 0 // } // // // Synchronize access to avoid desync issues // DispatchQueue.global(qos: .userInitiated).sync { // if let existingBills = userDefaults.array(forKey: "BillData") as? [[String: Any]] { // data = existingBills // print("IntentHandler: Existing bills: (data)") // } // // data.append(newBill) // userDefaults.set(data, forKey: "BillData") // userDefaults.synchronize() // Force write immediately (use with caution) // print("IntentHandler: BillData saved. New data: (data)") // } // // return data.count // } }
i also have issue in this