diff --git a/CHANGELOG.md b/CHANGELOG.md index 8428509..6d45133 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.5.0 + +* Add lifecycle autotracking config option (#39) + # 0.4.0 * Add configuration for setting custom HTTP headers for requests to the collector (#34) diff --git a/README.md b/README.md index 38b0446..ce50050 100644 --- a/README.md +++ b/README.md @@ -20,18 +20,19 @@ It is build on top of Snowplow's native [iOS](https://github.com/snowplow/snowpl ## Features -| Feature | Android | iOS | Web | -|---|---|---|---| -| Manual tracking of events: screen views, self-describing, structured, timing, consent granted and withdrawal | ✔ | ✔ | ✔ | -| Automatic tracking of views events from Navigator API | ✔ | ✔ | ✔ | -| Adding custom context entities to events | ✔ | ✔ | ✔ | -| Support for multiple trackers | ✔ | ✔ | ✔ | -| Configurable subject properties | ✔ | ✔ | partly | -| Session context entity added to events | ✔ | ✔ | ✔ | -| Geo-location context entity | ✔ | ✔ | ✔ | -| Mobile platform context entity | ✔ | ✔ | | -| Web page context entity | | | ✔ | -| Configurable GDPR context entity | ✔ | ✔ | ✔ | +| Feature | Android | iOS | Web | +|--------------------------------------------------------------------------------------------------------------|---|---|--------| +| Manual tracking of events: screen views, self-describing, structured, timing, consent granted and withdrawal | ✔ | ✔ | ✔ | +| Automatic tracking of views events from Navigator API | ✔ | ✔ | ✔ | +| Adding custom context entities to events | ✔ | ✔ | ✔ | +| Support for multiple trackers | ✔ | ✔ | ✔ | +| Configurable subject properties | ✔ | ✔ | partly | +| Session context entity added to events | ✔ | ✔ | ✔ | +| Geo-location context entity | ✔ | ✔ | ✔ | +| Mobile platform context entity | ✔ | ✔ | | +| Web page context entity | | | ✔ | +| Configurable GDPR context entity | ✔ | ✔ | ✔ | +| Lifecycle autotracking | ✔ | ✔ | | ## Quick Start @@ -47,7 +48,7 @@ This will add a line with the dependency like this to your `pubspec.yaml`: ```yml dependencies: - snowplow_tracker: ^0.4.0 + snowplow_tracker: ^0.5.0 ``` Import the package into your Dart code: diff --git a/android/src/main/kotlin/com/snowplowanalytics/snowplow_tracker/TrackerVersion.kt b/android/src/main/kotlin/com/snowplowanalytics/snowplow_tracker/TrackerVersion.kt index 1d47b78..d316e77 100644 --- a/android/src/main/kotlin/com/snowplowanalytics/snowplow_tracker/TrackerVersion.kt +++ b/android/src/main/kotlin/com/snowplowanalytics/snowplow_tracker/TrackerVersion.kt @@ -12,5 +12,5 @@ package com.snowplowanalytics.snowplow_tracker object TrackerVersion { - val TRACKER_VERSION = "flutter-0.4.0" + val TRACKER_VERSION = "flutter-0.5.0" } diff --git a/android/src/main/kotlin/com/snowplowanalytics/snowplow_tracker/readers/configurations/TrackerConfigurationReader.kt b/android/src/main/kotlin/com/snowplowanalytics/snowplow_tracker/readers/configurations/TrackerConfigurationReader.kt index 2de5956..4dd6743 100644 --- a/android/src/main/kotlin/com/snowplowanalytics/snowplow_tracker/readers/configurations/TrackerConfigurationReader.kt +++ b/android/src/main/kotlin/com/snowplowanalytics/snowplow_tracker/readers/configurations/TrackerConfigurationReader.kt @@ -28,6 +28,7 @@ class TrackerConfigurationReader(values: Map) { val userAnonymisation: Boolean? by valuesDefault val screenContext: Boolean? by valuesDefault val applicationContext: Boolean? by valuesDefault + val lifecycleAutotracking: Boolean? by valuesDefault fun toConfiguration(context: Context): TrackerConfiguration { @@ -52,6 +53,7 @@ class TrackerConfigurationReader(values: Map) { userAnonymisation?.let { trackerConfig.userAnonymisation(it) } screenContext?.let { trackerConfig.screenContext(it) } applicationContext?.let { trackerConfig.applicationContext(it) } + lifecycleAutotracking?.let { trackerConfig.lifecycleAutotracking(it) } return trackerConfig } diff --git a/doc/01-getting-started.md b/doc/01-getting-started.md index 3da46d5..b29b619 100644 --- a/doc/01-getting-started.md +++ b/doc/01-getting-started.md @@ -16,7 +16,7 @@ This will add a line with the dependency like to your pubspec.yaml: ```yml dependencies: - snowplow_tracker: ^0.4.0 + snowplow_tracker: ^0.5.0 ``` Import the package into your Dart code: diff --git a/doc/02-configuration.md b/doc/02-configuration.md index f6d8bee..beddfcc 100644 --- a/doc/02-configuration.md +++ b/doc/02-configuration.md @@ -34,23 +34,26 @@ Setting a custom POST path can be useful in avoiding adblockers; it replaces the `TrackerConfiguration` provides options to configure properties and features of the tracker. In addition to setting the app identifier and device platform, the configuration enables turning several automatic context entities on and off. -| Attribute | Type | Description | Android | iOS | Web | Default | -|---|---|---|---|---|---|---| -| `appId` | `String?` | Identifier of the app. | ✔ | ✔ | ✔ | null on Web, bundle identifier on iOS/Android | -| `devicePlatform` | `DevicePlatform?` | The device platform the tracker runs on. Available options are provided by the `DevicePlatform` enum. | ✔ | ✔ | ✔ | "web" on Web, "mob" on iOS/Android | -| `base64Encoding` | `bool?` | Indicates whether payload JSON data should be base64 encoded. | ✔ | ✔ | ✔ | true | -| `platformContext` | `bool?` | Indicates whether [platform](http://iglucentral.com/schemas/com.snowplowanalytics.snowplow/mobile_context/jsonschema/1-0-2) (mobile) context should be attached to tracked events. | ✔ | ✔ | | true | -| `geoLocationContext` | `bool?` | Indicates whether [geo-location](http://iglucentral.com/schemas/com.snowplowanalytics.snowplow/geolocation_context/jsonschema/1-1-0) context should be attached to tracked events. | ✔ | ✔ | ✔ | false | -| `sessionContext` | `bool?` | Indicates whether [session](http://iglucentral.com/schemas/com.snowplowanalytics.snowplow/client_session/jsonschema/1-0-2) context should be attached to tracked events. | ✔ | ✔ | ✔ | true | -| `webPageContext` | `bool?` | Indicates whether context about current [web page](http://iglucentral.com/schemas/com.snowplowanalytics.snowplow/web_page/jsonschema/1-0-0) should be attached to tracked events. | | | ✔ | true | -| `screenContext` | `bool?` | Indicates whether [screen](http://iglucentral.com/schemas/com.snowplowanalytics.mobile/screen/jsonschema/1-0-0) context should be attached to tracked events. | ✔ | ✔ | | true | -| `applicationContext` | `bool?` | Indicates whether [application](http://iglucentral.com/schemas/com.snowplowanalytics.mobile/application/jsonschema/1-0-0) context should be attached to tracked events. | ✔ | ✔ | | true | -| `webActivityTracking` | WebActivityTracking?` | Enables activity tracking using page views and pings on the Web. | | | ✔ | true | -| `userAnonymisation` | `bool?` | Anonymises certain user identifiers. | ✔ | ✔ | ✔ | false | +| Attribute | Type | Description | Android | iOS | Web | Default | +|-------------------------|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---|---|---|-----------------------------------------------| +| `appId` | `String?` | Identifier of the app. | ✔ | ✔ | ✔ | null on Web, bundle identifier on iOS/Android | +| `devicePlatform` | `DevicePlatform?` | The device platform the tracker runs on. Available options are provided by the `DevicePlatform` enum. | ✔ | ✔ | ✔ | "web" on Web, "mob" on iOS/Android | +| `base64Encoding` | `bool?` | Indicates whether payload JSON data should be base64 encoded. | ✔ | ✔ | ✔ | true | +| `platformContext` | `bool?` | Indicates whether [platform](http://iglucentral.com/schemas/com.snowplowanalytics.snowplow/mobile_context/jsonschema/1-0-2) (mobile) entity should be attached to tracked events. | ✔ | ✔ | | true | +| `geoLocationContext` | `bool?` | Indicates whether [geo-location](http://iglucentral.com/schemas/com.snowplowanalytics.snowplow/geolocation_context/jsonschema/1-1-0) entity should be attached to tracked events. | ✔ | ✔ | ✔ | false | +| `sessionContext` | `bool?` | Indicates whether [session](http://iglucentral.com/schemas/com.snowplowanalytics.snowplow/client_session/jsonschema/1-0-2) entity should be attached to tracked events. | ✔ | ✔ | ✔ | true | +| `webPageContext` | `bool?` | Indicates whether context about current [web page](http://iglucentral.com/schemas/com.snowplowanalytics.snowplow/web_page/jsonschema/1-0-0) should be attached to tracked events. | | | ✔ | true | +| `screenContext` | `bool?` | Indicates whether [screen](http://iglucentral.com/schemas/com.snowplowanalytics.mobile/screen/jsonschema/1-0-0) entity should be attached to tracked events. | ✔ | ✔ | | true | +| `applicationContext` | `bool?` | Indicates whether [application](http://iglucentral.com/schemas/com.snowplowanalytics.mobile/application/jsonschema/1-0-0) entity should be attached to tracked events. | ✔ | ✔ | | true | +| `webActivityTracking` | `WebActivityTracking?` | Enables activity tracking using page views and pings on the Web. | | | ✔ | true | +| `userAnonymisation` | `bool?` | Anonymises certain user identifiers. | ✔ | ✔ | ✔ | false | +| `lifecycleAutotracking` | `bool?` | Indicates whether the [lifecycle](iglu:com.snowplowanalytics.mobile/application_lifecycle/jsonschema/1-0-0) entity and foreground and background events should be autotracked. | ✔ | ✔ | | false | The optional `WebActivityTracking` property configures page tracking on Web. Initializing the configuration will inform `SnowplowObserver` observers (see section on auto-tracking in "Tracking events") to auto track `PageViewEvent` events instead of `ScreenView` events on navigation changes. Further, setting the `minimumVisitLength` and `heartbeatDelay` properties of the `WebActivityTracking` instance will enable activity tracking using 'page ping' events on Web. -Activity tracking monitors whether a user continues to engage with a page over time, and record how he / she digests content on the page over time. That is accomplished using 'page ping' events. If activity tracking is enabled, the web page is monitored to see if a user is engaging with it. (E.g. is the tab in focus, does the mouse move over the page, does the user scroll etc.) If any of these things occur in a set period of time (`minimumVisitLength` seconds from page load and every `heartbeatDelay` seconds after that), a page ping event fires, and records the maximum scroll left / right and up / down in the last ping period. If there is no activity in the page (e.g. because the user is on a different tab in his / her browser), no page ping fires. +Activity tracking monitors whether a user continues to engage with a page over time, and record how they digest content on the page over time. That is accomplished using 'page ping' events. If activity tracking is enabled, the web page is monitored to see if a user is engaging with it. (E.g. is the tab in focus, does the mouse move over the page, does the user scroll etc.) If any of these things occur in a set period of time (`minimumVisitLength` seconds from page load and every `heartbeatDelay` seconds after that), a page ping event fires, and records the maximum scroll left / right and up / down in the last ping period. If there is no activity in the page (e.g. because the user is on a different tab in their browser), no page ping fires. + +Lifecycle autotracking is only available on mobile apps (iOS and Android). When configured, a Lifecycle context entity is attached to all events. It records whether the app was visible or not when the event was tracked. In addition, a `Background` event will be tracked when the app is moved to background, and a `Foreground` event when the app moves back to foreground (becomes visible on the screen). See the separate page for information about anonymous tracking. diff --git a/example/android/build.gradle b/example/android/build.gradle index c9cd053..81e2fff 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.0.4' + classpath 'com.android.tools.build:gradle:7.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index bd2401b..778f79d 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -5,7 +5,7 @@ PODS: - FMDB/standard (2.7.5) - integration_test (0.0.1): - Flutter - - snowplow_tracker (0.4.0): + - snowplow_tracker (0.5.0): - Flutter - SnowplowTracker (~> 5.4) - SnowplowTracker (5.4.0): @@ -33,9 +33,9 @@ SPEC CHECKSUMS: Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a integration_test: 13825b8a9334a850581300559b8839134b124670 - snowplow_tracker: 022a7e65a05a6f6043043d58d8df870b379efe5d + snowplow_tracker: 941f2de51ed3c6964ccab206ac5ba75f326a188a SnowplowTracker: a7fa5ae461955637f773a51c941635f39a5b0747 PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 -COCOAPODS: 1.12.0 +COCOAPODS: 1.12.1 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index e37467d..e83cbc5 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -155,7 +155,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1430; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c87d15a..a6b826d 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ =3.0.0 <4.0.0" - flutter: ">=3.10.0" + dart: ">=3.2.0-194.0.dev <4.0.0" + flutter: ">=3.3.0" diff --git a/ios/Classes/TrackerVersion.swift b/ios/Classes/TrackerVersion.swift index c0115d2..a525bd1 100644 --- a/ios/Classes/TrackerVersion.swift +++ b/ios/Classes/TrackerVersion.swift @@ -12,5 +12,5 @@ import Foundation class TrackerVersion { - static let TRACKER_VERSION = "flutter-0.4.0" + static let TRACKER_VERSION = "flutter-0.5.0" } diff --git a/ios/Classes/readers/configurations/TrackerConfigurationReader.swift b/ios/Classes/readers/configurations/TrackerConfigurationReader.swift index be40eba..d7a0b47 100644 --- a/ios/Classes/readers/configurations/TrackerConfigurationReader.swift +++ b/ios/Classes/readers/configurations/TrackerConfigurationReader.swift @@ -22,6 +22,7 @@ struct TrackerConfigurationReader: Decodable { let userAnonymisation: Bool? let screenContext: Bool? let applicationContext: Bool? + let lifecycleAutotracking: Bool? var devicePlatformType: DevicePlatform? { if let devicePlatform = self.devicePlatform { @@ -75,6 +76,7 @@ extension TrackerConfigurationReader { if let ua = self.userAnonymisation { trackerConfig.userAnonymisation(ua) } if let scr = self.screenContext { trackerConfig.screenContext(scr) } if let ac = self.applicationContext { trackerConfig.applicationContext(ac) } + if let lc = self.lifecycleAutotracking { trackerConfig.lifecycleAutotracking(lc) } return trackerConfig } diff --git a/ios/snowplow_tracker.podspec b/ios/snowplow_tracker.podspec index 20d2270..3bd4a2d 100644 --- a/ios/snowplow_tracker.podspec +++ b/ios/snowplow_tracker.podspec @@ -4,7 +4,7 @@ # Pod::Spec.new do |s| s.name = 'snowplow_tracker' - s.version = '0.4.0' + s.version = '0.5.0' s.summary = 'A package for tracking Snowplow events in Flutter apps.' s.description = <<-DESC A package for tracking Snowplow events in Flutter apps. diff --git a/lib/configurations/tracker_configuration.dart b/lib/configurations/tracker_configuration.dart index 14588a6..2138e93 100644 --- a/lib/configurations/tracker_configuration.dart +++ b/lib/configurations/tracker_configuration.dart @@ -73,6 +73,11 @@ class TrackerConfiguration { /// Indicates whether user identifiers should be anonymised. final bool? userAnonymisation; + /// Indicates whether to enable automatic tracking of background and foreground transitions. + /// + /// Defaults to false on iOS and Android. Not available on Web. + final bool? lifecycleAutotracking; + const TrackerConfiguration( {this.appId, this.devicePlatform, @@ -84,7 +89,8 @@ class TrackerConfiguration { this.screenContext, this.applicationContext, this.webActivityTracking, - this.userAnonymisation}); + this.userAnonymisation, + this.lifecycleAutotracking}); Map toMap() { final conf = { @@ -98,7 +104,8 @@ class TrackerConfiguration { 'screenContext': screenContext, 'applicationContext': applicationContext, 'webActivityTracking': webActivityTracking?.toMap(), - 'userAnonymisation': userAnonymisation + 'userAnonymisation': userAnonymisation, + 'lifecycleAutotracking': lifecycleAutotracking }; conf.removeWhere((key, value) => value == null); return conf; diff --git a/pubspec.yaml b/pubspec.yaml index 9f2dfbc..8f1de63 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: snowplow_tracker description: A package for tracking Snowplow events in Flutter apps -version: 0.4.0 +version: 0.5.0 homepage: https://github.com/snowplow-incubator/snowplow-flutter-tracker repository: https://github.com/snowplow-incubator/snowplow-flutter-tracker