import Foundation
import SwiftUI
import AppIntents
import UIKit
@main
struct NumberChangerApp: App {
init() {
AppShortcuts.updateAppShortcutParameters()
}
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(NumberManager.shared)
}
}
}
struct AppShortcuts: AppShortcutsProvider {
@AppShortcutsBuilder
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: ChangeNumberIntent(),
phrases: ["Change number to \(\.$number)",
"Change to seven",
"Change to 7"],
shortTitle: "Update Number",
systemImageName: "number"
)
}
}
struct ChangeNumberIntent: AppIntent {
static var title: LocalizedStringResource = "Changes the displayed number"
static var description = IntentDescription("Updates the number shown in the app.")
@Parameter(title: "New Number")
var number: Int
static var parameterSummary: some ParameterSummary {
Summary("Change number to \(\.$number)")
}
func perform() async throws -> some IntentResult {
NumberManager.shared.updateNumber(number)
return .result()
}
}
struct ContentView: View {
@StateObject private var numberManager = NumberManager.shared
var body: some View {
VStack {
Text("Current Number: \(numberManager.currentNumber)")
.font(.system(size: 40, weight: .bold))
.padding()
Text("Say: 'Change number to X'")
.font(.title3)
.foregroundColor(.gray)
}
.padding()
}
}
class NumberManager: ObservableObject {
static let shared = NumberManager()
@Published var currentNumber: Int = 0
func updateNumber(_ newNumber: Int) {
DispatchQueue.main.async {
self.currentNumber = newNumber
}
}
}
I am trying to make a simple view where the app would take user inputs through voice (Siri) and change the number on screen. But Siri is not getting the intent or not updating the number at all.
Everything is in separate files, just posting whole code here.
I tried multiple videos and AI and they give same responses. But it is not working.
import Foundation
import SwiftUI
import AppIntents
import UIKit
@main
struct NumberChangerApp: App {
init() {
AppShortcuts.updateAppShortcutParameters()
}
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(NumberManager.shared)
}
}
}
struct AppShortcuts: AppShortcutsProvider {
@AppShortcutsBuilder
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: ChangeNumberIntent(),
phrases: ["Change number to \(\.$number)",
"Change to seven",
"Change to 7"],
shortTitle: "Update Number",
systemImageName: "number"
)
}
}
struct ChangeNumberIntent: AppIntent {
static var title: LocalizedStringResource = "Changes the displayed number"
static var description = IntentDescription("Updates the number shown in the app.")
@Parameter(title: "New Number")
var number: Int
static var parameterSummary: some ParameterSummary {
Summary("Change number to \(\.$number)")
}
func perform() async throws -> some IntentResult {
NumberManager.shared.updateNumber(number)
return .result()
}
}
struct ContentView: View {
@StateObject private var numberManager = NumberManager.shared
var body: some View {
VStack {
Text("Current Number: \(numberManager.currentNumber)")
.font(.system(size: 40, weight: .bold))
.padding()
Text("Say: 'Change number to X'")
.font(.title3)
.foregroundColor(.gray)
}
.padding()
}
}
class NumberManager: ObservableObject {
static let shared = NumberManager()
@Published var currentNumber: Int = 0
func updateNumber(_ newNumber: Int) {
DispatchQueue.main.async {
self.currentNumber = newNumber
}
}
}
I am trying to make a simple view where the app would take user inputs through voice (Siri) and change the number on screen. But Siri is not getting the intent or not updating the number at all.
Everything is in separate files, just posting whole code here.
I tried multiple videos and AI and they give same responses. But it is not working.
Share Improve this question edited yesterday HangarRash 15k5 gold badges19 silver badges55 bronze badges asked yesterday WorldTravellerWorldTraveller 1 New contributor WorldTraveller is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 1 |1 Answer
Reset to default 0To share an object between the app and its intents use AppDependencyManager
e.g. in your code something like this:
struct ChangeNumberIntent: AppIntent {
@Dependency var numberManager: NumberManager
fileprivate let numberManager = NumberManager() // lazy loaded
@main
struct NumberChangerApp: App {
init() {
AppDependencyManager.shared.add(dependency: numberManager) // dependency param is an autoclosure is only called when the intent runs.
NumberChangerApp.updateAppShortcutParameters()
}
// body only called when app launches not during previews
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(numberManager)
}
}
}
The aim here is to only cause the object to be init if the intent runs and/or the app launches (not during previews).
See this tutorial for more detail (however it doesn't cover proper init): https://developer.apple.com/documentation/appintents/actionbuttonarticle
@StateObject private var numberManager = NumberManager()
to yourNumberChangerApp
and pass the model using.environmentObject(numberManager)
. Declare@EnvironmentObject var numberManager: NumberManager
in yourContentView
. Don't use a singleton for NumberManager model. – workingdog support Ukraine Commented yesterday