promotedai / ios-metrics-sdk

iOS client library for Promoted.ai metrics tracking.
MIT License
7 stars 1 forks source link

Implement ClientPosition diagnostic tool #164

Closed yunapotamus closed 2 years ago

yunapotamus commented 2 years ago

Support the client_position diagnostic field on Action and Impression events. This is controlled by a client config param named eventsIncludeClientPositions.

  1. Add CollectionInteraction struct to contain client-side information about actions and impressions.
  2. Add methods in MetricsLogger to fill in the client_position field.
  3. Integrate CollectionInteraction with ImpressionTracker so that collection tracking (currently react-native-metrics) can use this mechanism.
  4. Remove unused subclasses of Content.
  5. Remove ImpressionConfig protocol and instead require ImpressionSourceType at initialization of Impression/ScrollTracker.

CollectionInteraction struct

Designed to hold information about instances of client-side interaction that triggered Promoted events. Right now this struct only has client position of collection cell as a field, but we could extend this to hold more data when we do detailed impression logging. By creating this struct and propagating it throughout our SDK, we form the foundation for such a feature.

Examples of more data we could log:

Interaction with Swift Collections

Another benefit to a separate struct is that it's easier to interact with generic Int collections instead of requiring arrays as argument to indexPath. In Swift, both [Int] and IndexPath (the Foundation struct) are Collections where Collection.Element == BinaryInteger. The syntax for dealing with these Collections in method signatures makes them cumbersome to work with:

func funcThatTakesIntCollection<
  C: Collection,
  E: BinaryInteger
>(
  arg: C
) where C.Element == E { ... }

By introducing this struct, we only need this generics boilerplate in one location. This allows us to pass both [Int] and IndexPath directly to the init(indexPath:) initializer, and also convert from any BinaryInteger to Int32.

MetricsLogger

Support filling in client_position on Actions and Impressions, keyed on the client config eventsIncludeClientPositions. Following the previous extension split, the method for filling this out goes in MetricsLogger+EventFields.swift.

ImpressionTracker

Both the iOS/UIKit and React Native libraries use ImpressionTracker. Added support for CollectionInteraction to track this metadata. For now, the implementation is biased towards making the normal path (without CollectionInteraction) efficient, since the diagnostics path is not designed for the majority use case. For example, collectionViewDidChangeVisibleContent takes a dictionary of [Content: CollectionInteraction] when a list of tuples could be more efficient. We should revisit this if we expand the CollectionInteraction mechanism.

Removed Content subclasses

Remove Item and Partner subclasses of Content. We're going to differentiate between entity types in a more sophisticated way, so we don't need these Swift classes. These subclasses also didn't end up being used.

Remove ImpressionConfig

This was originally intended to make it easier to configure all the collection/impression tracking classes, but wound up not being needed. We only had sourceType as an argument, so we just pass that everywhere.

Testing

Testing was done both via unit tests and integrating this functionality with a partner app.