ZupIT/beagle

BeagleScreenViewController Lifecycle Analytics

bradleysmaskell opened this issue · 4 comments

Use case

trackEventOnScreenDisappeared() is not implemented and the BeagleScreenViewModal is not public or subclassable so that integrators can provide their own implementation.

    public func trackEventOnScreenAppeared() {
        screenAppearEventIsPending = false
        analyticsService?.createRecord(screen: screenType, rootId: screen?.id)
    }
    
    public func trackEventOnScreenDisappeared() {}

Without this we're having to resort to method swizzling the BeagleScreenViewController's lifecycle methods so we can have view metrics.

Proposal

Please implement trackEventOnScreenDisappeared()

Hello @bradleysmaskell. The Beagle Analytics API let's you track when a screen is loaded, not when it's unloaded. This is not simply a matter of implementing this method, we'd have to change the API and then reflect this change into all platforms: iOS, Android, React and Angular.

The goal of Beagle Analytics API in regard to the navigation is to trigger an event when a Server Driven View is loaded. Example: if you have the flow: /home > /products > /cart > /payment > /order, 5 analytics events will be triggered, one when each of the screens is loaded.

Beagle analytics API doesn't aim to generate analytics for anything outside Beagle. The event of a Server Driven Screen disappearing in order for another to appear, can be tracked with the "appear" event of the next screen. If one of the screens is not server driven, then it should be implemented natively.

Can you please provide us more information about your use case? If it makes sense as a Beagle feature, we'll consider altering the API.

Hey @Tiagoperes.

Most analytics usually track what you mentioned as well as the duration of time a user spent on that screen. We can't really do that without getting some callback that the user has dismissed the screen.

  • On Android, you can subclass BeagleActivity so we can override lifecycle methods to observe view duration metrics.
  • On iOS the BeagleScreenViewController is public but not open, meaning we can't subclass lifecycle methods to observe view duration metrics the way we have done on Android as you are suggesting.

It'd be great to implement one or both of the following suggestions

  1. add another screen analytics event for when the server-driven screen is dismissed
  2. make BeagleScreenViewController open so that integrators can subclass.

If I had to recommend one it would be making the BeagleScreenViewController open which would solve other issues for us as well. I'd be happy to make a PR if there's agreement.

This could be achieved without altering Beagle:

@BeagleComponent
class AnalyticsProviderImpl : AnalyticsProvider{
    // ...

    private let lastScreenRecord: AnalyticsRecord? = null

    override fun createRecord(record: AnalyticsRecord) {
        // ...
        if (record.type == "screen") {
            lastScreenRecord?.let {
                val timeOnScreen = record.timestamp - lastScreenRecord.timestamp
                // do what you need with this information
            }
            lastScreenRecord = record
        }
    }
}

The problem with this approach is that the last screen will never generate analytics. To fix this, you can create a method in AnalyticsProviderImpl that sends the last screen time and call it when your native view is dismissed.

Having said this, I'm not opposed to making this class and these methods open in Beagle Android. I'd happily accept your PR with this change.

@Tiagoperes I've created a PR as discussed. Let me know if you have any feedback.
ZupIT/beagle-ios#52