Skip to content

Commit 19c34d9

Browse files
evan-masseauclaude
andcommitted
feat: Add form lifecycle hooks for in-app forms (Part of MAGE-287)
Adds FormLifecycleEvent sealed interface with event-specific data, FormLifecycleCallback registration API, and lifecycle event firing from PresentationManager and NativeBridge. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
1 parent 7f2a1d5 commit 19c34d9

28 files changed

Lines changed: 801 additions & 414 deletions

File tree

AGENTS.md

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
# AI Agent Guidelines
22

3-
Assume the role of an experienced Android SDK developer. Prioritize code quality, maintainability, and a smooth third-party developer experience. Search existing implementations before creating new code; refactor duplicated logic into shared utilities (typically in `sdk/core`). Default to modern, idiomatic Kotlin. Start pull requests in Draft unless told otherwise; fill in the PR template concisely.
3+
This file provides guidance to AI coding agents (Claude Code, Cursor, GitHub Copilot, etc.) when
4+
working with code in this repository.
5+
6+
AI agents should assume the role of an experienced android developer with a background in mobile app
7+
development.
8+
You are familiar with Kotlin, Android SDK development, and best practices in software engineering.
9+
You will be asked to help with code reviews, feature implementations, and debugging issues in the
10+
Klaviyo Android SDK.
11+
You prioritize code quality, maintainability, and adherence to the project's architecture and coding
12+
styles and standards.
13+
You create reusable code, searching for existing implementations first, and if you see conflicting
14+
or duplicative methods of doing the similar tasks, refactor common functionality into shared
15+
helpers/utilities.
16+
The experience of 3rd party developers integrating the SDK should be smooth, intuitive and as simple
17+
as possible.
18+
You prefer solutions using the most modern, practical and efficient approaches available in the
19+
Android ecosystem.
20+
When creating pull requests, you should typically start in Draft unless prompted otherwise, and
21+
fill in the repository's PR template with concise details in the appropriate sections.
422

523
## Intro
624

@@ -16,9 +34,11 @@ analytics, push notifications, and in-app messaging (aka forms).
1634
# Build the entire project
1735
./gradlew build
1836

19-
# Build a specific module (pattern applies to all modules under sdk/)
20-
# Modules: core, analytics, forms, forms-core, push-fcm, location, location-core
21-
./gradlew :sdk:{module}:build
37+
# Build a specific module
38+
./gradlew :sdk:core:build
39+
./gradlew :sdk:analytics:build
40+
./gradlew :sdk:forms:build
41+
./gradlew :sdk:push-fcm:build
2242

2343
# Assemble only (compile without testing)
2444
./gradlew assemble
@@ -39,11 +59,15 @@ field overrides via reflection.
3959
# Run all tests in the project
4060
./gradlew test
4161

42-
# Run unit tests for a specific module (same module list as build)
43-
./gradlew :sdk:{module}:testDebugUnitTest
62+
# Run unit tests for a specific module
63+
./gradlew :sdk:core:testDebugUnitTest
64+
./gradlew :sdk:analytics:testDebugUnitTest
65+
./gradlew :sdk:forms:testDebugUnitTest
66+
./gradlew :sdk:push-fcm:testDebugUnitTest
4467

4568
# Run a specific unit test with "--tests" flag
4669
./gradlew :sdk:core:testDebugUnitTest --tests "com.klaviyo.core.KLogTest"
70+
4771
```
4872

4973
### Lint Commands
@@ -89,18 +113,6 @@ The Klaviyo Android SDK is organized into multiple modules, each with specific r
89113
- Connects to Klaviyo's CDN for form content
90114
- Manages form display timing and user interaction
91115

92-
5. **Forms-Core Module** (`sdk/forms-core`):
93-
- Auto-registers forms services via ContentProvider
94-
- Allows forms feature to be excluded at build time without a no-op module
95-
96-
6. **Location Module** (`sdk/location`):
97-
- Provides location/geofencing capabilities (requires runtime permissions)
98-
- Depends on location-core for base registration
99-
100-
7. **Location-Core Module** (`sdk/location-core`):
101-
- Auto-registers location services via ContentProvider (no runtime permissions required)
102-
- Enables location feature without the full location module
103-
104116
### Key Components
105117

106118
1. **Klaviyo Object** (`Klaviyo.kt`):
@@ -125,9 +137,9 @@ The Klaviyo Android SDK is organized into multiple modules, each with specific r
125137

126138
### CI/CD Pipeline
127139

128-
The project uses GitHub Actions for CI/CD, particularly for running tests and lint checks on pull requests.
129-
Ensure that relevant tests pass and lint checks are successful before committing any changes.
130-
NEVER use --no-verify as a way to work around pre-commit checks unless prompted.
140+
The project uses GitHub Actions for CI/CD, particularly for running tests and link checks on pull requests.
141+
Ensure that all tests pass and lint checks are successful before committing any changes.
142+
Do not use --no-verify as a way to work around pre-commit checks unless prompted.
131143

132144
### Testing Approach
133145

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ The sample app serves as both a reference implementation and a testing tool for
103103
```kotlin
104104
// build.gradle.kts
105105
dependencies {
106-
implementation("com.github.klaviyo.klaviyo-android-sdk:analytics:4.3.1")
107-
implementation("com.github.klaviyo.klaviyo-android-sdk:push-fcm:4.3.1")
108-
implementation("com.github.klaviyo.klaviyo-android-sdk:forms:4.3.1")
109-
implementation("com.github.klaviyo.klaviyo-android-sdk:location:4.3.1")
106+
implementation("com.github.klaviyo.klaviyo-android-sdk:analytics:4.3.0")
107+
implementation("com.github.klaviyo.klaviyo-android-sdk:push-fcm:4.3.0")
108+
implementation("com.github.klaviyo.klaviyo-android-sdk:forms:4.3.0")
109+
implementation("com.github.klaviyo.klaviyo-android-sdk:location:4.3.0")
110110
}
111111
```
112112
</details>
@@ -117,10 +117,10 @@ The sample app serves as both a reference implementation and a testing tool for
117117
```groovy
118118
// build.gradle
119119
dependencies {
120-
implementation "com.github.klaviyo.klaviyo-android-sdk:analytics:4.3.1"
121-
implementation "com.github.klaviyo.klaviyo-android-sdk:push-fcm:4.3.1"
122-
implementation "com.github.klaviyo.klaviyo-android-sdk:forms:4.3.1"
123-
implementation "com.github.klaviyo.klaviyo-android-sdk:location:4.3.1"
120+
implementation "com.github.klaviyo.klaviyo-android-sdk:analytics:4.3.0"
121+
implementation "com.github.klaviyo.klaviyo-android-sdk:push-fcm:4.3.0"
122+
implementation "com.github.klaviyo.klaviyo-android-sdk:forms:4.3.0"
123+
implementation "com.github.klaviyo.klaviyo-android-sdk:location:4.3.0"
124124
}
125125
```
126126
</details>

docs/filelogger-instructions.md

Lines changed: 0 additions & 171 deletions
This file was deleted.

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
<!-- Redirect to latest version -->
2-
<meta HTTP-EQUIV="REFRESH" content="0; url=./4.3.1/index.html">
2+
<meta HTTP-EQUIV="REFRESH" content="0; url=./4.3.0/index.html">

sample/src/main/java/com/klaviyo/sample/SampleApplication.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ import android.app.Application
44
import android.content.Context
55
import android.widget.Toast
66
import com.klaviyo.analytics.Klaviyo
7+
import com.klaviyo.core.Registry
8+
import com.klaviyo.forms.FormLifecycleEvent.FormCtaClicked
9+
import com.klaviyo.forms.FormLifecycleEvent.FormDismissed
10+
import com.klaviyo.forms.FormLifecycleEvent.FormShown
711
import com.klaviyo.forms.registerForInAppForms
12+
import com.klaviyo.forms.registerFormLifecycleCallback
813
import com.klaviyo.location.registerGeofencing
914

1015
class SampleApplication : Application() {
@@ -22,6 +27,26 @@ class SampleApplication : Application() {
2227
// If not using a deep link handler, Klaviyo will send an Intent to your app with the deep link in intent.data
2328
showToast("Deep link to: $uri")
2429
}
30+
.registerFormLifecycleCallback { event ->
31+
// OPTIONAL SETUP NOTE: Register a callback to receive form lifecycle events
32+
// This allows you to track when forms are shown, dismissed, or when CTAs are clicked
33+
when (event) {
34+
is FormShown -> {
35+
Registry.log.debug("Form shown: ${event.formId} ${event.formName}")
36+
showToast("Form shown: ${event.formId} ${event.formName}")
37+
}
38+
is FormDismissed -> {
39+
Registry.log.debug("Form dismissed: ${event.formId} ${event.formName}")
40+
showToast("Form dismissed: ${event.formId} ${event.formName}")
41+
}
42+
is FormCtaClicked -> {
43+
Registry.log.debug(
44+
"Form CTA: ${event.buttonLabel} -> ${event.deepLinkUrl}"
45+
)
46+
showToast("Form CTA: ${event.buttonLabel} -> ${event.deepLinkUrl}")
47+
}
48+
}
49+
}
2550
}
2651
}
2752

0 commit comments

Comments
 (0)