I'm trying to add Siri support to my app for sending voice messages. I've implemented INSendMessageIntentHandling in my main app target.
It looks like it's getting as far as recording the voice message and passing my intent handler an INSendMessageIntent with an audio attachment, but I'm not able to read the attachment file.
func handle(
intent: INSendMessageIntent,
completion: @escaping (INSendMessageIntentResponse) -> Void
) {
if let attachment = intent.attachments?.first,
let audioFile = attachment.audioMessageFile,
let fileURL = audioFile.fileURL
{
// This branch runs
// fileURL is "file:///var/mobile/tmp/SiriMessages/89F738F7-6092-439A-B4FA-2DD9A99F0EED.caf"
let result = processMessageAudio(url: fileURL)
completion(result)
return
}
// This line isn't reached
completion(.init(code: .failure, userActivity: nil))
}
private func processMessageAudio(url: URL) -> INSendMessageIntentResponse {
var fileRef: ExtAudioFileRef?
if url.startAccessingSecurityScopedResource() {
logDebug("File access allowed")
} else {
// This branch runs
logDebug("File access not allowed")
}
defer {
url.stopAccessingSecurityScopedResource()
}
let openStatus = ExtAudioFileOpenURL(url as CFURL, &fileRef)
// openStatus is -54 (kAudio_FilePermissionError)
return INSendMessageIntentResponse(code: .failure, userActivity: nil)
}
I'm not sure what I'm missing. It looks like there should be an audio file, and Siri shows a preview of the audio for confirmation.
Siri and Voice
RSS for tagHelp users quickly accomplish tasks related to your app using just their voice.
Posts under Siri and Voice tag
70 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hello!
When trying to talk to text on CarPlay Siri would trip out, as if it were receiving a bunch of concurrent audio inputs.
When I tried to video the issue with my phone it worked perfectly. My guess is when videoing the video app was now using my phones mic so it wasn't available for CarPlay and it only received audio input from the car microphone.
It's weird because other voice commands and phone calls work just fine.
This also happens on every iPhone we connect.
My guess is there's some bug where the phone's microphone isn't being shut off properly when plugged in for CarPlay.
I reformatted the Alpine iLX-W670 radio and updated firmware.
Got new authentic Apple cable
Not sure what else to try.
Hi All,
requirement - "Search (placeholder) in (myApp)".
When user speaks this strings, Siri should open the app and pass the placeholder.
This worked for me only when i used an AppEnum (with specific defined set) with AppEntity.
I want the placeholder to be dynamic and not defined via the AppEnum.
Have observed this feature working fine with Youtube, Spotify & Whatsapp apps.
Is there anything else that these app add specifically to make this work. ?
Also in these app's Siri settings, there is a toggle named - 'Use with Ask Siri'.
Could someone please help in understanding, how this option is enabled ?
I have implemented a custom AppIntent in a macOS (14+) application and also added AppShortcuts. However whenever I try to launch it from Siri I get "Sorry something went wrong". In the documentation it states that Siri should automagically index and pick up these shortcuts/ intents. What ma I missing ?
Xcode Version 16.0 (16A242d)
iOS18 - Swift
There seems to be a behavior change on iOS18 when using AppShortcuts and AppIntents to pass string parameters. After Siri prompts for a string property requestValueDialog, if the user makes a statement the string is passed. If the user's statement is a question, however, the string is not sent to the AppIntent and instead Siri attempts to answer that question.
Example Code:
struct MyAppNameShortcuts: AppShortcutsProvider {
@AppShortcutsBuilder
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: AskQuestionIntent(),
phrases: [
"Ask \(.applicationName) a question",
]
)
}
}
struct AskQuestionIntent: AppIntent {
static var title: LocalizedStringResource = .init(stringLiteral: "Ask a question")
static var openAppWhenRun: Bool = false
static var parameterSummary: some ParameterSummary {
Summary("Search for \(\.$query)")
}
@Dependency
private var apiClient: MockApiClient
@Parameter(title: "Query", requestValueDialog: .init(stringLiteral: "What would you like to ask?"))
var query: String
// perform is not called if user asks a question such as "What color is the moon?" in response to requestValueDialog
// iOS 17, the same string is passed though
@MainActor
func perform() async throws -> some IntentResult & ProvidesDialog & ShowsSnippetView {
print("Query is: \(query)")
let queryResult = try await apiClient.askQuery(queryString: query)
let dialog = IntentDialog(
full: .init(stringLiteral: queryResult.answer),
supporting: .init(stringLiteral: "The answer to \(queryResult.question) is...")
)
let view = SiriAnswerView(queryResult: queryResult)
return .result(dialog: dialog, view: view)
}
}
Given the above mock code:
iOS17:
Hey Siri
Ask (AppName) a question
Siri responds "What would you like to ask?"
Say "What color is the moon?"
String of "What color is the moon?" is passed to the AppIntent
iOS18:
Hey Siri
Ask (AppName) a question
Siri responds "What would you like to ask?"
Say "What color is the moon?"
Siri answers the question "What color is the moon?"
Follow above steps again and instead reply "Moon"
"Moon" is passed to AppIntent
Basically any interrogative string parameters seem to be intercepted and sent to Siri proper rather than the provided AppIntent in iOS 18
Hello everyone,
I’m experiencing an issue with App Clips Advanced Experiences and Apple Maps/Siri Suggestions. We have already contacted Apple Support before, but they are investigating the cause of this issue and it has not been resolved til date.
The App Clip is bundled with the main app and has been already available on the App Store for several months. The business running the app has several physical shops and wants to offer the App Clip to show up in Apple Maps and Siri Suggestions at each location.
The App Clip is correctly exposed in the AASA file, and it's also validated correctly by the AASA APIs available at https://app-site-association.cdn-apple.com/a/v1.
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.bundleid",
"paths": []
}
]
},
"appclips": {
"apps": [
"TEAMID.bundleid.Clip"
]
}
}
(with TEAMID and bundleid being the team and bundle identifiers of the app)
The App Clip is displayed correctly when loading the website and when scanning a QR code or App Clip code, but doesn't appear in the Maps app or in Siri suggestions.
We have set up the App Clip Advanced Experiences on the App Store Connect page of the app, and each URL has been linked to a physical shop. All URLs are in the "Received" state, so they should appear correctly on Maps.
Unfortunately, I don't see any "Order" button in Apple Maps at any location card. We tried with both iOS 17 and 16. According to feedbacks from people in the shops, they don't see the app suggested in the Siri Suggestions.
I have just submitted a Custom Action Link on Apple Business Connect for one of the shops, but without success: the App Clip doesn't appear.
Any idea why is this happening?
Topic:
App & System Services
SubTopic:
Maps & Location
Tags:
App Clips
App Store Connect
Siri and Voice
Maps and Location
guard let fileURL = intent.attachments?.first?.audioMessageFile?.fileURL else {
print("Couldn't get fileNameWithExtension from intent.attachments?.first?.audioMessageFile?.fileURL?.lastPathComponent")
return failureResponse
}
defer {
fileURL.stopAccessingSecurityScopedResource()
}
let fileURLAccess = fileURL.startAccessingSecurityScopedResource()
print("FileURL: \(fileURLAccess)")
let tempDirectory = FileManager.default.temporaryDirectory
let tempFileURL = tempDirectory.appendingPathComponent(UUID().uuidString + "_" + fileURL.lastPathComponent)
do {
// Check if the file exists at the provided URL
guard FileManager.default.fileExists(atPath: fileURL.path) else {
print("Audio file does not exist at \(fileURL)")
return failureResponse
}
fileURL.stopAccessingSecurityScopedResource()
// Check if the temporary file already exists and remove it if necessary
if FileManager.default.fileExists(atPath: tempFileURL.path) {
try FileManager.default.removeItem(at: tempFileURL)
print("Removed existing temporary file at \(tempFileURL)")
}
// Copy the audio file to the temporary directory
try FileManager.default.copyItem(at: fileURL, to: tempFileURL)
print("Successfully copied audio file from \(fileURL) to \(tempFileURL)")
// Update your response based on the successful upload
// ...
} catch {
// Handle any errors that occur during file operations
print("Error handling audio file: \(error.localizedDescription)")
return failureResponse
}
guard let audioData = try? Data(contentsOf: tempFileURL), !audioData.isEmpty else {
print("Couldn't get audioData from intent.attachments?.first?.audioMessageFile?.data")
return failureResponse
}
Error:
FileURL: false
Audio file does not exist at file:///var/mobile/tmp/SiriMessages/BD57CB69-1E75-4429-8991-095CB90959A9.caf
is something I'm missing?
I'd like to build an AppIntent where the parameters are included in the initial invocation.
First-party example "Set a timer for 10 minutes" immediately sets new timer using the parameter 10 minutes.
Is this possible via AppIntents? Or do we have to invoke with "Set a timer" then give parameters via dialog: "for how long"? with user replying "10 minutes."
I'm currently testing the announce notifications feature and I can't seem to find out how to make Siri read aloud the current currency instead of dollars.
My locale is es-CL (Chile). It uses the currency symbol $ and reads as Pesos locally or Chilean Pesos where the number 5000.1 is represented as 5.000,1
This is the notification content
let content = UNMutableNotificationContent()
content.body = "¡Has recibido un pago por $5.000!"
Siri reads it aloud as "¡Has recibido un pago por 5.000 Dolares!" which translates to "You have received a payment for 5,000 Dollars", instead of the expected "¡Has recibido un pago por 5.000 Pesos!" -> "You have received a payment for 5,000 Pesos"
I've tried changing the development region of the app, interpolating the string with NumberFormatter.localizedString(from: 5000, number: .currency), and with others styles( .currencyAccounting, .currencyISOCode and .currencyPlural) without good results. The last one seems to work buts it's not ideal since it outputs "5.000 pesos chilenos" which gets read as "5 pesos chilenos" which is not the correct amount (bug), it's as is you're not on Chile and I personally prefer it to be a symbol instead of words.
I'm testing with my device which is setup with the region "Chile"
Could someone help me find a solution?
Topic:
Accessibility & Inclusion
SubTopic:
General
Tags:
Localization
User Notifications
Siri and Voice
I'm working on an app for an accompanying toy that allows you do drop a marble on a self made track.
As a nice bonus I wanted to make it possible to drop a marble using Siri Shortcuts, Siri or the HomePod. So the new iOS 16 App Intents work great for this.
The App Intent documentation is bare, but I got the App Intent to work and it evens shows a custom error message when something goes wrong,
However I now want to promote the feature. SiriTipUIView is meant for this, however I'm seeing an issue. The application name is missing from the tips UI, instead the phrase starts with a space.
The code for the App Shortcuts
struct MyAppShortcutsProvider: AppShortcutsProvider {
static var appShortcuts = [
AppShortcut(intent: DropMarbleIntent(), phrases: [
"\(.applicationName) drop marble",
"\(.applicationName) drop a marble",
"Drop a \(.applicationName)",
"Drop \(.applicationName)"
])
]
}
The code for the SiriTipUIView (just for testing)
let tipView = SiriTipUIView()
tipView.setIntent(intent: DropMarbleIntent())
tipView.sizeToFitUsingConstraints()
tipView.allowsDismissal = true
presentedSubscription = tipView.publisher(for: \.isPresented).sink { isPresented in
if isPresented == false {
self.tableView.tableHeaderView = nil
}
}
tableView.tableHeaderView = tipView
This happens on any iOS 16 simulator and on an iPhone 13 Pro running the iOS 16 release version.
Am I missing something, or should I report a bug using feedback?