如何用Swift通过SiriKit在iOS应用中集成视觉码并实现扫码支付等功能
Hey there! Let's walk through exactly how to integrate visual code (QR code) scanning with SiriKit in your iOS app using Swift—covering payments, money requests, and contact sharing. I’ve broken this down into actionable steps to make it straightforward:
First, make sure you have these covered:
- iOS 13+ deployment target (Siri’s visual code scanning support starts here)
- Xcode 11+
- An Apple Developer account (to enable SiriKit capabilities)
- Camera permission (required for scanning QR codes)
Head to your project settings to flip the necessary switches:
- Open your target > Signing & Capabilities
- Click the
+ Capabilitybutton and add Siri and Camera - Open
Info.plistand add these permission descriptions (users will see these when granting access):NSSiriUsageDescription: "Allow Siri to scan QR codes for payments, money requests, and contact sharing"NSCameraUsageDescription: "Need camera access to scan QR codes"
SiriKit relies on custom intents to understand and handle your specific tasks. Here’s how to set them up:
- Right-click your project > New File > Select Intent Definition File (name it something like
CustomIntents.intentdefinition) - Open the file and add three intents tailored to your needs:
- ScanQRForPaymentIntent (for payments)
- Add parameters:
amount(NSDecimalNumber),recipientIdentifier(String) - Set Intent Category to Payments
- For
recipientIdentifier, set Input Type to Visual Code, enable QR Code support, and choose "Extract text from code"
- Add parameters:
- ScanQRForMoneyRequestIntent (for requesting payments)
- Add parameters:
requestAmount(NSDecimalNumber),payerIdentifier(String) - Repeat the visual code setup for
payerIdentifier - Category: Payments
- Add parameters:
- ScanQRForContactShareIntent (for contact sharing)
- Add parameter:
contactData(INPerson) - For
contactData, set Input Type to Visual Code and configure to extract contact data (Siri can parse vCard-formatted QR codes automatically) - Category: Contacts
- Add parameter:
- ScanQRForPaymentIntent (for payments)
- Check Generate Swift Code at the top of the intent editor—Xcode will auto-create the necessary classes and protocols.
Create a handler class to process the intents and execute your app’s logic. Make a new file CustomIntentHandler.swift:
import Intents class CustomIntentHandler: INExtension, ScanQRForPaymentIntentHandling, ScanQRForMoneyRequestIntentHandling, ScanQRForContactShareIntentHandling { // Handle payment intent func handle(intent: ScanQRForPaymentIntent, completion: @escaping (ScanQRForPaymentIntentResponse) -> Void) { guard let amount = intent.amount, let qrText = intent.recipientIdentifier else { completion(ScanQRForPaymentIntentResponse(code: .failure, userActivity: nil)) return } // Parse QR code text (adjust this to match your QR data format) if let paymentData = parseQRCodeText(qrText), let recipientID = paymentData["recipient"] as? String { // Replace with your actual payment logic (e.g., call a payment SDK) let paymentSuccess = true if paymentSuccess { completion(ScanQRForPaymentIntentResponse(code: .success, userActivity: nil)) } else { completion(ScanQRForPaymentIntentResponse(code: .failurePaymentFailed, userActivity: nil)) } } else { completion(ScanQRForPaymentIntentResponse(code: .failureInvalidQRCode, userActivity: nil)) } } // Handle money request intent func handle(intent: ScanQRForMoneyRequestIntent, completion: @escaping (ScanQRForMoneyRequestIntentResponse) -> Void) { guard let amount = intent.requestAmount, let qrText = intent.payerIdentifier else { completion(ScanQRForMoneyRequestIntentResponse(code: .failure, userActivity: nil)) return } // Parse QR data and trigger your request logic let requestSent = true // Replace with actual result if requestSent { completion(ScanQRForMoneyRequestIntentResponse(code: .success, userActivity: nil)) } else { completion(ScanQRForMoneyRequestIntentResponse(code: .failure, userActivity: nil)) } } // Handle contact share intent func handle(intent: ScanQRForContactShareIntent, completion: @escaping (ScanQRForContactShareIntentResponse) -> Void) { guard let contact = intent.contactData else { completion(ScanQRForContactShareIntentResponse(code: .failure, userActivity: nil)) return } // Save or share the contact (e.g., add to device contacts) let contactSaved = true // Replace with actual result if contactSaved { completion(ScanQRForContactShareIntentResponse(code: .success, userActivity: nil)) } else { completion(ScanQRForContactShareIntentResponse(code: .failure, userActivity: nil)) } } // Helper to parse structured QR code data (e.g., JSON) private func parseQRCodeText(_ text: String) -> [String: Any]? { guard let data = text.data(using: .utf8) else { return nil } return try? JSONSerialization.jsonObject(with: data) as? [String: Any] } override func handler(for intent: INIntent) -> Any { return self } }
Note: Add custom error codes (like failureInvalidQRCode) in your intent definition file to make error handling more specific.
There are two main ways to let users start scanning via Siri:
Option 1: Voice Shortcuts
Add a button to your app to let users create a custom voice command:
import IntentsUI // In your view controller override func viewDidLoad() { super.viewDidLoad() let paymentIntent = ScanQRForPaymentIntent() paymentIntent.suggestedInvocationPhrase = "Pay with QR code" let shortcut = INShortcut(intent: paymentIntent) let shortcutButton = INUIAddVoiceShortcutButton(style: .whiteOutline) shortcutButton.shortcut = shortcut shortcutButton.center = view.center view.addSubview(shortcutButton) }
Users can tap this button to record a phrase like "Pay my coffee bill" to trigger the scan.
Option 2: Direct Siri Command
Users can also trigger the intent directly by saying something like:
- "Hey Siri, scan a QR code to pay"
- "Hey Siri, request money via QR code"
Siri will automatically launch the camera to scan the QR code, parse the data, and pass it to your intent handler.
- Run your app on a physical iOS device (Siri doesn’t work on simulators)
- First, request Siri authorization on app launch:
import Intents func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { INPreferences.requestSiriAuthorization { status in // Handle authorization status (e.g., show a prompt if denied) } return true } - Test each intent by triggering Siri, scanning a test QR code, and verifying your app’s logic runs as expected.
- Use structured QR data (like JSON or vCard for contacts) to make parsing reliable
- Add loading states and clear error messages for users during payment/request flows
- Follow Apple’s SiriKit Design Guidelines to ensure natural voice interactions
内容的提问来源于stack exchange,提问作者Jaydeep Patel

