istornz / flutter_live_activities

A Flutter plugin to use iOS 16.1+ Live Activities ⛹ī¸ & iPhone Dynamic Island 🏝ī¸ features
https://dimitridessus.fr/
MIT License
160 stars 48 forks source link

Can't I use LiveActivityIntent? #62

Open soulwawa opened 8 months ago

soulwawa commented 8 months ago

hi! Thanks for the great work! I want to use interactivity live activity using LiveActivityIntent.

But, I don't know how to refresh in swift code.

Can I update the live activity in swift (widget file) rather than flutter code? This is a sample code

struct RefreshIntent: LiveActivityIntent {

    static var title: LocalizedStringResource = "Refresh"
    static var description = IntentDescription("Refresh Description.")

    func perform() async throws -> some IntentResult {
        //  live activity update ??

        return .result()
    }
}

Thank you 🙇

https://developer.apple.com/documentation/AppIntents/LiveActivityIntent

Elliot727 commented 6 months ago

To update a Live Activity you need to do something in the perform function

struct RefreshIntent: LiveActivityIntent {

    static var title: LocalizedStringResource = "Refresh"
    static var description = IntentDescription("Refresh Description.")

    func perform() async throws -> some IntentResult {
        //  live activity update ??

        return .result()
    }
}

for example you could call an API and then update the UserDefaults

Heres an example:

@available(iOS 17.0, *)
struct ReloadDataAppIntent:AppIntent{

    @Parameter(title: "id")
    var id:String
    init() {
        id = ""
    }
    init(id: String) {
        self.id = id
    }

    static var title: LocalizedStringResource = "ReloadData"

    func perform() async throws -> some IntentResult {
        @StateObject var viewModel = ReloadDataViewModel()

        let sharedDefault = UserDefaults(suiteName: "YOURGROUPNAME")!

        data = await viewModel.fetchData(apiKey:"YOURAPIKEY)
        sharedDefault.set(YOURDATA, forKey: "YOURKEY")
        WidgetCenter.shared.reloadAllTimelines()
        return .result()
    }
}

Then in a button you can do

if #available(iOS 17.0, *) {
                Button(intent: ReloadDataAppIntent(id: "YOUR ID")) {
                    Image(systemName: "arrow.clockwise")
                        .font(.system(size: 20, weight: .semibold, design: .rounded))
                        .foregroundStyle(.white)
                }
                .buttonStyle(PlainButtonStyle())
            }
soulwawa commented 6 months ago

@Elliot727 Thank you reply, I don't understand maybe because I don't know the swift.

@StateObject var viewModel = ReloadDataViewModel()

let sharedDefault = UserDefaults(suiteName: "YOURGROUPNAME")!

data = await viewModel.fetchData(apiKey:"YOURAPIKEY)
sharedDefault.set(YOURDATA, forKey: "YOURKEY")
WidgetCenter.shared.reloadAllTimelines()
return .result()

Because it creates live activity with the flutter code.. It's hard to understand the code above 😭

Elliot727 commented 6 months ago

Let me explain. Hope this helps

  1. Creating a ViewModel with @StateObject:

    @StateObject var viewModel = ReloadDataViewModel()

    In SwiftUI, @StateObject is used to create an instance of a class that survives the entire view's lifecycle. In this case, a ReloadDataViewModel is being instantiated and managed as a state object. This is commonly used for data management in SwiftUI.

  2. Initializing UserDefaults with a specific suite name:

    let sharedDefault = UserDefaults(suiteName: "YOURGROUPNAME")!

    This code initializes a UserDefaults instance with a specified suite name. This can be useful when you want to share UserDefaults between different parts of your app or even between your app and its extensions.

  3. Asynchronous data fetching using async/await:

    data = await viewModel.fetchData(apiKey: "YOURAPIKEY")

    This code calls an asynchronous function fetchData from the ReloadDataViewModel class, using the new async/await syntax in Swift. It fetches data from an API and assigns it to the data variable.

  4. Setting data in UserDefaults:

    sharedDefault.set(YOURDATA, forKey: "YOURKEY")

    This line sets a value (YOURDATA) for a specified key (YOURKEY) in the UserDefaults instance (sharedDefault). UserDefaults is commonly used for storing simple data persistently.

  5. Reloading all timelines in a Widget:

    WidgetCenter.shared.reloadAllTimelines()

    If you are working with iOS widgets, this code triggers a reload of all the timelines associated with your app's widgets. It's useful when you want to update the content displayed in widgets dynamically.

  6. Returning a .result() value:

    return .result()

    This is a generic return statement, suggesting the function returns a result. The specific meaning of .result() depends on the context of the function and its return type.

Please replace placeholders like "YOURGROUPNAME," "YOURAPIKEY," "YOURDATA," and "YOURKEY" with your actual values as needed.

Let Me Know if you need anything else explained

Also its best to learn Swift / SwiftUI when building the iOS widgets