Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

Commit dbfc267

Browse files
oscbAlan Charles
and
Alan Charles
authored
feat: add deeplink referral application data (segmentio#454)
Co-authored-by: Alan Charles <[email protected]>
1 parent 5f0529f commit dbfc267

File tree

26 files changed

+2279
-2822
lines changed

26 files changed

+2279
-2822
lines changed

README.md

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,40 @@ NOTE: This project is currently in development and is covered by Segment's [Firs
88

99
## Table of Contents
1010

11-
- [Installation](#installation)
12-
- [Permissions](#permissions)
13-
- [Expo](#expo-installation)
14-
- [Migration](#migrating)
15-
- [Usage](#usage)
16-
- [Setting up the client](#setting-up-the-client)
17-
- [Client options](#client-options)
18-
- [Usage with hooks](#usage-with-hooks)
19-
- [useAnalytics](#useanalytics)
20-
- [Usage without hooks](#usage-without-hooks)
21-
- [Client methods](#client-methods)
22-
- [Track](#track)
23-
- [Screen](#screen)
24-
- [Identify](#identify)
25-
- [Group](#group)
26-
- [Alias](#alias)
27-
- [Reset](#reset)
28-
- [Flush](#flush)
29-
- [Advanced Cleanup](#advanced-cleanup)
30-
- [Automatic screen tracking](#automatic-screen-tracking)
31-
- [React Navigation](#react-navigation)
32-
- [React Native Navigation](#react-native-navigation)
33-
- [Plugin Architecture](#plugin-types)
34-
- [Contributing](#contributing)
35-
- [Code of Conduct](#code-of-conduct)
36-
- [License](#license)
11+
- [@segment/analytics-react-native ![circleci](#segmentanalytics-react-native-circlecicircleci-url)
12+
- [Table of Contents](#table-of-contents)
13+
- [Installation](#installation)
14+
- [Expo Installation](#expo-installation)
15+
- [Permissions](#permissions)
16+
- [Migrating](#migrating)
17+
- [Usage](#usage)
18+
- [Setting up the client](#setting-up-the-client)
19+
- [Client Options](#client-options)
20+
- [iOS Deep Link Tracking Setup](#ios-deep-link-tracking-setup)
21+
- [Usage with hooks](#usage-with-hooks)
22+
- [useAnalytics()](#useanalytics)
23+
- [Usage without hooks](#usage-without-hooks)
24+
- [Client methods](#client-methods)
25+
- [Track](#track)
26+
- [Screen](#screen)
27+
- [Identify](#identify)
28+
- [Group](#group)
29+
- [Alias](#alias)
30+
- [Reset](#reset)
31+
- [Flush](#flush)
32+
- [(Advanced) Cleanup](#advanced-cleanup)
33+
- [Automatic screen tracking](#automatic-screen-tracking)
34+
- [React Navigation](#react-navigation)
35+
- [React Native Navigation](#react-native-navigation)
36+
- [Plugins + Timeline architecture](#plugins--timeline-architecture)
37+
- [Plugin Types](#plugin-types)
38+
- [Destination Plugins](#destination-plugins)
39+
- [Adding Plugins](#adding-plugins)
40+
- [Writing your own Plugins](#writing-your-own-plugins)
41+
- [Example Plugins](#example-plugins)
42+
- [Contributing](#contributing)
43+
- [Code of Conduct](#code-of-conduct)
44+
- [License](#license)
3745

3846
## Installation
3947

@@ -109,12 +117,26 @@ You must pass at least the `writeKey`. Additional configuration options are list
109117
| `maxBatchSize` | 1000 | How many events to send to the API at once |
110118
| `maxEventsToRetry` | 1000 | How many events to keep around for to retry sending if the initial request failed |
111119
| `trackAppLifecycleEvents` | false | Enable automatic tracking for [app lifecycle events](https://segment.com/docs/connections/spec/mobile/#lifecycle-events): application installed, opened, updated, backgrounded) |
112-
| `trackDeepLinks` | false | Enable automatic tracking for when the user opens the app via a deep link |
120+
| `trackDeepLinks` | false | Enable automatic tracking for when the user opens the app via a deep link (Note: Requires additional setup on iOS, [see instructions](#ios-deep-link-tracking-setup)) |
113121
| `defaultSettings` | undefined | Settings that will be used if the request to get the settings from Segment fails |
114122
| `autoAddSegmentDestination`| true | Set to false to skip adding the SegmentDestination plugin |
115123

116124
\* The default value of `debug` will be false in production.
117125

126+
### iOS Deep Link Tracking Setup
127+
*Note: This is only required for iOS if you are using the `trackDeepLinks` option. Android does not require any additional setup*
128+
129+
To track deep links in iOS you must add the following to your `AppDelegate.m` file:
130+
131+
```objc
132+
- (BOOL)application:(UIApplication *)application
133+
openURL: (NSURL *)url
134+
options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
135+
136+
[AnalyticsReactNative trackDeepLink:url withOptions:options];
137+
return YES;
138+
}
139+
```
118140
### Usage with hooks
119141

120142
In order to use the `useAnalytics` hook within the application, we will additionally need to wrap the application in

example/android/.project

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<projectDescription>
3-
<name>android</name>
3+
<name>AnalyticsReactNativeExample</name>
44
<comment>Project android created by Buildship.</comment>
55
<projects>
66
</projects>
@@ -14,4 +14,15 @@
1414
<natures>
1515
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
1616
</natures>
17+
<filteredResources>
18+
<filter>
19+
<id>1644522731203</id>
20+
<name></name>
21+
<type>30</type>
22+
<matcher>
23+
<id>org.eclipse.core.resources.regexFilterMatcher</id>
24+
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
25+
</matcher>
26+
</filter>
27+
</filteredResources>
1728
</projectDescription>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,13 @@
1+
arguments=
2+
auto.sync=false
3+
build.scans.enabled=false
4+
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
15
connection.project.dir=
26
eclipse.preferences.version=1
7+
gradle.user.home=
8+
java.home=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
9+
jvm.arguments=
10+
offline.mode=false
11+
override.workspace.settings=true
12+
show.console.view=true
13+
show.executions.view=true

example/android/app/src/main/AndroidManifest.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@
2525
<category android:name="android.intent.category.BROWSABLE" />
2626
<data android:scheme="segmentreactnative" android:host="hello" />
2727
</intent-filter>
28+
<intent-filter>
29+
<action android:name="android.intent.action.VIEW" />
30+
<category android:name="android.intent.category.DEFAULT" />
31+
<category android:name="android.intent.category.BROWSABLE" />
32+
<data
33+
android:scheme="https"
34+
android:host="segmentreactnative.com"
35+
android:pathPrefix="/deepLink"
36+
/>
37+
</intent-filter>
2838
</activity>
2939
<activity
3040
android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"

example/android/app/src/main/java/com/example/segmentanalyticsreactnative/MainActivity.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
11
package com.example.segmentanalyticsreactnative;
22

3+
import android.app.Activity;
4+
import android.content.Intent;
5+
import android.net.Uri;
36
import android.os.Bundle;
7+
import android.util.Log;
8+
import android.os.Build;
49

510
import com.facebook.react.ReactActivity;
11+
import com.facebook.react.ReactInstanceManager;
12+
import com.facebook.react.bridge.ReactApplicationContext;
13+
import com.facebook.react.bridge.ReactContext;
14+
import com.segmentanalyticsreactnative.AnalyticsReactNativeModule;
15+
import com.sovranreactnative.SovranModule;
616
import com.zoontek.rnbootsplash.RNBootSplash;
717

18+
import java.util.Hashtable;
19+
820
public class MainActivity extends ReactActivity {
921

1022
/**
11-
* Returns the name of the main component registered from JavaScript. This is used to schedule
23+
* Returns the name of the main component registered from JavaScript. This is
24+
* used to schedule
1225
* rendering of the component.
1326
*/
1427
@Override
@@ -21,4 +34,9 @@ protected void onCreate(Bundle savedInstanceState) {
2134
super.onCreate(savedInstanceState);
2235
RNBootSplash.init(R.drawable.bootsplash, MainActivity.this);
2336
}
37+
38+
@Override
39+
protected void onResume() {
40+
super.onResume();
41+
}
2442
}

example/android/app/src/main/java/com/example/segmentanalyticsreactnative/MainApplication.java

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,32 @@
1010
import com.facebook.soloader.SoLoader;
1111
import java.lang.reflect.InvocationTargetException;
1212
import java.util.List;
13-
1413
import com.segmentanalyticsreactnative.AnalyticsReactNativePackage;
1514

1615
public class MainApplication extends Application implements ReactApplication {
1716

18-
private final ReactNativeHost mReactNativeHost =
19-
new ReactNativeHost(this) {
20-
@Override
21-
public boolean getUseDeveloperSupport() {
22-
return BuildConfig.DEBUG;
23-
}
24-
25-
@Override
26-
protected List<ReactPackage> getPackages() {
27-
@SuppressWarnings("UnnecessaryLocalVariable")
28-
List<ReactPackage> packages = new PackageList(this).getPackages();
29-
// Packages that cannot be autolinked yet can be added manually here, for AnalyticsReactNativeExample:
30-
// packages.add(new MyReactNativePackage());
31-
packages.add(new AnalyticsReactNativePackage());
17+
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
18+
@Override
19+
public boolean getUseDeveloperSupport() {
20+
return BuildConfig.DEBUG;
21+
}
3222

33-
return packages;
34-
}
23+
@Override
24+
protected List<ReactPackage> getPackages() {
25+
@SuppressWarnings("UnnecessaryLocalVariable")
26+
List<ReactPackage> packages = new PackageList(this).getPackages();
27+
// Packages that cannot be autolinked yet can be added manually here, for
28+
// AnalyticsReactNativeExample:
29+
// packages.add(new MyReactNativePackage());
30+
packages.add(new AnalyticsReactNativePackage());
31+
return packages;
32+
}
3533

36-
@Override
37-
protected String getJSMainModuleName() {
38-
return "index";
39-
}
40-
};
34+
@Override
35+
protected String getJSMainModuleName() {
36+
return "index";
37+
}
38+
};
4139

4240
@Override
4341
public ReactNativeHost getReactNativeHost() {
@@ -48,7 +46,9 @@ public ReactNativeHost getReactNativeHost() {
4846
public void onCreate() {
4947
super.onCreate();
5048
SoLoader.init(this, /* native exopackage */ false);
51-
initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); // Remove this line if you don't want Flipper enabled
49+
initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); //// Remove this line if you don't want
50+
//// Flipper enabled
51+
5252
}
5353

5454
/**
@@ -60,9 +60,9 @@ private static void initializeFlipper(Context context, ReactInstanceManager reac
6060
if (BuildConfig.DEBUG) {
6161
try {
6262
/*
63-
We use reflection here to pick up the class that initializes Flipper,
64-
since Flipper library is not available in release mode
65-
*/
63+
* We use reflection here to pick up the class that initializes Flipper,
64+
* since Flipper library is not available in release mode
65+
*/
6666
Class<?> aClass = Class.forName("com.segmentanalyticsreactnativeExample.ReactNativeFlipper");
6767
aClass
6868
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)

example/ios/AnalyticsReactNativeExample.xcodeproj/project.pbxproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
20F357AE24636CDF00C146DC /* AnalyticsReactNativeExample-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AnalyticsReactNativeExample-Bridging-Header.h"; sourceTree = "<group>"; };
3131
20F357AF24636CDF00C146DC /* File.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = File.swift; sourceTree = "<group>"; };
3232
4D7192F03A36A017E887435B /* Pods-AnalyticsReactNativeExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AnalyticsReactNativeExample.release.xcconfig"; path = "Target Support Files/Pods-AnalyticsReactNativeExample/Pods-AnalyticsReactNativeExample.release.xcconfig"; sourceTree = "<group>"; };
33+
82A9DBCD27ADC2ED00E38216 /* AnalyticsReactNativeExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = AnalyticsReactNativeExample.entitlements; path = AnalyticsReactNativeExample/AnalyticsReactNativeExample.entitlements; sourceTree = "<group>"; };
3334
871719007ECC5EAD276C345C /* Pods-AnalyticsReactNativeExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AnalyticsReactNativeExample.debug.xcconfig"; path = "Target Support Files/Pods-AnalyticsReactNativeExample/Pods-AnalyticsReactNativeExample.debug.xcconfig"; sourceTree = "<group>"; };
3435
BCEA90A70F4BEAD7E9FA28B2 /* libPods-AnalyticsReactNativeExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AnalyticsReactNativeExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
3536
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
@@ -50,6 +51,7 @@
5051
13B07FAE1A68108700A75B9A /* AnalyticsReactNativeExample */ = {
5152
isa = PBXGroup;
5253
children = (
54+
82A9DBCD27ADC2ED00E38216 /* AnalyticsReactNativeExample.entitlements */,
5355
02771A7425486F20008AD4BC /* GoogleService-Info.plist */,
5456
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
5557
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
@@ -195,7 +197,7 @@
195197
);
196198
runOnlyForDeploymentPostprocessing = 0;
197199
shellPath = /bin/sh;
198-
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
200+
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
199201
};
200202
7A2FB6969CDA2F7083356BAB /* [CP] Copy Pods Resources */ = {
201203
isa = PBXShellScriptBuildPhase;
@@ -278,6 +280,7 @@
278280
buildSettings = {
279281
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
280282
CLANG_ENABLE_MODULES = YES;
283+
CODE_SIGN_ENTITLEMENTS = AnalyticsReactNativeExample/AnalyticsReactNativeExample.entitlements;
281284
CURRENT_PROJECT_VERSION = 1;
282285
DEAD_CODE_STRIPPING = NO;
283286
ENABLE_BITCODE = NO;
@@ -309,6 +312,7 @@
309312
buildSettings = {
310313
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
311314
CLANG_ENABLE_MODULES = YES;
315+
CODE_SIGN_ENTITLEMENTS = AnalyticsReactNativeExample/AnalyticsReactNativeExample.entitlements;
312316
CURRENT_PROJECT_VERSION = 1;
313317
ENABLE_BITCODE = NO;
314318
"EXCLUDED_ARCHS[sdk=*]" = arm64;

example/ios/AnalyticsReactNativeExample.xcodeproj/xcshareddata/xcschemes/AnalyticsReactNativeExample.xcscheme

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
ReferencedContainer = "container:AnalyticsReactNativeExample.xcodeproj">
5151
</BuildableReference>
5252
</MacroExpansion>
53+
<Testables>
54+
</Testables>
5355
</TestAction>
5456
<LaunchAction
5557
buildConfiguration = "Debug"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.developer.associated-domains</key>
6+
<array/>
7+
</dict>
8+
</plist>

example/ios/AnalyticsReactNativeExample/AppDelegate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#import <React/RCTBridgeDelegate.h>
99
#import <UIKit/UIKit.h>
1010
#import <React/RCTBridgeModule.h>
11+
@import segment_analytics_react_native;
1112

1213
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
1314

example/ios/AnalyticsReactNativeExample/AppDelegate.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#import <React/RCTRootView.h>
1313
#import "RNBootSplash.h"
1414
@import AdSupport;
15+
@import React;
16+
@import segment_analytics_react_native;
1517

1618
@implementation AppDelegate
1719

@@ -30,7 +32,14 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
3032
self.window.rootViewController = rootViewController;
3133
[self.window makeKeyAndVisible];
3234
[RNBootSplash initWithStoryboard:@"LaunchScreen" rootView:rootView];
35+
return YES;
36+
}
37+
38+
- (BOOL)application:(UIApplication *)application
39+
openURL: (NSURL *)url
40+
options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
3341

42+
[AnalyticsReactNative trackDeepLink:url withOptions:options];
3443
return YES;
3544
}
3645

example/ios/Podfile.lock

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ PODS:
288288
- React-Core
289289
- segment-analytics-react-native (2.1.6-beta):
290290
- React-Core
291+
- sovran-react-native
291292
- segment-analytics-react-native-plugin-idfa (0.2.0-beta):
292293
- React-Core
293294
- sovran-react-native (0.2.4):
@@ -458,7 +459,7 @@ SPEC CHECKSUMS:
458459
RNCAsyncStorage: b49b4e38a1548d03b74b30e558a1d18465b94be7
459460
RNCMaskedView: 0e1bc4bfa8365eba5fbbb71e07fbdc0555249489
460461
RNGestureHandler: bf572f552ea324acd5b5464b8d30755b2d8c1de6
461-
segment-analytics-react-native: 2efa452e7ce2b8b59cf2dd9335e208c963ebbbbe
462+
segment-analytics-react-native: 1651b31be11bee997e39ff7ababd296f00f7492a
462463
segment-analytics-react-native-plugin-idfa: 2dc6e38506a5b034db4a4cf16db48643b2f356a2
463464
sovran-react-native: 1b68d70aaa2d96489e0338eaf3a4cbf92688c793
464465
Yoga: 3f5bfc54ce164fcd5b5d7f9f4232182d6298dd56

0 commit comments

Comments
 (0)