最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - Unable to integrate AppIntents - Stack Overflow

programmeradmin1浏览0评论
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
  • Try adding @StateObject private var numberManager = NumberManager() to your NumberChangerApp and pass the model using .environmentObject(numberManager). Declare @EnvironmentObject var numberManager: NumberManager in your ContentView. Don't use a singleton for NumberManager model. – workingdog support Ukraine Commented yesterday
Add a comment  | 

1 Answer 1

Reset to default 0

To 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

发布评论

评论列表(0)

  1. 暂无评论