PWA Tab Synchronization
This document reviews how to synchronize data between multiple instances
of a PWA running inside an Astro app. By the end of this document you will
understand how to synchronize data between multiple instances of a PWA by
NativeConnector component, Astro events and app events.
An Astro app with a tab design runs multiple instances of PWA inside
the app's web views. There is no guarantee that these PWA instances will
stay in sync. For example, the redux stores in the PWAs may not contain
the same state. In order to synchronize the state of the PWAs
can be used to pass events between the instances. These events can inform
the instances to update certain portions of their state.
NativeConnector is a hidden component in the PWA. It provides a central place where communication between the PWA and
App.js can be customized.
NativeConnector subscribes to the redux store updates using
mapStateToProps and receives updates on these state changes in
componentWillReceiveProps it compares the previous state values to the new state values and sends updates to
App.js if state changes have occured.
NativeConnector can send these updates to
App.js using events or rpc calls over the JS-Native bridge. These events/rpc calls to Astro should be sent by redux actions.
NativeConnector registers to listen for Astro events in
componentDidMount and unregisters from the events in
Broadcasting Events to Multiple Tabs
Redux state syncing is not automatic between multiple instances of the PWA running inside an Astro app. Each portion of the state that needs to be synced between instances needs to be synced manually. Functionality has been added to the Mobify PWAs to facilitate syncing.
In order to sync the state, the
NativeConnector can inform
App.js of the state change as described above.
App.js can then broadcast this state change to all PWA instances using the
PWABroadcaster. A new instance of the
PWABroadcaster should be created for every web view inside
App.js. The constructor for
PWABroadcaster takes the web view as a parameter. It registers to listen to all events sent to the
AppEvents bus and then relays any event that starts with
broadcast: to its registered web view.
An event that needs to be broadcast to all tabs is first sent to the
AppEvents bus. Each
PWABroadcaster listens for specially named broadcast events (
broadcast:) and propagates the broadcast event to the PWA. In the PWA, the
NativeConnector is listening for these events and performs the actions necessary to update the state in that instance of the PWA (updates redux store and/or calls IntegrationManager).
AppEvents bus is a (backbone events)[http://backbonejs.org/#Events] object inside of
AppEvents to pass internal events between its components/controllers.
// Create a new NavigationPlugin let navigationPlugin = await NavigationPlugin.init() // Register the NavigationPlugin to listen for broadcast events let pwaBroadcaster = new PWABroadcaster(navigationPlugin) // In some other part of App.js ... far, far away // // Send a broadcast event to the AppEvents bus // // Since the navigationPlugin created above has // registered with a PwaBroadcaster the // broadcast:userLoggedIn event will be sent to the // PWA loaded inside the navigationPlugin AppEvents.trigger('broadcast:userLoggedIn`)