Support the client_position diagnostic field on Action and Impression events. This is controlled by a client config param named eventsIncludeClientPositions.
Add CollectionInteraction struct to contain client-side information about actions and impressions.
Add methods in MetricsLogger to fill in the client_position field.
Integrate CollectionInteraction with ImpressionTracker so that collection tracking (currently react-native-metrics) can use this mechanism.
Remove unused subclasses of Content.
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:
Frame of view that was interacted with
Visible frame of collection view
Location of interaction within view
Type of gesture
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.
Verified events via local console logging on simulator
Verified that this mechanism works with other diagnostic information
Verified that this mechanism is disabled with the config flag is off
Verified in CloudWatch that events are coming through properly
Support the
client_position
diagnostic field onAction
andImpression
events. This is controlled by a client config param namedeventsIncludeClientPositions
.CollectionInteraction
struct to contain client-side information about actions and impressions.MetricsLogger
to fill in theclient_position
field.CollectionInteraction
withImpressionTracker
so that collection tracking (currently react-native-metrics) can use this mechanism.Content
.ImpressionConfig
protocol and instead requireImpressionSourceType
at initialization ofImpression/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 toindexPath
. In Swift, both[Int]
andIndexPath
(the Foundation struct) areCollection
s whereCollection.Element == BinaryInteger
. The syntax for dealing with theseCollection
s in method signatures makes them cumbersome to work with:By introducing this struct, we only need this generics boilerplate in one location. This allows us to pass both
[Int]
andIndexPath
directly to theinit(indexPath:)
initializer, and also convert from anyBinaryInteger
toInt32
.MetricsLogger
Support filling in
client_position
on Actions and Impressions, keyed on the client configeventsIncludeClientPositions
. Following the previous extension split, the method for filling this out goes inMetricsLogger+EventFields.swift
.ImpressionTracker
Both the iOS/UIKit and React Native libraries use
ImpressionTracker
. Added support forCollectionInteraction
to track this metadata. For now, the implementation is biased towards making the normal path (withoutCollectionInteraction
) 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 theCollectionInteraction
mechanism.Removed Content subclasses
Remove
Item
andPartner
subclasses ofContent
. 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.