Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,14 @@ package com.segment.analytics.reactnative.core

import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.net.Uri
import com.facebook.react.bridge.*
import com.segment.analytics.Analytics
import com.segment.analytics.Properties
import com.segment.analytics.Options
import com.segment.analytics.Traits
import com.segment.analytics.ValueMap
import com.segment.analytics.internal.Utils.getSegmentSharedPreferences
import java.util.concurrent.TimeUnit
import com.facebook.react.bridge.ReadableMap
import com.segment.analytics.*
import java.io.IOException
import java.net.HttpURLConnection



Expand Down Expand Up @@ -155,6 +154,37 @@ class RNAnalyticsModule(context: ReactApplicationContext): ReactContextBaseJavaM
builder.trackApplicationLifecycleEvents()
}

if(options.hasKey("proxy") && options.getType("proxy") == ReadableType.Map) {
val proxyOptions = options.getMap("proxy")!!

builder.connectionFactory(object:ConnectionFactory() {
override fun openConnection(url:String): HttpURLConnection {
val uri = Uri.parse(url)
val uriBuilder = uri.buildUpon();

if (proxyOptions.hasKey("scheme")) {
uriBuilder.scheme(proxyOptions.getString("scheme"))
}

if (proxyOptions.hasKey("host")) {
var host = proxyOptions.getString("host");

if (proxyOptions.hasKey("port")) {
host = host + ":" + proxyOptions.getInt("port");
}

uriBuilder.encodedAuthority(host)
}

if (proxyOptions.hasKey("path")) {
uriBuilder.path(proxyOptions.getString("path") + uri.path)
}

return super.openConnection(uriBuilder.toString())
}
})
}

try {
Analytics.setSingletonInstance(
RNAnalytics.buildWithIntegrations(builder)
Expand Down
2 changes: 1 addition & 1 deletion packages/core/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

**Ƭ Integration**: *`function` \| `object`*

*Defined in [analytics.ts:8](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L8)*
*Defined in [analytics.ts:8](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L8)*

___

30 changes: 15 additions & 15 deletions packages/core/docs/classes/analytics.client.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

**● ready**: *`false`* = false

*Defined in [analytics.ts:104](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L104)*
*Defined in [analytics.ts:147](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L147)*

Whether the client is ready to send events to Segment.

Expand All @@ -55,7 +55,7 @@ ___

▸ **alias**(newId: *`string`*, options?: *[Options]()*): `Promise`<`void`>

*Defined in [analytics.ts:274](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L274)*
*Defined in [analytics.ts:317](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L317)*

Merge two user identities, effectively connecting two sets of user data as one. This may not be supported by all integrations.

Expand All @@ -77,7 +77,7 @@ ___

▸ **catch**(handler: *[ErrorHandler]()*): `this`

*Defined in [analytics.ts:119](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L119)*
*Defined in [analytics.ts:162](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L162)*

Catch React-Native bridge errors

Expand All @@ -98,7 +98,7 @@ ___

▸ **disable**(): `Promise`<`void`>

*Defined in [analytics.ts:313](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L313)*
*Defined in [analytics.ts:356](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L356)*

Completely disable the sending of any analytics data.

Expand All @@ -113,7 +113,7 @@ ___

▸ **enable**(): `Promise`<`void`>

*Defined in [analytics.ts:303](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L303)*
*Defined in [analytics.ts:346](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L346)*

Enable the sending of analytics data. Enabled by default.

Expand All @@ -128,7 +128,7 @@ ___

▸ **flush**(): `Promise`<`void`>

*Defined in [analytics.ts:294](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L294)*
*Defined in [analytics.ts:337](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L337)*

Trigger an upload of all queued events.

Expand All @@ -143,7 +143,7 @@ ___

▸ **getAnonymousId**(): `Promise`<`string`>

*Defined in [analytics.ts:318](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L318)*
*Defined in [analytics.ts:361](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L361)*

Retrieve the anonymousId.

Expand All @@ -156,7 +156,7 @@ ___

▸ **group**(groupId: *`string`*, traits?: *[JsonMap]()*, options?: *[Options]()*): `Promise`<`void`>

*Defined in [analytics.ts:261](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L261)*
*Defined in [analytics.ts:304](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L304)*

Associate a user with a group, organization, company, project, or w/e _you_ call them.

Expand All @@ -179,7 +179,7 @@ ___

▸ **identify**(user: *`string`*, traits?: *[JsonMap]()*, options?: *[Options]()*): `Promise`<`void`>

*Defined in [analytics.ts:248](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L248)*
*Defined in [analytics.ts:291](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L291)*

Associate a user with their unique ID and record traits about them.

Expand All @@ -202,7 +202,7 @@ ___

▸ **middleware**(middleware: *[Middleware]()*): `this`

*Defined in [analytics.ts:157](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L157)*
*Defined in [analytics.ts:200](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L200)*

Append a new middleware to the middleware chain.

Expand Down Expand Up @@ -240,7 +240,7 @@ ___

▸ **reset**(): `Promise`<`void`>

*Defined in [analytics.ts:284](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L284)*
*Defined in [analytics.ts:327](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L327)*

Reset any user state that is cached on the device.

Expand All @@ -255,7 +255,7 @@ ___

▸ **screen**(name: *`string`*, properties?: *[JsonMap]()*, options?: *[Options]()*): `Promise`<`void`>

*Defined in [analytics.ts:233](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L233)*
*Defined in [analytics.ts:276](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L276)*

Record the screens or views your users see.

Expand All @@ -278,7 +278,7 @@ ___

▸ **setup**(writeKey: *`string`*, configuration?: *[Configuration](../interfaces/analytics.configuration.md)*): `Promise`<`void`>

*Defined in [analytics.ts:196](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L196)*
*Defined in [analytics.ts:239](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L239)*

Setup the Analytics module. All calls made before are queued and only executed if the configuration was successful.

Expand Down Expand Up @@ -308,7 +308,7 @@ ___

▸ **track**(event: *`string`*, properties?: *[JsonMap]()*, options?: *[Options]()*): `Promise`<`void`>

*Defined in [analytics.ts:215](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L215)*
*Defined in [analytics.ts:258](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L258)*

Record the actions your users perform.

Expand All @@ -331,7 +331,7 @@ ___

▸ **useNativeConfiguration**(): `this`

*Defined in [analytics.ts:169](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L169)*
*Defined in [analytics.ts:212](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L212)*

Use the native configuration.

Expand Down
32 changes: 23 additions & 9 deletions packages/core/docs/interfaces/analytics.configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* [defaultProjectSettings](analytics.configuration.md#defaultprojectsettings)
* [flushAt](analytics.configuration.md#flushat)
* [ios](analytics.configuration.md#ios)
* [proxy](analytics.configuration.md#proxy)
* [recordScreenViews](analytics.configuration.md#recordscreenviews)
* [trackAppLifecycleEvents](analytics.configuration.md#trackapplifecycleevents)
* [trackAttributionData](analytics.configuration.md#trackattributiondata)
Expand All @@ -30,7 +31,7 @@

**● android**: *`undefined` \| `object`*

*Defined in [analytics.ts:77](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L77)*
*Defined in [analytics.ts:120](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L120)*

Android specific settings.

Expand All @@ -41,7 +42,7 @@ ___

**● debug**: *`undefined` \| `false` \| `true`*

*Defined in [analytics.ts:38](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L38)*
*Defined in [analytics.ts:38](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L38)*

___
<a id="defaultprojectsettings"></a>
Expand All @@ -50,7 +51,7 @@ ___

**● defaultProjectSettings**: *`undefined` \| `object`*

*Defined in [analytics.ts:46](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L46)*
*Defined in [analytics.ts:46](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L46)*

Default project settings to use, if Segment.com cannot be reached. An example configuration can be found here, using your write key: [](https://cdn-settings.segment.com/v1/projects/YOUR_WRITE_KEY/settings)[https://cdn-settings.segment.com/v1/projects/YOUR\_WRITE\_KEY/settings](https://cdn-settings.segment.com/v1/projects/YOUR_WRITE_KEY/settings)

Expand All @@ -61,7 +62,7 @@ ___

**● flushAt**: *`undefined` \| `number`*

*Defined in [analytics.ts:54](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L54)*
*Defined in [analytics.ts:54](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L54)*

The number of queued events that the analytics client should flush at. Setting this to `1` will not queue any events and will use more battery.

Expand All @@ -74,18 +75,31 @@ ___

**● ios**: *`undefined` \| `object`*

*Defined in [analytics.ts:59](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L59)*
*Defined in [analytics.ts:102](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L102)*

iOS specific settings.

___
<a id="proxy"></a>

### `<Optional>` proxy

**● proxy**: *`undefined` \| `object`*

*Defined in [analytics.ts:72](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L72)*

Whether the analytics client should send all requests through your own hosted proxy rather than directly to Segment. See: iOS: [https://segment.com/docs/connections/sources/catalog/libraries/mobile/ios/#proxy-http-calls](https://segment.com/docs/connections/sources/catalog/libraries/mobile/ios/#proxy-http-calls) android: [https://segment.com/docs/connections/sources/catalog/libraries/mobile/android/#proxy-http-calls](https://segment.com/docs/connections/sources/catalog/libraries/mobile/android/#proxy-http-calls)

Ex. For a desired proxy through `http://localhost:64000/segment` the configuration would look like such { scheme: 'http', host: 'localhost', port: 64000, path: '/segment' }

___
<a id="recordscreenviews"></a>

### `<Optional>` recordScreenViews

**● recordScreenViews**: *`undefined` \| `false` \| `true`*

*Defined in [analytics.ts:19](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L19)*
*Defined in [analytics.ts:19](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L19)*

Whether the analytics client should automatically make a screen call when a view controller is added to a view hierarchy. Because the iOS underlying implementation uses method swizzling, we recommend initializing the analytics client as early as possible.

Expand All @@ -98,7 +112,7 @@ ___

**● trackAppLifecycleEvents**: *`undefined` \| `false` \| `true`*

*Defined in [analytics.ts:26](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L26)*
*Defined in [analytics.ts:26](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L26)*

Whether the analytics client should automatically track application lifecycle events, such as "Application Installed", "Application Updated" and "Application Opened".

Expand All @@ -111,7 +125,7 @@ ___

**● trackAttributionData**: *`undefined` \| `false` \| `true`*

*Defined in [analytics.ts:32](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L32)*
*Defined in [analytics.ts:32](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L32)*

Whether the analytics client should automatically track attribution data from enabled providers using the mobile service.

Expand All @@ -124,7 +138,7 @@ ___

**● using**: *[Integration](../#integration)[]*

*Defined in [analytics.ts:37](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L37)*
*Defined in [analytics.ts:37](https://github.com/adkenyon/analytics-react-native/blob/master/packages/core/src/analytics.ts#L37)*

Register a set of integrations to be used with this Analytics instance.

Expand Down
27 changes: 27 additions & 0 deletions packages/core/ios/RNAnalytics/RNAnalytics.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,33 @@ +(void)initialize {
config.enableAdvertisingTracking = [options[@"ios"][@"trackAdvertising"] boolValue];
config.defaultSettings = options[@"defaultProjectSettings"];

if ([options valueForKey:@"proxy"]) {
NSDictionary *proxyOptions = (NSDictionary *)[options valueForKey:@"proxy"];

config.requestFactory = ^(NSURL *url) {
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];

if ([proxyOptions valueForKey:@"scheme"]) {
components.scheme = [proxyOptions[@"scheme"] stringValue];
}

if ([proxyOptions valueForKey:@"host"]) {
components.host = [proxyOptions[@"host"] stringValue];
}

if ([proxyOptions valueForKey:@"port"]) {
components.port = [NSNumber numberWithInt:[proxyOptions[@"port"] intValue]];
}

if ([proxyOptions valueForKey:@"path"]) {
components.path = [[proxyOptions[@"path"] stringValue] stringByAppendingString:components.path];
}

NSURL *transformedURL = components.URL;
return [NSMutableURLRequest requestWithURL:transformedURL];
};
}

for(id factory in RNAnalyticsIntegrations) {
[config use:factory];
}
Expand Down
43 changes: 43 additions & 0 deletions packages/core/src/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,49 @@ export module Analytics {
*/
flushAt?: number

/**
* Whether the analytics client should send all requests through your own hosted
* proxy rather than directly to Segment.
* See:
* iOS: https://segment.com/docs/connections/sources/catalog/libraries/mobile/ios/#proxy-http-calls
* android: https://segment.com/docs/connections/sources/catalog/libraries/mobile/android/#proxy-http-calls
*
* Ex. For a desired proxy through `http://localhost:64000/segment` the configuration would look like such
* {
* scheme: 'http',
* host: 'localhost',
* port: 64000,
* path: '/segment'
* }
*
*/
proxy?: {

/**
* The proxy scheme, ex: http, https
*
* `https` by default.
*/
scheme?: string,

/**
* The proxy host name, ex: api.segment.io, cdn.segment.io
*
* Note: When using localhost with an Android device or simulator use `adb reverse tcp:<port> tcp:<port>`
*/
host?: string,

/**
* The proxy port number, ex: 80
*/
port?: number,

/**
* The proxy path, ex: /path/to/proxy
*/
path?: string,
},

/**
* iOS specific settings.
*/
Expand Down
Loading