Skip to content

Commit a8cf4db

Browse files
belleklaviyoevan-masseau
authored andcommitted
Bridge geofencing methods (#277)
* Modify permissions library * Add bridging to test mock API call * Removed unused react-native-permissions library * Oh we don't need react-native-geolocation-service either * Rename registerForGeofences to registerGeofencing * Bridge unregister method * Add permission prompting through react-native-permissions, add to example app * Support location services in terminated state * Only bridge background monitor method to objc, not RN * Point to swift SDK feat/geofencing * Remove duplicate setup_permissions * Bridged android methods (#283) Co-authored-by: Evan Masseau <> * dispatch to main thread, update pods * Remove permissions from Android manifest * Add dispatch to main * Remove redundant script loading * Unversion dependencies * Point to updated feat/geofencing swift branch * fix path for CI * Use Task in KlaviyoBridge async calls * Bridge getCurrentGeofences * Point pods to feat/geofencing * Fix async calls * Fix getCurrentGeofences in KlaviyoBridge * Added android "getCurrentGeofences" bridge function, tagged it internal also added tests --------- Co-authored-by: Evan C Masseau <[email protected]> Co-authored-by: Evan Masseau <>
1 parent 3101d78 commit a8cf4db

File tree

20 files changed

+1404
-789
lines changed

20 files changed

+1404
-789
lines changed

android/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ dependencies {
121121
api "com.github.klaviyo.klaviyo-android-sdk:analytics:$klaviyoAndroidSdkVersion"
122122
api "com.github.klaviyo.klaviyo-android-sdk:push-fcm:$klaviyoAndroidSdkVersion"
123123
api "com.github.klaviyo.klaviyo-android-sdk:forms:$klaviyoAndroidSdkVersion"
124+
api "com.github.klaviyo.klaviyo-android-sdk:location:$klaviyoAndroidSdkVersion"
124125
implementation "com.github.klaviyo.klaviyo-android-sdk:core:$klaviyoAndroidSdkVersion"
125126

126127
// We used reflection to enumerate keywords in the Klaviyo Android SDK dynamically

android/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryErro
1111
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
1212
# org.gradle.parallel=true
1313
#Tue Dec 19 15:08:27 EST 2023
14-
KlaviyoReactNativeSdk_klaviyoAndroidSdkVersion=4.1.0
14+
KlaviyoReactNativeSdk_klaviyoAndroidSdkVersion=68d7123
1515
KlaviyoReactNativeSdk_kotlinVersion=1.8.0
1616
KlaviyoReactNativeSdk_minSdkVersion=23
1717
KlaviyoReactNativeSdk_targetSdkVersion=36

android/src/main/java/com/klaviyoreactnativesdk/KlaviyoReactNativeSdkModule.kt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.klaviyoreactnativesdk
22

3+
import com.facebook.react.bridge.Arguments
34
import com.facebook.react.bridge.Callback
45
import com.facebook.react.bridge.ReactApplicationContext
56
import com.facebook.react.bridge.ReactContextBaseJavaModule
@@ -20,6 +21,9 @@ import com.klaviyo.core.utils.AdvancedAPI
2021
import com.klaviyo.forms.InAppFormsConfig
2122
import com.klaviyo.forms.registerForInAppForms
2223
import com.klaviyo.forms.unregisterFromInAppForms
24+
import com.klaviyo.location.LocationManager
25+
import com.klaviyo.location.registerGeofencing
26+
import com.klaviyo.location.unregisterGeofencing
2327
import java.io.Serializable
2428
import kotlin.reflect.KVisibility
2529
import kotlin.time.Duration.Companion.seconds
@@ -87,6 +91,41 @@ class KlaviyoReactNativeSdkModule(
8791
}
8892
}
8993

94+
@ReactMethod
95+
fun registerGeofencing() {
96+
Klaviyo.registerGeofencing()
97+
}
98+
99+
@ReactMethod
100+
fun unregisterGeofencing() {
101+
Klaviyo.unregisterGeofencing()
102+
}
103+
104+
@ReactMethod
105+
fun getCurrentGeofences(callback: Callback) {
106+
// Note: in the future, we may be storing more fences than we are observing, so we'd have to update this
107+
val geofencesArray = Arguments.createArray()
108+
Registry.getOrNull<LocationManager>()?.getStoredGeofences()?.forEach { geofence ->
109+
geofencesArray.pushMap(
110+
Arguments.createMap().apply {
111+
putString("identifier", geofence.id)
112+
putDouble("latitude", geofence.latitude)
113+
putDouble("longitude", geofence.longitude)
114+
putDouble("radius", geofence.radius.toDouble())
115+
},
116+
)
117+
} ?: run {
118+
Registry.log.wtf("Geofencing is not yet registered")
119+
}
120+
121+
val resultMap =
122+
Arguments.createMap().apply {
123+
putArray("geofences", geofencesArray)
124+
}
125+
126+
callback.invoke(resultMap)
127+
}
128+
90129
@ReactMethod
91130
fun setProfile(profile: ReadableMap) {
92131
val parsedProfile = Profile()

configure-sdk.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ function configure_pods() {
300300
sed -i '' "/pod 'KlaviyoCore'/d" "$podfile"
301301
sed -i '' "/pod 'KlaviyoSwift'/d" "$podfile"
302302
sed -i '' "/pod 'KlaviyoForms'/d" "$podfile"
303+
sed -i '' "/pod 'KlaviyoLocation'/d" "$podfile"
303304

304305
# Restore podspec
305306
sed -i '' 's/\(s\.dependency "KlaviyoSwift"\) ##, "\([^"]*\)"/\1, "\2"/' "$podspec"
@@ -316,7 +317,7 @@ function configure_pods() {
316317
echo "Commented out version constraints in $podspec for local development"
317318

318319
# List of dependencies
319-
dependencies=("KlaviyoCore" "KlaviyoSwift" "KlaviyoForms")
320+
dependencies=("KlaviyoCore" "KlaviyoSwift" "KlaviyoForms" "KlaviyoLocation")
320321

321322
# Find the line number of the target block
322323
target_line=$(grep -n "# Insert override klaviyo-swift-sdk pods below this line when needed" "$podfile" | cut -d: -f1)

example/ios/KlaviyoReactNativeSdkExample/AppDelegate.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
#import <UIKit/UIKit.h>
33
#import <UserNotifications/UserNotifications.h>
44
#import "KlaviyoReactNativeSdkExample-Swift.h"
5+
#if __has_include(<klaviyo_react_native_sdk/klaviyo_react_native_sdk-Swift.h>)
6+
#import <klaviyo_react_native_sdk/klaviyo_react_native_sdk-Swift.h>
7+
#else
8+
#import "klaviyo_react_native_sdk-Swift.h"
9+
#endif
510

611
// iOS Installation Step 1: Conform AppDelegate to UNUserNotificationCenterDelegate
712
@interface AppDelegate: RCTAppDelegate <UNUserNotificationCenterDelegate>

example/ios/KlaviyoReactNativeSdkExample/AppDelegate.mm

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ - (BOOL)application:(UIApplication *)application
2424
// iOS Installation Step 3: Initialize the SDK with public key, if
2525
// initializing from native code Exclude if initializing from react native
2626
// layer
27-
[PushNotificationsHelper initializeSDK:@"Xr5bFG"];
27+
[PushNotificationsHelper initializeSDK:@"YOUR_KLAVIYO_PUBLIC_API_KEY"];
2828

2929
// iOS Installation Step 4: Request notification permission from the user
3030
// Exclude if handling permissions from react native layer
@@ -33,6 +33,11 @@ - (BOOL)application:(UIApplication *)application
3333
// Initialize cross-platform push library, e.g. Firebase
3434
}
3535

36+
// Start monitoring geofences from background
37+
dispatch_async(dispatch_get_main_queue(), ^{
38+
[KlaviyoBridge monitorGeofencesFromBackground];
39+
});
40+
3641
// refer to installation step 16 below
3742
NSMutableDictionary *launchOptionsWithURL =
3843
[self getLaunchOptionsWithURL:launchOptions];

example/ios/KlaviyoReactNativeSdkExample/Info.plist

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,19 @@
4848
<key>NSAllowsLocalNetworking</key>
4949
<true/>
5050
</dict>
51+
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
52+
<string>We need access to your location at all times to provide geofencing features, including when the app is in the background.</string>
53+
<key>NSLocationAlwaysUsageDescription</key>
54+
<string>We need access to your location at all times to provide geofencing features, including when the app is in the background.</string>
5155
<key>NSLocationWhenInUseUsageDescription</key>
52-
<string></string>
56+
<string>We use your location to provide location-based features and geofencing.</string>
5357
<key>RCTNewArchEnabled</key>
5458
<true/>
59+
<key>UIBackgroundModes</key>
60+
<array>
61+
<string>location</string>
62+
<string>fetch</string>
63+
</array>
5564
<key>UILaunchStoryboardName</key>
5665
<string>LaunchScreen</string>
5766
<key>UIRequiredDeviceCapabilities</key>

example/ios/Podfile

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
# Resolve react_native_pods.rb with node to allow for hoisting
2-
require Pod::Executable.execute_command('node', ['-p',
3-
'require.resolve(
4-
"react-native/scripts/react_native_pods.rb",
5-
{paths: [process.argv[1]]},
6-
)', __dir__]).strip
1+
def node_require(script)
2+
require Pod::Executable.execute_command('node', ['-p',
3+
"require.resolve(
4+
'#{script}',
5+
{paths: [process.argv[1]]},
6+
)", __dir__]).strip
7+
end
8+
9+
node_require('react-native/scripts/react_native_pods.rb')
10+
node_require('react-native-permissions/scripts/setup.rb')
711

812
platform :ios, min_ios_version_supported
913
prepare_react_native_project!
1014

11-
1215
linkage = ENV['USE_FRAMEWORKS']
1316
if linkage != nil
1417
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
@@ -21,6 +24,17 @@ target 'KlaviyoReactNativeSdkExample' do
2124
use_frameworks! :linkage => :static
2225

2326
# Insert override klaviyo-swift-sdk pods below this line when needed
27+
# Using remote branch feat/geofencing from GitHub
28+
pod 'KlaviyoCore', :git => 'https://github.com/klaviyo/klaviyo-swift-sdk.git', :branch => 'feat/geofencing'
29+
pod 'KlaviyoSwift', :git => 'https://github.com/klaviyo/klaviyo-swift-sdk.git', :branch => 'feat/geofencing'
30+
pod 'KlaviyoForms', :git => 'https://github.com/klaviyo/klaviyo-swift-sdk.git', :branch => 'feat/geofencing'
31+
pod 'KlaviyoLocation', :git => 'https://github.com/klaviyo/klaviyo-swift-sdk.git', :branch => 'feat/geofencing'
32+
33+
# Setup permissions for react-native-permissions
34+
setup_permissions([
35+
'LocationWhenInUse',
36+
'LocationAlways',
37+
])
2438

2539
use_react_native!(
2640
:path => config[:reactNativePath],

0 commit comments

Comments
 (0)