diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5479a5..6182a21 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,7 +123,7 @@ jobs: - uses: ruby/setup-ruby@v1 with: - ruby-version: '3.2.2' + ruby-version: '2.6.10' - name: Setup uses: ./.github/actions/setup @@ -158,54 +158,11 @@ jobs: - name: Install cocoapods if: env.turbo_cache_hit != 1 && steps.cocoapods-cache.outputs.cache-hit != 'true' run: | - yarn pod-install example/ios - brew install watchman + cd example/ios + pod install env: NO_FLIPPER: 1 - name: Build example for iOS run: | yarn turbo run build:ios --cache-dir="${{ env.TURBO_CACHE_DIR }}" - - - generate-documentation: - # Only run on master branch push (e.g. after pull request merge). - if: github.event_name == 'push' - runs-on: ubuntu-22.04 - env: - CI_COMMIT_MESSAGE: Generated docs for ${{ github.sha }} - GH_TOKEN: ${{ github.token }} - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: documentation - fetch-depth: 0 - - - name: Setup - uses: ./.github/actions/setup - - - name: Git config - run: | - git config user.name github-actions - git config user.email github-actions@github.com - git fetch origin - - - name: Create branch for docs PR - run: | - git checkout -b "documentation-${{ github.sha }}" - git merge origin/master --no-edit --strategy-option theirs - - - name: Generate docs - run: | - yarn generate-docs - - - name: Commit and push docs - run: | - git add docs - git commit -m "${{ env.CI_COMMIT_MESSAGE }}" - git push -u origin "documentation-${{ github.sha }}" - - - name: Create PR for doc updates - run: | - gh pr create --draft --title "Generated Docs for \"$(git show -s --format=%B ${{ github.sha }})\"" --body "This PR was automatically generated by a GitHub Action for ${{ github.sha }}." -B "documentation" -H "documentation-${{ github.sha }}" diff --git a/.github/workflows/doc-bot.yml b/.github/workflows/doc-bot.yml new file mode 100644 index 0000000..7fa9943 --- /dev/null +++ b/.github/workflows/doc-bot.yml @@ -0,0 +1,57 @@ +name: CI + +on: + push: + branches: + - master + +permissions: + contents: write + pull-requests: write + +jobs: + + generate-documentation: + runs-on: ubuntu-22.04 + env: + CI_COMMIT_MESSAGE: Generated docs for ${{ github.sha }} + GH_TOKEN: ${{ github.token }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: documentation + fetch-depth: 0 + + - name: Setup + uses: ./.github/actions/setup + + - name: Git config + run: | + git config user.name github-actions + git config user.email github-actions@github.com + git fetch origin + + - name: Create branch for docs PR + run: | + git checkout -b "documentation-${{ github.sha }}" + git merge origin/master --no-edit --strategy-option theirs + + - name: Generate docs + run: | + yarn generate-docs + + - name: Commit and push docs + run: | + if [ $(git status -s -uno | wc -l) -eq 0 ]; then + echo "No documentation to change" + exit 0 + fi + + git add docs + git commit -m "${{ env.CI_COMMIT_MESSAGE }}" + git push -u origin "documentation-${{ github.sha }}" + + - name: Create PR for doc updates + run: | + gh pr create --title "Generated Docs for \"$(git show -s --format=%B ${{ github.sha }})\"" --body "This PR was automatically generated by a GitHub Action for ${{ github.sha }}." -B "documentation" -H "documentation-${{ github.sha }}" diff --git a/README.md b/README.md index 2fdb3c2..32adfff 100644 --- a/README.md +++ b/README.md @@ -2,99 +2,124 @@ ⚠️ This repository is in beta development ⚠️ -Official Klaviyo React Native SDK +The Klaviyo React Native SDK allows developers to incorporate Klaviyo analytics and push notification functionality in +their React Native applications for Android and iOS. It is a Typescript wrapper (native module bridge) around the native +Klaviyo iOS and Android SDKs. For more information on the native SDKs, please see the +[iOS](https://github.com/klaviyo/klaviyo-swift-sdk) and [Android](https://github.com/klaviyo/klaviyo-android-sdk). +repositories. This repo also contains a basic [React Native sample app](./example) to assist your integration. -## Overview +The SDK assists in identifying users and tracking user events via the latest [Klaviyo Client APIs](https://developers.klaviyo.com/en/reference/api_overview). +To reduce performance overhead, API requests are queued and sent in batches. The queue is persisted to local storage +so that data is not lost if the device is offline or the app is terminated. -klaviyo-react-native-sdk is an SDK, written in TypeScript, that can be integrated into your React Native App. -The SDK enables you to engage with your customers using push notifications. In addition, you will be able to take advantage of Klaviyo's identification and event tracking functionality. -Once integrated, your marketing team will be able to better understand your app users' needs and send them timely messages via APNs/Google FCM. +Once integrated, your marketing team will be able to better understand your app users' needs and send them timely +push notifications via FCM (Firebase Cloud Messaging) and APNs (Apple Push Notification Service). -This SDK is a wrapper (native module bridge) around the native Klaviyo iOS and Android SDKs. -For more information on the native SDKs, please see the [iOS](https://github.com/klaviyo/klaviyo-swift-sdk) and [Android](https://github.com/klaviyo/klaviyo-android-sdk) repositories. +## Requirements +For initial beta release, the SDK was developed and tested against the latest minor release of React Native (0.73). +We are actively testing and expanding support to the latest patch releases of recent minor versions of React Native. -## Installation - -The Klaviyo React Native SDK is available via [NPM](http://npmjs.com). To add it to your project, run the following from your project's root directory: +### React Native +- `0.68.7+` - We have successfully compiled this SDK on a bare React Native template app down to `0.68.7`. + Testing is ongoing to verify on older versions. -```sh -npm install klaviyo-react-native-sdk -``` +### Android +- `minSdkVersion` of `23+` +- `compileSdkVersion` of `34+` -### iOS Setup +### iOS +- Minimum Deployment Target `13.0+` -To get started with iOS setup, you need to run the following command in the `ios` directory of your React Native project: +## Installation +The Klaviyo React Native SDK is available via [NPM](http://npmjs.com). To add it to your project, +run the following from your project's root directory: ```sh -pod install -``` - -This may require you to install [Cocoapods](https://cocoapods.org/). - -Once you have installed all the dependencies using cocoapods, you should have access to the native Klaviyo iOS SDK which we will use in the following section to setup your react native iOS project. - -### Troubleshooting pod install issues - -if you are seeing issues with deployment versions when installing pods, -you may need to update you minimum iOS version to 13.0 in your Podfile. - -An example of overriding the minimum iOS version in your Podfile is shown below: - -```ruby -MIN_IOS_OVERRIDE = '13.0' -if Gem::Version.new(MIN_IOS_OVERRIDE) > Gem::Version.new(min_ios_version_supported) - min_ios_version_supported = MIN_IOS_OVERRIDE -end -# existing code -platform :ios, min_ios_version_supported -``` - -Another option is to use `IPHONEOS_DEPLOYMENT_TARGET` from your Xcode project file like below, - -```ruby -####### -# Read min iOS version from Xcode project and set as min iOS version for Podfile -require 'xcodeproj' - -project_path = './YOUR_XCODE_PROJECT.xcodeproj' -project = Xcodeproj::Project.open(project_path) -min_ios_version_supported = project.build_configurations.first.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] -###### +# Using npm +npm install klaviyo-react-native-sdk -platform :ios, min_ios_version_supported +# Using yarn +yarn add klaviyo-react-native-sdk ``` -### Android Setup - -For Android, there are no additional installation requirements. The React Native SDK gradle file exposes transitive dependencies upon the Klaviyo Android SDK -so you can import in your kotlin/java classes without modifying your gradle files. +### Android +Android installation requirements may vary depending upon your project configuration and other dependencies. +The Klaviyo React Native SDK's `build.gradle` file exposes transitive dependencies upon the Klaviyo Android SDK, +so you can import Android Klaviyo SDK references from your Kotlin/Java files without modifying your gradle configuration. -## SDK Initialization +#### React Native 0.73.x +There are no additional installation requirements. Android support is fully tested and verified, +including `minSdkVersion=23`. -Initialization should be done from the native layer: +#### React Native 0.68.x - 0.72.x +We have successfully compiled the Klaviyo React Native SDK in a bare React Native template app for these versions +with the following modifications to the `android/build.gradle` file: +- Set `compileSdkVersion=34` +- Set `minSdkVersion=23` -### Android +#### React Native <= 0.67.x +We are actively working to verify compatibility with these versions. If you encounter issues, please file an issue. -Follow the [Android](https://github.com/klaviyo/klaviyo-android-sdk#Initialization) guide on initializing. +#### Android Troubleshooting +- We have seen projects, particularly on react-native versions `0.72.x` and `0.71.x`, that required a `minSdkVersion` + of `24`, despite the Klaviyo Android SDK supporting API 23+. If you encounter this, please file an issue in our + repository and provide version numbers of your react-native dependencies. ### iOS - -Here we'll create the native iOS SDK instance and initialize it with your Klaviyo public key. - -```swift -KlaviyoSDK().initialize(with: "YOUR_KLAVIYO_PUBLIC_API_KEY") +After installing the npm package, run the following command in the `ios` directory of your React Native project. +Install [Cocoapods](https://cocoapods.org/) if you have not already. +```sh +pod install --repo-update ``` +#### iOS Troubleshooting +If you are seeing issues related to `minimum deployment target` when installing pods, you may need to update your +minimum iOS version to 13.0 in your Podfile with one of the following strategies. +- Specify iOS version directly in the `Podfile`: + ```ruby + MIN_IOS_OVERRIDE = '13.0' + if Gem::Version.new(MIN_IOS_OVERRIDE) > Gem::Version.new(min_ios_version_supported) + min_ios_version_supported = MIN_IOS_OVERRIDE + end + # existing code + platform :ios, min_ios_version_supported + ``` +- Set the deployment target to 13.0 in XCode, and then pull `IPHONEOS_DEPLOYMENT_TARGET` from the XCode project: + ```ruby + ####### + # Read min iOS version from Xcode project and set as min iOS version for Podfile + require 'xcodeproj' + + project_path = './YOUR_XCODE_PROJECT.xcodeproj' + project = Xcodeproj::Project.open(project_path) + min_ios_version_supported = project.build_configurations.first.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] + ###### + + platform :ios, min_ios_version_supported + ``` + +## Initialization +The SDK must be initialized with the short alphanumeric +[public API key](https://help.klaviyo.com/hc/en-us/articles/115005062267#difference-between-public-and-private-api-keys1) +for your Klaviyo account, also known as your Site ID. Initialization is done in the native layer, and must occur before +any other SDK methods can be invoked. Follow the native SDK instructions for initialization, and refer to the +[example app](./example) in this repository for guidance: +- [Android SDK instructions](https://github.com/klaviyo/klaviyo-android-sdk#Initialization), and + [example app `MainApplication.kt`](./example/android/app/src/main/java/com/klaviyoreactnativesdkexample/MainApplication.kt#L39) +- [iOS SDK instructions](https://github.com/klaviyo/klaviyo-swift-sdk#Initialization), and + [example app `AppDelegate.mm`](./example/ios/KlaviyoReactNativeSdkExample/AppDelegate.mm#L14) + ## Identifying a Profile +The SDK provides methods to identify profiles via the +[Create Client Profile API](https://developers.klaviyo.com/en/reference/create_client_profile). +A profile can be identified by any combination of the following: -The SDK provides helpers for identifying profiles and syncing via the -[Klaviyo client API](https://developers.klaviyo.com/en/reference/create_client_profile). -All profile identifiers (email, phone, external ID, anonymous ID) are persisted to local storage -so that the SDK can keep track of the current profile. +- External ID: A unique identifier used by customers to associate Klaviyo profiles with profiles in an external system, + such as a point-of-sale system. Format varies based on the external system. +- Individual's email address +- Individual's phone number in [E.164 format](https://help.klaviyo.com/hc/en-us/articles/360046055671#h_01HE5ZYJEAHZKY6WZW7BAD36BG) -The Klaviyo SDK does not validate email address or phone number inputs locally. See -[documentation](https://help.klaviyo.com/hc/en-us/articles/360046055671-Accepted-phone-number-formats-for-SMS-in-Klaviyo) -for guidance on proper phone number formatting. +Identifiers are persisted to local storage on each platform so that the SDK can keep track of the current profile. Profile attributes can be set all at once: @@ -128,7 +153,12 @@ Klaviyo.setExternalId('12345'); Klaviyo.setProfileAttribute(ProfilePropertyKey.FIRST_NAME, 'Kermit'); ``` -If a user is logged out or if you want to reset the profile for some reason, use the following: +Either way, the native SDKs will group and batch API calls to improve performance. + +### Reset Profile +To start a _new_ profile altogether (e.g. if a user logs out), either call `Klaviyo.resetProfile()` +to clear the currently tracked profile identifiers (e.g. on logout), or use `Klaviyo.setProfile(profile)` +to overwrite it with a new profile object. ```typescript import { Klaviyo } from 'klaviyo-react-native-sdk'; @@ -136,11 +166,16 @@ import { Klaviyo } from 'klaviyo-react-native-sdk'; Klaviyo.resetProfile(); ``` -## Event Tracking +### Anonymous Tracking +Klaviyo will track unidentified users with an autogenerated ID whenever a push token is set or an event is created. +That way, you can collect push tokens and track events prior to collecting profile identifiers such as email or +phone number. When an identifier is provided, Klaviyo will merge the anonymous user with an identified user. -The SDK also provides tools for tracking analytics events to the Klaviyo API. -A list of common Klaviyo-defined event names is provided in [MetricName](https://github.com/klaviyo/klaviyo-react-native-sdk/blob/master/src/Event.ts), or -you can just provide a string for a custom event name. +## Event Tracking +The SDK also provides tools for tracking analytics events via the +[Create Client Event API](https://developers.klaviyo.com/en/reference/create_client_event). +A list of common Klaviyo-defined event metrics is provided in [`MetricName`](https://github.com/klaviyo/klaviyo-react-native-sdk/blob/master/src/Event.ts), +or you can just provide a string for a custom event name. Below is an example using one of the Klaviyo-defined event names: @@ -164,40 +199,75 @@ import { Klaviyo } from 'klaviyo-react-native-sdk'; Klaviyo.createEvent({ name: 'My Custom Event', }); -Klaviyo.createEvent(event); ``` ## Push Notifications -When setting up push notifications (including rich push notifications), you will need to follow directions from the [iOS](https://github.com/klaviyo/klaviyo-swift-sdk?tab=readme-ov-file#Push-Notifications) and [Android](https://github.com/klaviyo/klaviyo-android-sdk?tab=readme-ov-file#Push-Notifications) SDKs. - -## Deep Linking - -To handle deep links in your app, start by familiarizing yourself with the React Native [guide](https://reactnative.dev/docs/linking) to deep linking. Once you've done that, you should follow directions from the [iOS](https://github.com/klaviyo/klaviyo-swift-sdk?tab=readme-ov-file#Deep-Linking) and [Android](https://github.com/klaviyo/klaviyo-android-sdk?tab=readme-ov-file#Deep-Linking) SDKs. -The sections below give additional details for each platform as it pertains to React Native. - -### iOS - -As shown in the native SDK documentation, you can follow option 1 or 2. - -With option 1, when you get the callback, you can handle it as follows: - -```objective-c -[RCTLinkingManager application:application openURL:url options:options] -``` - -Since you won't have `options`, you can just pass in an empty dictionary for that parameter. - -With option 2, when you handle the open url (in [`application(_:open:options)`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application)), -you call the linking code block above similar to what you would do with option 1. - -### Android - -On Android, simply follow the [Android SDK docs](https://github.com/klaviyo/klaviyo-android-sdk?tab=readme-ov-file#Deep-Linking) on handling intent filters. - -### React Native Changes - -Then on the React Native side, you can handle the deep link as follows: +### Prerequisites +Integrating push notifications is highly platform-specific. Begin by thoroughly reviewing the setup +instructions for Push Notifications in the README from each native Klaviyo SDK: +- [Android](https://github.com/klaviyo/klaviyo-android-sdk#Push-Notifications) +- [iOS](https://github.com/klaviyo/klaviyo-swift-sdk#Push-Notifications) + +### Setup +Refer to the following README sections on push setup: +- [Android](https://github.com/klaviyo/klaviyo-android-sdk#Setup) +- [iOS](https://github.com/klaviyo/klaviyo-swift-sdk#Setup) + +### Collecting Push Tokens +Push tokens must be collected in the native layer. Follow the platform-specific instructions below: +- [Android](https://github.com/klaviyo/klaviyo-android-sdk#Collecting-Push-Tokens) +- [iOS](https://github.com/klaviyo/klaviyo-swift-sdk#Collecting-Push-Tokens) + +#### Notification Permission +Requesting user permission to display notifications can be managed in the native layer as instructed in our native SDK +documentation, or with a third party library that provides cross-platform permissions APIs. If you opt for a +cross-platform permission solution, you will still need to provide the Klaviyo SDK with the push token from the +native layer after a permission change. + +### Receiving Push Notifications +You can send test notifications to a specific token using the +[push notification preview](https://help.klaviyo.com/hc/en-us/articles/18011985278875) +feature in order to test your integration. + +#### Rich Push +[Rich Push](https://help.klaviyo.com/hc/en-us/articles/16917302437275) is the ability to add images to +push notification messages. On iOS, you will need to implement an extension service to attach images to notifications. +No additional setup is needed to support rich push on Android. +- [Android](https://github.com/klaviyo/klaviyo-android-sdk#Rich-Push) +- [iOS](https://github.com/klaviyo/klaviyo-swift-sdk#Rich-Push) + +#### Tracking Open Events +Klaviyo tracks push opens events with a specially formatted event `Opened Push` that includes message tracking +parameters in the event properties. To track push opens, you will need to follow platform-specific instructions: +- [Android](https://github.com/klaviyo/klaviyo-android-sdk#Tracking-Open-Events) +- [iOS](https://github.com/klaviyo/klaviyo-swift-sdk#Tracking-Open-Events) + +#### Tracking Open Events +To track push notification opens, you must call `Klaviyo.handlePush(intent)` when your app is launched from an intent. +This method will check if the app was opened from a notification originating from Klaviyo and if so, create an +`Opened Push` event with required message tracking parameters. For example: + +#### Deep Linking +[Deep Links](https://help.klaviyo.com/hc/en-us/articles/14750403974043) allow you to navigate to a particular +page within your app in response to the user opening a notification. Familiarize yourself with the +[React Native Guide](https://reactnative.dev/docs/linking) to deep linking, then read through the platform-specific +instructions below. +- [Android](https://github.com/klaviyo/klaviyo-android-sdk#Deep-Linking) instructions for handling intent filters +- [iOS](https://github.com/klaviyo/klaviyo-swift-sdk#Deep-Linking) + As shown in the native SDK documentation, you can follow option 1 or 2. + With option 1, when you get the callback, you can handle it as follows: + + ```objective-c + [RCTLinkingManager application:application openURL:url options:options] + ``` + + Since you won't have `options`, you can just pass in an empty dictionary for that parameter. + + With option 2, when you handle the open url (in [`application(_:open:options)`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application)), + you call the linking code block above similar to what you would do with option 1. + +In your React Native code, you can handle the deep link as follows: ```typescript import { Linking } from 'react-native'; @@ -211,15 +281,13 @@ Linking.getInitialURL().then((url) => { }); ``` -## Push Permissions - -It is recommended that handling push permissions be done from the native layer. On iOS, you can follow the [iOS](https://github.com/klaviyo/klaviyo-swift-sdk?tab=readme-ov-file#sending-push-notifications) guide on requesting permissions. On Android, you can follow the [Android](https://source.android.com/docs/core/display/notification-perm) guide on requesting permissions. - ## Contributing - -See the [contributing guide](.github/CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow. +Refer to the [contributing guide](.github/CONTRIBUTING.md) to learn how to contribute to the Klaviyo React Native SDK. +We welcome your feedback in the [discussion](https://github.com/klaviyo/klaviyo-react-native-sdk/discussions) +and [issues](https://github.com/klaviyo/klaviyo-react-native-sdk/issues) sections of our public GitHub repository. ## License +The Klaviyo React Native SDK is available under the terms of the MIT license. See [LICENSE](./LICENSE) for more info. -## License -The Klaviyo React Native SDK is available under the MIT license. See [LICENSE](./LICENSE) for more info. +## Code Documentation +Browse complete autogenerated code documentation [here](https://klaviyo.github.io/klaviyo-react-native-sdk/). diff --git a/android/build.gradle b/android/build.gradle index 35aac48..1146662 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -103,15 +103,33 @@ repositories { } def kotlin_version = getExtOrDefault("kotlinVersion") +def localProperties = new Properties() +if (rootProject.file("local.properties").canRead()) { + localProperties.load(new FileInputStream(rootProject.file("local.properties"))) +} +def reactNativeVersion = localProperties['reactNativeAndroidVersion'] ?: "" + dependencies { - // For < 0.71, this will be from the local maven repo - // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin - //noinspection GradleDynamicVersion - implementation "com.facebook.react:react-android:0.73.1" + if (reactNativeVersion) { + // For local development of the SDK code, specify the react-android version to use + // So that the SDK can be built and .kt files are linted against a real version of react-native + implementation "com.facebook.react:react-android:$reactNativeVersion" + } else { + // Production build / once embedded in a react-native app, + // the react-native version gets loaded in from the application dependencies. + // For < 0.71, this will be from the local maven repo + // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin + //noinspection GradleDynamicVersion + implementation "com.facebook.react:react-native:+" + } implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + + // Klaviyo Android SDK api "com.github.klaviyo.klaviyo-android-sdk:analytics:2.0.0" api "com.github.klaviyo.klaviyo-android-sdk:push-fcm:2.0.0" + + // We used reflection to enumerate keywords in the Klaviyo Android SDK dynamically implementation "org.jetbrains.kotlin:kotlin-reflect:1.8.21" } diff --git a/android/gradle.properties b/android/gradle.properties index b997206..e3ce6fc 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -12,7 +12,7 @@ org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryErro # org.gradle.parallel=true #Tue Dec 19 15:08:27 EST 2023 KlaviyoReactNativeSdk_compileSdkVersion=31 -KlaviyoReactNativeSdk_kotlinVersion=1.7.0 +KlaviyoReactNativeSdk_kotlinVersion=1.8.0 KlaviyoReactNativeSdk_minSdkVersion=23 KlaviyoReactNativeSdk_ndkversion=21.4.7075529 KlaviyoReactNativeSdk_targetSdkVersion=31 diff --git a/android/local.properties b/android/local.properties new file mode 100644 index 0000000..509f9fd --- /dev/null +++ b/android/local.properties @@ -0,0 +1,7 @@ +## Changes in this file must *NOT* be tracked by Version Control Systems, +# as it contains information specific to your local configuration. +# Only the base template should be checked in to VCS. + +## Uncomment for local SDK development, so that gradle can locate the +# correct RN version outside the context of an application +#reactNativeAndroidVersion=0.73.1 diff --git a/android/src/main/java/com/klaviyoreactnativesdk/KlaviyoReactNativeSdkModule.kt b/android/src/main/java/com/klaviyoreactnativesdk/KlaviyoReactNativeSdkModule.kt index 01f36c9..7dcfd2a 100644 --- a/android/src/main/java/com/klaviyoreactnativesdk/KlaviyoReactNativeSdkModule.kt +++ b/android/src/main/java/com/klaviyoreactnativesdk/KlaviyoReactNativeSdkModule.kt @@ -49,7 +49,7 @@ class KlaviyoReactNativeSdkModule internal constructor(private val context: Reac override fun setProfile(profile: ReadableMap) { val parsedProfile = Profile() - profile.toHashMap().forEach { (key, value) -> + profile.toHashMap().iterator().forEach { (key, value) -> when (key) { LOCATION, PROPERTIES -> (value as? HashMap<*, *>)?.forEach { (key, value) -> diff --git a/docs/assets/highlight.css b/docs/assets/highlight.css index 6d44ef6..f2d959e 100644 --- a/docs/assets/highlight.css +++ b/docs/assets/highlight.css @@ -1,20 +1,20 @@ :root { - --light-hl-0: #795E26; - --dark-hl-0: #DCDCAA; - --light-hl-1: #000000; - --dark-hl-1: #D4D4D4; - --light-hl-2: #A31515; - --dark-hl-2: #CE9178; - --light-hl-3: #0070C1; - --dark-hl-3: #4FC1FF; - --light-hl-4: #AF00DB; - --dark-hl-4: #C586C0; - --light-hl-5: #267F99; - --dark-hl-5: #4EC9B0; - --light-hl-6: #0000FF; - --dark-hl-6: #569CD6; - --light-hl-7: #008000; - --dark-hl-7: #6A9955; + --light-hl-0: #008000; + --dark-hl-0: #6A9955; + --light-hl-1: #795E26; + --dark-hl-1: #DCDCAA; + --light-hl-2: #000000; + --dark-hl-2: #D4D4D4; + --light-hl-3: #A31515; + --dark-hl-3: #CE9178; + --light-hl-4: #0000FF; + --dark-hl-4: #569CD6; + --light-hl-5: #0070C1; + --dark-hl-5: #4FC1FF; + --light-hl-6: #AF00DB; + --dark-hl-6: #C586C0; + --light-hl-7: #267F99; + --dark-hl-7: #4EC9B0; --light-hl-8: #001080; --dark-hl-8: #9CDCFE; --light-hl-9: #098658; diff --git a/docs/enums/EventName.html b/docs/enums/EventName.html index 60b8629..5efcf67 100644 --- a/docs/enums/EventName.html +++ b/docs/enums/EventName.html @@ -1,10 +1,10 @@ EventName | klaviyo-react-native-sdk

EventName is a convenience enum for the names of common events that can be tracked.

-

Enumeration Members

Enumeration Members

ADDED_TO_CART_METRIC: number

The 'Added to Cart' event is used to track when a user adds a product to their cart.

-
OPENED_APP_METRIC: number

The 'Opened App' event is used to track when a user opens the app.

-
STARTED_CHECKOUT_METRIC: number

The 'Started Checkout' event is used to track when a user starts the checkout process.

-
VIEWED_PRODUCT_METRIC: number

The 'Viewed Product' event is used to track when a user views a product.

-

Generated using TypeDoc

\ No newline at end of file +
OPENED_APP_METRIC: number

The 'Opened App' event is used to track when a user opens the app.

+
STARTED_CHECKOUT_METRIC: number

The 'Started Checkout' event is used to track when a user starts the checkout process.

+
VIEWED_PRODUCT_METRIC: number

The 'Viewed Product' event is used to track when a user views a product.

+

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/enums/ProfileProperty.html b/docs/enums/ProfileProperty.html index c1e7775..45b14d5 100644 --- a/docs/enums/ProfileProperty.html +++ b/docs/enums/ProfileProperty.html @@ -1,5 +1,5 @@ ProfileProperty | klaviyo-react-native-sdk

Enumeration ProfileProperty

Enum for various profile properties that can be set on a user

-

Enumeration Members

Enumeration Members

ADDRESS1 ADDRESS2 CITY COUNTRY @@ -19,22 +19,22 @@ TITLE ZIP

Enumeration Members

ADDRESS1: number

First line of street address

-
ADDRESS2: number

Second line of street address

-
CITY: number

City name

-
COUNTRY: number

Country name

-
EMAIL: number

Individual's email address

-
EXTERNAL_ID: number

A unique identifier used by customers to associate Klaviyo profiles with profiles in an external system, such as a point-of-sale system. Format varies based on the external system.

-
FIRST_NAME: number

Individual's first name

-
IMAGE: number

URL pointing to the location of a profile image

-
LAST_NAME: number

Individual's last name

-
LATITUDE: number

Latitude coordinate. We recommend providing a precision of four decimal places.

-
LOCATION: number

An object containing location information for this profile

-
LONGITUDE: number

Longitude coordinate. We recommend providing a precision of four decimal places.

-
ORGANIZATION: number

Name of the company or organization within the company for whom the individual works

-
PHONE_NUMBER: number

Individual's phone number in E.164 format

-
PROPERTIES: number

An object containing key/value pairs for any custom properties assigned to this profile

-
REGION: number

Region within a country, such as state or province

-
TIMEZONE: number

Time zone name. We recommend using time zones from the IANA Time Zone Database.

-
TITLE: number

Individual's job title

-
ZIP: number

Zip code

-

Generated using TypeDoc

\ No newline at end of file +
ADDRESS2: number

Second line of street address

+
CITY: number

City name

+
COUNTRY: number

Country name

+
EMAIL: number

Individual's email address

+
EXTERNAL_ID: number

A unique identifier used by customers to associate Klaviyo profiles with profiles in an external system, such as a point-of-sale system. Format varies based on the external system.

+
FIRST_NAME: number

Individual's first name

+
IMAGE: number

URL pointing to the location of a profile image

+
LAST_NAME: number

Individual's last name

+
LATITUDE: number

Latitude coordinate. We recommend providing a precision of four decimal places.

+
LOCATION: number

An object containing location information for this profile

+
LONGITUDE: number

Longitude coordinate. We recommend providing a precision of four decimal places.

+
ORGANIZATION: number

Name of the company or organization within the company for whom the individual works

+
PHONE_NUMBER: number

Individual's phone number in E.164 format

+
PROPERTIES: number

An object containing key/value pairs for any custom properties assigned to this profile

+
REGION: number

Region within a country, such as state or province

+
TIMEZONE: number

Time zone name. We recommend using time zones from the IANA Time Zone Database.

+
TITLE: number

Individual's job title

+
ZIP: number

Zip code

+

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/index.html b/docs/index.html index ac8d42f..0b37a05 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,73 +1,170 @@ klaviyo-react-native-sdk

klaviyo-react-native-sdk

klaviyo-react-native-sdk

⚠️ This repository is in beta development ⚠️

-

Official Klaviyo React Native SDK

-

Overview

klaviyo-react-native-sdk is an SDK, written in TypeScript, that can be integrated into your React Native App. -The SDK enables you to engage with your customers using push notifications. In addition, you will be able to take advantage of Klaviyo's identification and event tracking functionality. -Once integrated, your marketing team will be able to better understand your app users' needs and send them timely messages via APNs/Google FCM.

-

This SDK is a wrapper (native module bridge) around the native Klaviyo iOS and Android SDKs. -For more information on the native SDKs, please see the iOS and Android repositories.

-

Installation

The Klaviyo React Native SDK is available via NPM. To add it to your project, run the following from your project's root directory:

-
npm install klaviyo-react-native-sdk
+

The Klaviyo React Native SDK allows developers to incorporate Klaviyo analytics and push notification functionality in +their React Native applications for Android and iOS. It is a Typescript wrapper (native module bridge) around the native +Klaviyo iOS and Android SDKs. For more information on the native SDKs, please see the +iOS and Android. +repositories. This repo also contains a basic React Native sample app to assist your integration.

+

The SDK assists in identifying users and tracking user events via the latest Klaviyo Client APIs. +To reduce performance overhead, API requests are queued and sent in batches. The queue is persisted to local storage +so that data is not lost if the device is offline or the app is terminated.

+

Once integrated, your marketing team will be able to better understand your app users' needs and send them timely +push notifications via FCM (Firebase Cloud Messaging) and APNs (Apple Push Notification Service).

+

Requirements

For initial beta release, the SDK was developed and tested against the latest minor release of React Native (0.73). +We are actively testing and expanding support to the latest patch releases of recent minor versions of React Native.

+

React Native

    +
  • 0.68.7+ - We have successfully compiled this SDK on a bare React Native template app down to 0.68.7. +Testing is ongoing to verify on older versions.
  • +
+

Android

    +
  • minSdkVersion of 23+
  • +
  • compileSdkVersion of 34+
  • +
+

iOS

    +
  • Minimum Deployment Target 13.0+
  • +
+

Installation

The Klaviyo React Native SDK is available via NPM. To add it to your project, +run the following from your project's root directory:

+
# Using npm
npm install klaviyo-react-native-sdk

# Using yarn
yarn add klaviyo-react-native-sdk
-

iOS Setup

To get started with iOS setup, you need to run the following command in the ios directory of your React Native project:

-
pod install
+

Android

Android installation requirements may vary depending upon your project configuration and other dependencies. +The Klaviyo React Native SDK's build.gradle file exposes transitive dependencies upon the Klaviyo Android SDK, +so you can import Android Klaviyo SDK references from your Kotlin/Java files without modifying your gradle configuration.

+

React Native 0.73.x

There are no additional installation requirements. Android support is fully tested and verified, +including minSdkVersion=23.

+

React Native 0.68.x - 0.72.x

We have successfully compiled the Klaviyo React Native SDK in a bare React Native template app for these versions +with the following modifications to the android/build.gradle file:

+
    +
  • Set compileSdkVersion=34
  • +
  • Set minSdkVersion=23
  • +
+

React Native <= 0.67.x

We are actively working to verify compatibility with these versions. If you encounter issues, please file an issue.

+

Android Troubleshooting

    +
  • We have seen projects, particularly on react-native versions 0.72.x and 0.71.x, that required a minSdkVersion +of 24, despite the Klaviyo Android SDK supporting API 23+. If you encounter this, please file an issue in our +repository and provide version numbers of your react-native dependencies.
  • +
+

iOS

After installing the npm package, run the following command in the ios directory of your React Native project. +Install Cocoapods if you have not already.

+
pod install --repo-update
 
-

This may require you to install Cocoapods.

-

Once you have installed all the dependencies using cocoapods, you should have access to the native Klaviyo iOS SDK which we will use in the following section to setup your react native iOS project.

-

Troubleshooting pod install issues

if you are seeing issues with deployment versions when installing pods, -you may need to update you minimum iOS version to 13.0 in your Podfile.

-

An example of overriding the minimum iOS version in your Podfile is shown below:

-
MIN_IOS_OVERRIDE = '13.0'
if Gem::Version.new(MIN_IOS_OVERRIDE) > Gem::Version.new(min_ios_version_supported)
min_ios_version_supported = MIN_IOS_OVERRIDE
end
# existing code
platform :ios, min_ios_version_supported +

iOS Troubleshooting

If you are seeing issues related to minimum deployment target when installing pods, you may need to update your +minimum iOS version to 13.0 in your Podfile with one of the following strategies.

+
    +
  • Specify iOS version directly in the Podfile:
    MIN_IOS_OVERRIDE = '13.0'
    if Gem::Version.new(MIN_IOS_OVERRIDE) > Gem::Version.new(min_ios_version_supported)
    min_ios_version_supported = MIN_IOS_OVERRIDE
    end
    # existing code
    platform :ios, min_ios_version_supported
    -

    Another option is to use IPHONEOS_DEPLOYMENT_TARGET from your Xcode project file like below,

    -
    #######
    # Read min iOS version from Xcode project and set as min iOS version for Podfile
    require 'xcodeproj'

    project_path = './YOUR_XCODE_PROJECT.xcodeproj'
    project = Xcodeproj::Project.open(project_path)
    min_ios_version_supported = project.build_configurations.first.build_settings['IPHONEOS_DEPLOYMENT_TARGET']
    ######

    platform :ios, min_ios_version_supported +
  • +
  • Set the deployment target to 13.0 in XCode, and then pull IPHONEOS_DEPLOYMENT_TARGET from the XCode project:
    #######
    # Read min iOS version from Xcode project and set as min iOS version for Podfile
    require 'xcodeproj'

    project_path = './YOUR_XCODE_PROJECT.xcodeproj'
    project = Xcodeproj::Project.open(project_path)
    min_ios_version_supported = project.build_configurations.first.build_settings['IPHONEOS_DEPLOYMENT_TARGET']
    ######

    platform :ios, min_ios_version_supported
    -

    Android Setup

    For Android, there are no additional installation requirements. The React Native SDK gradle file exposes transitive dependencies upon the Klaviyo Android SDK -so you can import in your kotlin/java classes without modifying your gradle files.

    -

    SDK Initialization

    Initialization should be done from the native layer:

    -

    Android

    Follow the Android guide on initializing.

    -

    iOS

    Here we'll create the native iOS SDK instance and initialize it with your Klaviyo public key.

    -
    KlaviyoSDK().initialize(with: "YOUR_KLAVIYO_PUBLIC_API_KEY")
    -
    -

    Identifying a Profile

    The SDK provides helpers for identifying profiles and syncing via the -Klaviyo client API. -All profile identifiers (email, phone, external ID, anonymous ID) are persisted to local storage -so that the SDK can keep track of the current profile.

    -

    The Klaviyo SDK does not validate email address or phone number inputs locally. See -documentation -for guidance on proper phone number formatting.

    +
  • +
+

Initialization

The SDK must be initialized with the short alphanumeric +public API key +for your Klaviyo account, also known as your Site ID. Initialization is done in the native layer, and must occur before +any other SDK methods can be invoked. Follow the native SDK instructions for initialization, and refer to the +example app in this repository for guidance:

+ +

Identifying a Profile

The SDK provides methods to identify profiles via the +Create Client Profile API. +A profile can be identified by any combination of the following:

+
    +
  • External ID: A unique identifier used by customers to associate Klaviyo profiles with profiles in an external system, +such as a point-of-sale system. Format varies based on the external system.
  • +
  • Individual's email address
  • +
  • Individual's phone number in E.164 format
  • +
+

Identifiers are persisted to local storage on each platform so that the SDK can keep track of the current profile.

Profile attributes can be set all at once:

-
import { Klaviyo, Profile } from 'klaviyo-react-native-sdk';

const profile: Profile = {
email: 'kermit@example.com',
phone: '+15555555555',
externalId: '12345',
firstName: 'Kermit',
lastName: 'The Frog',
title: 'CEO',
organization: 'Muppets, Inc.',
location: {
latitude: 42.3601,
longitude: 71.0589,
},
};
Klaviyo.setProfile(profile); +
import { Klaviyo, Profile } from 'klaviyo-react-native-sdk';

const profile: Profile = {
email: 'kermit@example.com',
phone: '+15555555555',
externalId: '12345',
firstName: 'Kermit',
lastName: 'The Frog',
title: 'CEO',
organization: 'Muppets, Inc.',
location: {
latitude: 42.3601,
longitude: 71.0589,
},
};
Klaviyo.setProfile(profile);

or individually:

-
import { ProfilePropertyKey, Klaviyo } from 'klaviyo-react-native-sdk';

Klaviyo.setEmail('kermit@example.com');
Klaviyo.setPhone('+15555555555');
Klaviyo.setExternalId('12345');
Klaviyo.setProfileAttribute(ProfilePropertyKey.FIRST_NAME, 'Kermit'); +
import { ProfilePropertyKey, Klaviyo } from 'klaviyo-react-native-sdk';

Klaviyo.setEmail('kermit@example.com');
Klaviyo.setPhone('+15555555555');
Klaviyo.setExternalId('12345');
Klaviyo.setProfileAttribute(ProfilePropertyKey.FIRST_NAME, 'Kermit');
-

If a user is logged out or if you want to reset the profile for some reason, use the following:

-
import { Klaviyo } from 'klaviyo-react-native-sdk';

Klaviyo.resetProfile(); +

Either way, the native SDKs will group and batch API calls to improve performance.

+

Reset Profile

To start a new profile altogether (e.g. if a user logs out), either call Klaviyo.resetProfile() +to clear the currently tracked profile identifiers (e.g. on logout), or use Klaviyo.setProfile(profile) +to overwrite it with a new profile object.

+
import { Klaviyo } from 'klaviyo-react-native-sdk';

Klaviyo.resetProfile();
-

Event Tracking

The SDK also provides tools for tracking analytics events to the Klaviyo API. -A list of common Klaviyo-defined event names is provided in MetricName, or -you can just provide a string for a custom event name.

+

Anonymous Tracking

Klaviyo will track unidentified users with an autogenerated ID whenever a push token is set or an event is created. +That way, you can collect push tokens and track events prior to collecting profile identifiers such as email or +phone number. When an identifier is provided, Klaviyo will merge the anonymous user with an identified user.

+

Event Tracking

The SDK also provides tools for tracking analytics events via the +Create Client Event API. +A list of common Klaviyo-defined event metrics is provided in MetricName, +or you can just provide a string for a custom event name.

Below is an example using one of the Klaviyo-defined event names:

-
import { Event, Klaviyo, EventName } from 'klaviyo-react-native-sdk';

const event: Event = {
name: EventName.STARTED_CHECKOUT_METRIC,
value: 99,
properties: { products: ['SKU1', 'SKU2'] },
};

Klaviyo.createEvent(event); +
import { Event, Klaviyo, EventName } from 'klaviyo-react-native-sdk';

const event: Event = {
name: EventName.STARTED_CHECKOUT_METRIC,
value: 99,
properties: { products: ['SKU1', 'SKU2'] },
};

Klaviyo.createEvent(event);

You can also create an event by providing a string for the event name as follows:

-
import { Klaviyo } from 'klaviyo-react-native-sdk';

Klaviyo.createEvent({
name: 'My Custom Event',
});
Klaviyo.createEvent(event); +
import { Klaviyo } from 'klaviyo-react-native-sdk';

Klaviyo.createEvent({
name: 'My Custom Event',
});
-

Push Notifications

When setting up push notifications (including rich push notifications), you will need to follow directions from the iOS and Android SDKs.

-

Deep Linking

To handle deep links in your app, start by familiarizing yourself with the React Native guide to deep linking. Once you've done that, you should follow directions from the iOS and Android SDKs. -The sections below give additional details for each platform as it pertains to React Native.

-

iOS

As shown in the native SDK documentation, you can follow option 1 or 2.

-

With option 1, when you get the callback, you can handle it as follows:

-
[RCTLinkingManager application:application openURL:url options:options]
+

Push Notifications

Prerequisites

Integrating push notifications is highly platform-specific. Begin by thoroughly reviewing the setup +instructions for Push Notifications in the README from each native Klaviyo SDK:

+ +

Setup

Refer to the following README sections on push setup:

+ +

Collecting Push Tokens

Push tokens must be collected in the native layer. Follow the platform-specific instructions below:

+ +

Notification Permission

Requesting user permission to display notifications can be managed in the native layer as instructed in our native SDK +documentation, or with a third party library that provides cross-platform permissions APIs. If you opt for a +cross-platform permission solution, you will still need to provide the Klaviyo SDK with the push token from the +native layer after a permission change.

+

Receiving Push Notifications

You can send test notifications to a specific token using the +push notification preview +feature in order to test your integration.

+

Rich Push

Rich Push is the ability to add images to +push notification messages. On iOS, you will need to implement an extension service to attach images to notifications. +No additional setup is needed to support rich push on Android.

+ +

Tracking Open Events

Klaviyo tracks push opens events with a specially formatted event Opened Push that includes message tracking +parameters in the event properties. To track push opens, you will need to follow platform-specific instructions:

+ +

Tracking Open Events

To track push notification opens, you must call Klaviyo.handlePush(intent) when your app is launched from an intent. +This method will check if the app was opened from a notification originating from Klaviyo and if so, create an +Opened Push event with required message tracking parameters. For example:

+

Deep Linking

Deep Links allow you to navigate to a particular +page within your app in response to the user opening a notification. Familiarize yourself with the +React Native Guide to deep linking, then read through the platform-specific +instructions below.

+
    +
  • Android instructions for handling intent filters

    +
  • +
  • iOS +As shown in the native SDK documentation, you can follow option 1 or 2. +With option 1, when you get the callback, you can handle it as follows:

    +
    [RCTLinkingManager application:application openURL:url options:options]
     

    Since you won't have options, you can just pass in an empty dictionary for that parameter.

    With option 2, when you handle the open url (in application(_:open:options)), you call the linking code block above similar to what you would do with option 1.

    -

    Android

    On Android, simply follow the Android SDK docs on handling intent filters.

    -

    React Native Changes

    Then on the React Native side, you can handle the deep link as follows:

    -
    import { Linking } from 'react-native';

    Linking.addEventListener('url', (event) => {
    console.log(event.url);
    });

    Linking.getInitialURL().then((url) => {
    console.log('Initial Url: url', url);
    }); +
  • +
+

In your React Native code, you can handle the deep link as follows:

+
import { Linking } from 'react-native';

Linking.addEventListener('url', (event) => {
console.log(event.url);
});

Linking.getInitialURL().then((url) => {
console.log('Initial Url: url', url);
});
-

Push Permissions

It is recommended that handling push permissions be done from the native layer. On iOS, you can follow the iOS guide on requesting permissions. On Android, you can follow the Android guide on requesting permissions.

-

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

-

License

License

The Klaviyo React Native SDK is available under the MIT license. See LICENSE for more info.

-

Generated using TypeDoc

\ No newline at end of file +

Contributing

Refer to the contributing guide to learn how to contribute to the Klaviyo React Native SDK. +We welcome your feedback in the discussion +and issues sections of our public GitHub repository.

+

License

The Klaviyo React Native SDK is available under the terms of the MIT license. See LICENSE for more info.

+

Code Documentation

Browse complete autogenerated code documentation here.

+

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/interfaces/Event.html b/docs/interfaces/Event.html index 0c50c1f..8174218 100644 --- a/docs/interfaces/Event.html +++ b/docs/interfaces/Event.html @@ -1,19 +1,19 @@ Event | klaviyo-react-native-sdk

Interface for an event

-
interface Event {
    name: string | EventName;
    properties?: EventProperties;
    uniqueId?: string;
    value?: number;
}

Properties

interface Event {
    name: string | EventName;
    properties?: EventProperties;
    uniqueId?: string;
    value?: number;
}

Properties

name: string | EventName

Name of the event. Must be less than 128 characters.

-
properties?: EventProperties

Properties of this event. Any top level property (that are not objects) can be +

properties?: EventProperties

Properties of this event. Any top level property (that are not objects) can be used to create segments. The $extra property is a special property. This records any non-segmentable values that can be referenced later. For example, HTML templates are useful on a segment but are not used to create a segment. There are limits placed onto the size of the data present. This must not exceed 5 MB. This must not exceed 300 event properties. A single string cannot be larger than 100 KB. Each array must not exceed 4000 elements. The properties cannot contain more than 10 nested levels.

-
uniqueId?: string

A unique identifier for an event. If the uniqueId is repeated for the same +

uniqueId?: string

A unique identifier for an event. If the uniqueId is repeated for the same profile and metric, only the first processed event will be recorded. If this is not present, this will use the time to the second. Using the default, this limits only one event per profile per second.

-
value?: number

A numeric value to associate with this event. For example, the dollar amount of a purchase.

-

Generated using TypeDoc

\ No newline at end of file +
value?: number

A numeric value to associate with this event. For example, the dollar amount of a purchase.

+

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/interfaces/KlaviyoInterface.html b/docs/interfaces/KlaviyoInterface.html index ec7abca..37965ff 100644 --- a/docs/interfaces/KlaviyoInterface.html +++ b/docs/interfaces/KlaviyoInterface.html @@ -1,7 +1,7 @@ KlaviyoInterface | klaviyo-react-native-sdk

The Klaviyo React Native SDK Interface

This interface extends the KlaviyoEventAPI and KlaviyoProfileApi interfaces, providing a unified API for interacting with Klaviyo's event tracking and profile management features.

-
interface KlaviyoInterface {
    createEvent(event): void;
    getEmail(callback): null | String;
    getExternalId(callback): null | String;
    getPhoneNumber(callback): null | String;
    resetProfile(): void;
    setEmail(email): void;
    setExternalId(externalId): void;
    setPhoneNumber(phoneNumber): void;
    setProfile(profile): void;
    setProfileAttribute(propertyKey, value): void;
}

Hierarchy

  • KlaviyoEventAPI
  • KlaviyoProfileApi
    • KlaviyoInterface

Methods

interface KlaviyoInterface {
    createEvent(event): void;
    getEmail(callback): null | String;
    getExternalId(callback): null | String;
    getPhoneNumber(callback): null | String;
    resetProfile(): void;
    setEmail(email): void;
    setExternalId(externalId): void;
    setPhoneNumber(phoneNumber): void;
    setProfile(profile): void;
    setProfileAttribute(propertyKey, value): void;
}

Hierarchy

  • KlaviyoEventAPI
  • KlaviyoProfileApi
    • KlaviyoInterface

Methods

  • Create a new event to track a profile's activity.

    Parameters

    • event: Event

      The event to track

      -

    Returns void

  • Retrieve a profile's email address.

    +

Returns void

  • Retrieve a profile's email address.

    Parameters

    • callback: undefined | Function

      The callback function to handle the response

      -

    Returns null | String

  • Retrieve a profile's external ID.

    +

Returns null | String

  • Retrieve a profile's external ID.

    Parameters

    • callback: undefined | Function

      The callback function to handle the response

      -

    Returns null | String

  • Retrieve a profile's phone number.

    +

Returns null | String

  • Retrieve a profile's phone number.

    Parameters

    • callback: undefined | Function

      The callback function to handle the response

      -

    Returns null | String

  • Clear the current profile and set it to a new anonymous profile

    -

    Returns void

  • Update a profile's email address.

    +

Returns null | String

  • Clear the current profile and set it to a new anonymous profile

    +

    Returns void

  • Update a profile's email address.

    Parameters

    • email: String

      The email address to set

      -

    Returns void

  • Update a profile's external ID.

    +

Returns void

  • Update a profile's external ID.

    Parameters

    • externalId: String

      The external ID to set

      -

    Returns void

  • Update a profile's phone number.

    +

Returns void

  • Update a profile's phone number.

    Parameters

    • phoneNumber: String

      The phone number to set

      -

    Returns void

  • Create and update properties about a profile without tracking an associated event.

    +

Returns void

  • Create and update properties about a profile without tracking an associated event.

    Parameters

    • profile: Profile

      The profile object to set

      -

    Returns void

  • Update a profile's properties.

    +

Returns void

  • Update a profile's properties.

    Parameters

    • propertyKey: ProfilePropertyKey

      The property key to set

    • value: String

      The property value to set

      -

    Returns void

Generated using TypeDoc

\ No newline at end of file +

Returns void

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/interfaces/Location.html b/docs/interfaces/Location.html index 4063d39..b89f596 100644 --- a/docs/interfaces/Location.html +++ b/docs/interfaces/Location.html @@ -1,5 +1,5 @@ Location | klaviyo-react-native-sdk

Interface for location information of a profile

-
interface Location {
    address1?: string;
    address2?: string;
    city?: string;
    country?: string;
    latitude?: number;
    longitude?: number;
    region?: string;
    timezone?: string;
    zip?: string;
}

Properties

interface Location {
    address1?: string;
    address2?: string;
    city?: string;
    country?: string;
    latitude?: number;
    longitude?: number;
    region?: string;
    timezone?: string;
    zip?: string;
}

Properties

Properties

address1?: string

First line of street address

-
address2?: string

Second line of street address

-
city?: string

City name

-
country?: string

Country name

-
latitude?: number

Latitude coordinate. We recommend providing a precision of four decimal places.

-
longitude?: number

Longitude coordinate. We recommend providing a precision of four decimal places.

-
region?: string

Region within a country, such as state or province

-
timezone?: string

Time zone name. We recommend using time zones from the IANA Time Zone Database.

-
zip?: string

Zip code

-

Generated using TypeDoc

\ No newline at end of file +
address2?: string

Second line of street address

+
city?: string

City name

+
country?: string

Country name

+
latitude?: number

Latitude coordinate. We recommend providing a precision of four decimal places.

+
longitude?: number

Longitude coordinate. We recommend providing a precision of four decimal places.

+
region?: string

Region within a country, such as state or province

+
timezone?: string

Time zone name. We recommend using time zones from the IANA Time Zone Database.

+
zip?: string

Zip code

+

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/interfaces/Profile.html b/docs/interfaces/Profile.html index ce98bfd..f4033d2 100644 --- a/docs/interfaces/Profile.html +++ b/docs/interfaces/Profile.html @@ -1,5 +1,5 @@ Profile | klaviyo-react-native-sdk

Interface for a profile

-
interface Profile {
    email?: string;
    externalId?: string;
    firstName?: string;
    image?: string;
    lastName?: string;
    location?: Location;
    organization?: string;
    phoneNumber?: string;
    properties?: ProfileProperties;
    title?: string;
}

Properties

interface Profile {
    email?: string;
    externalId?: string;
    firstName?: string;
    image?: string;
    lastName?: string;
    location?: Location;
    organization?: string;
    phoneNumber?: string;
    properties?: ProfileProperties;
    title?: string;
}

Properties

Properties

email?: string

Individual's email address

-
externalId?: string

A unique identifier used by customers to associate Klaviyo profiles with profiles in an external system, such as a point-of-sale system. Format varies based on the external system.

-
firstName?: string

Individual's first name

-
image?: string

URL pointing to the location of a profile image

-
lastName?: string

Individual's last name

-
location?: Location

An object containing location information for this profile

-
organization?: string

Name of the company or organization within the company for whom the individual works

-
phoneNumber?: string

Individual's phone number in E.164 format

-
properties?: ProfileProperties

An object containing key/value pairs for any custom properties assigned to this profile

-
title?: string

Individual's job title

-

Generated using TypeDoc

\ No newline at end of file +
externalId?: string

A unique identifier used by customers to associate Klaviyo profiles with profiles in an external system, such as a point-of-sale system. Format varies based on the external system.

+
firstName?: string

Individual's first name

+
image?: string

URL pointing to the location of a profile image

+
lastName?: string

Individual's last name

+
location?: Location

An object containing location information for this profile

+
organization?: string

Name of the company or organization within the company for whom the individual works

+
phoneNumber?: string

Individual's phone number in E.164 format

+
properties?: ProfileProperties

An object containing key/value pairs for any custom properties assigned to this profile

+
title?: string

Individual's job title

+

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/types/EventProperties.html b/docs/types/EventProperties.html index e9f3e69..772565e 100644 --- a/docs/types/EventProperties.html +++ b/docs/types/EventProperties.html @@ -1,2 +1,2 @@ EventProperties | klaviyo-react-native-sdk

Type alias EventProperties

EventProperties: Record<string, Object>

Type for event properties

-

Generated using TypeDoc

\ No newline at end of file +

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/types/ProfileProperties.html b/docs/types/ProfileProperties.html index fd73bc0..ac60a53 100644 --- a/docs/types/ProfileProperties.html +++ b/docs/types/ProfileProperties.html @@ -1,2 +1,2 @@ ProfileProperties | klaviyo-react-native-sdk

Type alias ProfileProperties

ProfileProperties: Record<ProfilePropertyKey, Object>

Type for profile properties

-

Generated using TypeDoc

\ No newline at end of file +

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/types/ProfilePropertyKey.html b/docs/types/ProfilePropertyKey.html index 964ca93..76c1954 100644 --- a/docs/types/ProfilePropertyKey.html +++ b/docs/types/ProfilePropertyKey.html @@ -1,2 +1,2 @@ ProfilePropertyKey | klaviyo-react-native-sdk

Type alias ProfilePropertyKey

ProfilePropertyKey: ProfileProperty | string

Type for a profile property key

-

Generated using TypeDoc

\ No newline at end of file +

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/variables/Klaviyo.html b/docs/variables/Klaviyo.html index 5f5aead..34d2b47 100644 --- a/docs/variables/Klaviyo.html +++ b/docs/variables/Klaviyo.html @@ -1,2 +1,2 @@ Klaviyo | klaviyo-react-native-sdk

Variable KlaviyoConst

Klaviyo: Spec = ...

Implementation of the KlaviyoInterface

-

Generated using TypeDoc

\ No newline at end of file +

Generated using TypeDoc

\ No newline at end of file diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 1aa8789..a214a51 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -70,6 +70,12 @@ def enableProguardInReleaseBuilds = false def jscFlavor = 'org.webkit:android-jsc:+' android { + def localProperties = new Properties() + if (rootProject.file("local.properties").canRead()) { + localProperties.load(new FileInputStream(rootProject.file("local.properties"))) + } + def apiKey = localProperties['publicApiKey'] ?: publicApiKey + ndkVersion rootProject.ext.ndkVersion buildToolsVersion rootProject.ext.buildToolsVersion compileSdk rootProject.ext.compileSdkVersion @@ -93,6 +99,7 @@ android { buildTypes { debug { signingConfig signingConfigs.debug + buildConfigField "String", "PUBLIC_API_KEY", "\"${apiKey}\"" } release { // Caution! In production, you need to generate your own keystore file. @@ -100,6 +107,7 @@ android { signingConfig signingConfigs.debug minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + buildConfigField "String", "PUBLIC_API_KEY", "\"${apiKey}\"" } } } diff --git a/example/android/app/src/main/java/com/klaviyoreactnativesdkexample/MainApplication.kt b/example/android/app/src/main/java/com/klaviyoreactnativesdkexample/MainApplication.kt index 53f2558..757cd4e 100644 --- a/example/android/app/src/main/java/com/klaviyoreactnativesdkexample/MainApplication.kt +++ b/example/android/app/src/main/java/com/klaviyoreactnativesdkexample/MainApplication.kt @@ -36,7 +36,7 @@ class MainApplication : Application(), ReactApplication { override fun onCreate() { super.onCreate() SoLoader.init(this, false) - Klaviyo.initialize("YOUR_PUBLIC_API_KEY", this) + Klaviyo.initialize(BuildConfig.PUBLIC_API_KEY, this) registerActivityLifecycleCallbacks(Klaviyo.lifecycleCallbacks) if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { diff --git a/example/android/gradle.properties b/example/android/gradle.properties index a46a5b9..2fe38e9 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -39,3 +39,7 @@ newArchEnabled=false # Use this property to enable or disable the Hermes JS engine. # If set to false, you will be using JSC instead. hermesEnabled=true + +# Public API Key for your Company +# or override this from an untracked local.properties file +publicApiKey=YOUR_PUBLIC_API_KEY diff --git a/example/android/local.properties b/example/android/local.properties new file mode 100644 index 0000000..76dc8c8 --- /dev/null +++ b/example/android/local.properties @@ -0,0 +1,6 @@ +## Changes in this file must *NOT* be tracked by Version Control Systems, +# as it contains information specific to your local configuration, +# such as your Klaviyo company ID aka "Public API Key". +# Only the base template should be checked in to VCS. + +#publicApiKey=YOUR_PUBLIC_API_KEY diff --git a/example/ios/KlaviyoReactNativeSdkExample/AppDelegate.mm b/example/ios/KlaviyoReactNativeSdkExample/AppDelegate.mm index 78af675..d321cc6 100644 --- a/example/ios/KlaviyoReactNativeSdkExample/AppDelegate.mm +++ b/example/ios/KlaviyoReactNativeSdkExample/AppDelegate.mm @@ -11,6 +11,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // They will be passed down to the ViewController used by React Native. self.initialProps = @{}; + [PushNotificationsHelper initializeSDK]; [PushNotificationsHelper requestPushPermission]; return [super application:application didFinishLaunchingWithOptions:launchOptions]; diff --git a/example/ios/KlaviyoReactNativeSdkExample/PushNotificationsHelper.swift b/example/ios/KlaviyoReactNativeSdkExample/PushNotificationsHelper.swift index 9cdbf8e..99fc528 100644 --- a/example/ios/KlaviyoReactNativeSdkExample/PushNotificationsHelper.swift +++ b/example/ios/KlaviyoReactNativeSdkExample/PushNotificationsHelper.swift @@ -5,6 +5,11 @@ import KlaviyoSwift @objc(PushNotificationsHelper) class PushNotificationsHelper: NSObject { + @objc + static func initializeSDK() { + KlaviyoSDK().initialize(with: "YOUR_PUBLIC_API_KEY") + } + @objc static func requestPushPermission() { // since we need the SDK to be initialized before setting the push token to it @@ -30,9 +35,4 @@ class PushNotificationsHelper: NSObject { static func setPushToken(token: Data) { KlaviyoSDK().set(pushToken: token) } - - @objc - private static func initializeSDK() { - KlaviyoSDK().initialize(with: "YOUR_PUBLIC_API_KEY") - } } diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 0438c07..7d6731c 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -72,12 +72,10 @@ PODS: - hermes-engine (0.73.1): - hermes-engine/Pre-built (= 0.73.1) - hermes-engine/Pre-built (0.73.1) - - klaviyo-react-native-sdk (0.1.0): - - glog - - KlaviyoSwift (= 3.0.0) - - RCT-Folly (= 2022.05.16.00) + - klaviyo-react-native-sdk (0.1.1): + - KlaviyoSwift (= 3.0.2) - React-Core - - KlaviyoSwift (3.0.0): + - KlaviyoSwift (3.0.2): - AnyCodable-FlightSchool - libevent (2.1.12) - OpenSSL-Universal (1.1.1100) @@ -1335,8 +1333,8 @@ SPEC CHECKSUMS: fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2 hermes-engine: 34df9d5034e90bd9bf1505e1ca198760373935af - klaviyo-react-native-sdk: ab1e9cd0d87782ebbd45235ed71bed06c0c85ee7 - KlaviyoSwift: 772fd78ef4b1f5d22c192b19e3ac2fd58ad49c90 + klaviyo-react-native-sdk: 7222f2b84ec269dd50bc734f998020b33a32091d + KlaviyoSwift: b3454b6c177b67b72b0afa1b77f6bf6281e9c754 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c RCT-Folly: 7169b2b1c44399c76a47b5deaaba715eeeb476c0 diff --git a/klaviyo-react-native-sdk.podspec b/klaviyo-react-native-sdk.podspec index fce630e..d26efc0 100644 --- a/klaviyo-react-native-sdk.podspec +++ b/klaviyo-react-native-sdk.podspec @@ -1,10 +1,9 @@ require "json" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) -folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' Pod::Spec.new do |s| - s.name = "klaviyo-react-native-sdk" + s.name = package["name"] s.version = package["version"] s.summary = package["description"] s.homepage = package["homepage"] @@ -13,30 +12,10 @@ Pod::Spec.new do |s| s.platforms = { :ios => "13.0" } s.source = { :git => "https://github.com/klaviyo/klaviyo-react-native-sdk.git", :tag => "#{s.version}" } - s.source_files = "ios/**/*.{h,m,mm,swift}" - # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0. - # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79. - if respond_to?(:install_modules_dependencies, true) - install_modules_dependencies(s) - else - s.dependency "React-Core" + s.pod_target_xcconfig = { "DEFINES_MODULE" => "YES" } - # Don't install the dependencies when we run `pod install` in the old architecture. - if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then - s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" - s.pod_target_xcconfig = { - "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"", - "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1", - "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" - } - s.dependency "React-Codegen" - s.dependency "RCT-Folly" - s.dependency "RCTRequired" - s.dependency "RCTTypeSafety" - s.dependency "ReactCommon/turbomodule/core" - end - end - s.dependency "KlaviyoSwift", "3.0.0" + s.dependency "React-Core" + s.dependency "KlaviyoSwift", "3.0.2" end