liveview-native / liveview-client-swiftui

MIT License
372 stars 36 forks source link

Sharing iOS app data to LVN #993

Closed dbii closed 11 months ago

dbii commented 1 year ago

@bcardarella asked me to post here from the Slack channel to open this for discussion. Here is our use case:

We want to use notifications, but need to have the iOS app pass back the GUID that uniquely identifies the phone-app for notifications. So LVN needs to make some data available to the LiveView.

Could we do that in the config part of return LiveSessionCoordinator(URL(string: "http://1.2.3.4:4000/news")!, config: config) ? Or how would we have the iOS pass info into the LVN?

For example, in our testing of notifications, we're just checking the XCode log:

let token = deviceToken.reduce("") { $0 + String(format: "%02x", $1) }
print("The token is")
print(token)

but we need a way to pass that to the Elixir backend so that we can save it and know the token to use to send the APNS message to.

carson-katri commented 1 year ago

You can use pushEvent to send data to a handle_event on your LiveView. The value parameter can be any JSON serializable type.

bcardarella commented 1 year ago

@dbii if this works for you please let us know and we can close this out

dbii commented 1 year ago

I see how pushEvent works (in the context of the toggle-favorite button in the Cats iOS-tutorial), but don't see how to setup pushEvent to be triggered on app startup/switching to app, since it needs the LiveView socket instantiated. I think what needs to happen is when the LiveSessionCoordinator makes the initial call the value gets stuck in as a key to params maybe (but I'm not sure if that can be accessed, haven't played with it)? Or maybe put into socket or session so that the LiveView mount can get it?

dbii commented 1 year ago

I realized that is where it really needs to go, so that when the user logs in in the LiveView, their APNS token can be linked to their account.

carson-katri commented 1 year ago

You can use LiveSessionConfiguration.connectParams to send the data to mount.

LiveView(
  ...,
  configuration: .init(
    connectParams: { _ in
      ["apns_token": tokenValue]
    }
  )
)

However, it may be better to send the token once when the user logs in and allows notification access.

dbii commented 1 year ago

We get an error in Xcode trying this. Screenshot 2023-07-12 at 8 46 45 AM

carson-katri commented 1 year ago

@dbii Since you're passing the session in, you need to set the connectParams on the configuration of your LiveSessionCoordinator. Or if you'd prefer to use the new session-less init, you can remove the session coordinator and do something like:

var body: some View {
    LiveView(
        .automatic(development: .localhost, production: .custom(URL(string: "example.com")!)),
        configuration: .init(connectParams: { _ in ["apns_token": "tokenValue"] })
    )
}
supernintendo commented 11 months ago

I just tested this following @carson-katri's example and can confirm its working as expected.

@dbii Let us know if you find any other issues related to this.