This example demonstrates query-based App Intents using a weather application that provides information without opening the app interface. It showcases how to create background data queries with voice responses optimized for Siri.
ProvidesDialog for Siri voice responsesThis example uses the hybrid approach with:
ios/Runner/AppDelegate.swift)lib/main.dart)| App Interface | iOS Shortcuts |
|---|---|
![]() |
![]() |
| App Interface | iOS Shortcuts |
|---|---|
![]() |
![]() |
| Navigation app | iOS Shortcuts app |
cd weather
flutter pub get
flutter run
Manual Testing: Use the buttons in the app interface to test queries
iOS Shortcuts: Check the Shortcuts app for available weather actions
Enable Siri: ⚠️ IMPORTANT - In Shortcuts app, tap “Weather Example Shortcuts” and toggle ON the Siri switch (it’s OFF by default)
The iOS side defines static query intents in AppDelegate.swift:
@available(iOS 16.0, *)
struct GetCurrentWeatherIntent: AppIntent {
static var title: LocalizedStringResource = "Get Current Weather"
static var description = IntentDescription("Get current weather conditions for a location")
static var isDiscoverable = true
// Note: No openAppWhenRun - this works in background
@Parameter(title: "Location")
var location: String?
func perform() async throws -> some IntentResult & ReturnsValue<String> & ProvidesDialog {
let plugin = FlutterAppIntentsPlugin.shared
let result = await plugin.handleIntentInvocation(
identifier: "get_current_weather",
parameters: ["location": location ?? "current location"]
)
if let success = result["success"] as? Bool, success {
let value = result["value"] as? String ?? "Weather information retrieved"
return .result(
value: value,
dialog: IntentDialog(stringLiteral: value) // Ensures Siri speaks result
)
} else {
let errorMessage = result["error"] as? String ?? "Failed to get weather"
throw AppIntentError.executionFailed(errorMessage)
}
}
}
The Flutter side handles data fetching and voice response formatting:
Future<AppIntentResult> _handleCurrentWeather(Map<String, dynamic> parameters) async {
try {
final location = parameters['location'] as String? ?? 'current location';
// Simulate weather data fetching
final weatherData = await _fetchWeatherData(location);
// Log the query for demonstration
setState(() {
_queryLog.insert(0, 'Current weather for $location');
});
// Donate intent for Siri learning
await _client.donateIntent('get_current_weather', parameters);
// Format response optimized for Siri voice output
final response = _formatCurrentWeatherResponse(weatherData, location);
return AppIntentResult.successful(
value: response,
// Note: needsToContinueInApp = false for background queries
needsToContinueInApp: false,
);
} catch (e) {
return AppIntentResult.failed(
error: 'Failed to get weather data: $e',
);
}
}
Responses are optimized for Siri speech:
String _formatCurrentWeatherResponse(Map<String, dynamic> data, String location) {
final temp = data['temperature'];
final condition = data['condition'];
final humidity = data['humidity'];
final wind = data['wind_speed'];
return 'Current weather in $location: $temp degrees and $condition. '
'Humidity is $humidity percent with winds at $wind miles per hour.';
}
The static shortcuts are declared with an AppShortcutsProvider:
@available(iOS 16.0, *)
struct WeatherAppShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
// Current weather shortcut - comprehensive weather information
AppShortcut(
intent: GetCurrentWeatherIntent(),
phrases: [
"Get weather from \(.applicationName)",
"Check weather using \(.applicationName)",
"What's the weather in \(.applicationName)",
"Current weather with \(.applicationName)"
],
shortTitle: "Weather",
systemImageName: "cloud.sun"
)
// ... other shortcuts
}
}
This example focuses on query intents that:
needsToContinueInApp: false)ProvidesDialog return type in Swift for voice responsesKey Differences from Other Examples:
ProvidesDialog usage for Siri voice responses"Get weather from Weather Example"
"Check weather using Weather Example"
"What's the weather in Weather Example"
"Get temperature in San Francisco using Weather Example"
"Check weather in New York with Weather Example"
"What's the forecast in Seattle from Weather Example"
"Is it raining in Miami with Weather Example"
"Get forecast for tomorrow using Weather Example"
"Check temperature using Weather Example"
This weather example demonstrates the query pattern that’s perfect for:
For action-based intents, see the counter example. For navigation intents, see the navigation example.