Screen_summary context missing screen size properties

We’ve updated to the latest mobile tracking SDKs and are attempting to implement the screen engagement events in both iOS and Android. Based on the demo, the content_height, content_width, min/max_y_offset and min/max_x_offset properties should be included in the payload regardless if the user scrolls or not.

However, we’re noticing that if a user views a screen, does not scroll at all and visits another screen, the screen_summary context only picks up the foreground_sec and background_sec properties. If the user scrolls, and then leaves the page, we see all of the properties as expected.

We’re seeing this behaviour in both Android and iOS and wondering if there’s any issue in the SDK that may be causing this?

Thanks,

Hi @ks107,

I think this can happen due to two reasons:

  1. In case the user does not interact with the scroll view, you might not get any callback with the scroll changed. In this case, you won’t track any ScrollChanged events and thus the tracker won’t have information about the content width/height and offsets and won’t track it in the screen summary.
    • Can you check if the ScrollChanged event is tracked even if users don’t scroll on the screen?
    • If that is the case, you may track a ScrollChanged event after every screen view just passing the current information.
  2. The ScrollChanged event is tracked before the ScreenView event. In some cases, you might get a callback about the scroll position earlier than you get a callback for the screen view.
    • This depends on how you implement the tracking, but could you check on the order of the events?

I hope this makes sense, let us know if you have more questions or suggestions!

1 Like

@matus Thanks for the quick reply! Turns out it was the second scenario you mentioned. We were able to adjust the tracking and it’s now working as expected. Appreciate it!

2 Likes

@matus do you have any recommendations on how to ensure the order of events is correct in the second scenario you mentioned above, other than implementing a delay on the screen_view event?

Unfortunately, I don’t have a general solution for this other than delaying the ScrollChanged events a few milliseconds (you mentioned a delay on the screen view event but if I understand correctly the problem is that the scroll is tracked before screen view).

It depends on the UI framework and what are the options there though – is it possible to track the screen view at an earlier point in the screen transition (e.g., before the scroll view is rendered)?

@matus Thank you for your quick response.

We tried a couple of things:

  1. Stacking events in the order of the first screen_view call and then, after that, the scroll_depth in onResume() of Fragment lifecycle.
  2. Calling screen_view in onCreate() and scroll_depth in onResume() in a Fragment.
  3. Implementing an explicit delay of 400 milliseconds for the scroll_depth event after we called screen_view.

For the 1st and 2nd approaches, we see scroll_depth pixels attached to the previous fragment’s screen_end. Only the 3rd approach works, which we’re really trying to avoid, since a delay, even in a separate thread, is not a feasible solution for app performance.
Do you have any insights on that?

Thanks for the extra details @Priyanka_Sharma, that makes sense.

One more question to help me understand – at which point do you subscribe a scroll change listener? Could you please share a simplified code for how you set up the Fragment/Activity and screen and scroll tracking there?

@matus It works fine for the scenario when user starts scrolling. The problem is when user does not scroll and move to other screen(screen_end gets called without scrolling). For this scenario we tried calling scroll_depth with screen height and width pixels on onResume and onCreate. Following is the simplified version of it.


val screenAnalytics: Observable<AnalyticsStateScreenBundle>

override fun onCreate(savedInstanceState: Bundle?)  {
    super.onCreate(savedInstanceState)

    screenAnalytics
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe {
            analyticsManager.trackAnalyticsState(it)// For screen_view
 val scrollMap: Map<String, Int?> = mapOf(
            SCROLL_X_OFFSET to binding.scrollView.scrollX,
            SCROLL_Y_OFFSET to binding.scrollView.scrollY,
            SCROLL_VIEW_WIDTH to binding.scrollView.width,
            SCROLL_VIEW_HEIGHT to binding.scrollView.height,
            SCROLL_CONTENT_WIDTH to requireView().width,
            SCROLL_CONTENT_HEIGHT to requireView().height
            )
            analyticsManager.trackAnalyticsAction(
                AnalyticsActionScrollDepth.make(
                    mMap
                )
            )// For scroll_depth
        }
        .addTo(createDisposable)
}

Hi @Priyanka_Sharma,

Thanks for clarifying that. If you want to track the ScrollChanged event with the initial information about the scroll view for each screen view event, my suggestion would be to track it right after tracking a screen view event. So track it inside the same function as you track the screen view so that we are sure they happen in the correct order (first screen view, then scroll changed).

I have tried this in an Android app using Jetpack Compose and when I track the scroll changed event after the screen view, the screen end event gets the correct information. Here is a simple snippet showing the calls that I used:

        navController.addOnDestinationChangedListener { _, destination, _ ->
            Snowplow.defaultTracker?.track(ScreenView(destination.route ?: "null"))
            Snowplow.defaultTracker?.track(ScrollChanged(
                yOffset = 1,
                xOffset = 2,
                viewHeight = 100,
                viewWidth = 200,
                contentHeight = 300,
                contentWidth = 400
            ))
        }