diff --git a/.prettierignore b/.prettierignore index 6bbf0967e..0174f420a 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,3 @@ -packages/core/docs +packages/core/docs/ +build/ +node_modules/ diff --git a/README.md b/README.md index 55750940a..543f0fe4d 100644 --- a/README.md +++ b/README.md @@ -37,17 +37,21 @@ import Mixpanel from '@segment/analytics-react-native-mixpanel' import GoogleAnalytics from '@segment/analytics-react-native-google-analytics' analytics - .configure() - .using(Mixpanel, GoogleAnalytics) - .recordScreenViews() - .trackAppLifecycleEvents() - .trackAttributionData() - .ios() - .trackAdvertising() - .trackDeepLinks() - .android() - .disableDevicedId() - .setup("writeKey") + .setup('writeKey', { + using: [Mixpanel, GoogleAnalytics], + recordScreenViews: true, + trackAppLifecycleEvents: true, + trackAttributionData: true, + + android: { + flushInterval: 60, + collectDeviceId: true + }, + ios: { + trackAdvertising: true, + trackDeepLinks: true + } + }) .then(() => console.log('Analytics is ready') ) @@ -94,11 +98,9 @@ In your code : import analytics from '@segment/analytics-react-native' import GoogleAnalytics from '@segment/analytics-react-native-google-analytics' -await analytics - .configure() - .using(GoogleAnalytics) - // ... - .setup('writeKey') +await analytics.setup('writeKey', { + using: [GoogleAnalytics] +}) ``` #### Integrations diff --git a/packages/core/android/src/main/java/com/segment/analytics/reactnative/core/RNAnalyticsModule.kt b/packages/core/android/src/main/java/com/segment/analytics/reactnative/core/RNAnalyticsModule.kt index 8e5658266..8e130413e 100644 --- a/packages/core/android/src/main/java/com/segment/analytics/reactnative/core/RNAnalyticsModule.kt +++ b/packages/core/android/src/main/java/com/segment/analytics/reactnative/core/RNAnalyticsModule.kt @@ -42,9 +42,8 @@ class RNAnalyticsModule(context: ReactApplicationContext): ReactContextBaseJavaM @ReactMethod fun setup(options: ReadableMap) { - val android = options.getMap("android") val builder = Analytics - .Builder(reactApplicationContext, android.getString("writeKey")) + .Builder(reactApplicationContext, options.getString("writeKey")) .flushQueueSize(options.getInt("flushAt")) if(options.getBoolean("recordScreenViews")) { diff --git a/packages/core/docs/README.md b/packages/core/docs/README.md index 2040ed512..9be84965d 100644 --- a/packages/core/docs/README.md +++ b/packages/core/docs/README.md @@ -2,18 +2,17 @@ ## Index -### Modules - -* [ChainedConfiguration](modules/analytics.chainedconfiguration.md) - ### Classes * [Client](classes/analytics.client.md) +### Interfaces + +* [Configuration](interfaces/analytics.configuration.md) + ### Type aliases * [Integration](#integration) -* [WriteKey](#writekey) --- @@ -26,17 +25,7 @@ **Ƭ Integration**: * `function` | `object` * -*Defined in analytics.ts:229* - -___ - - -### WriteKey - -**Ƭ WriteKey**: * `string` | `object` -* - -*Defined in analytics.ts:231* +*Defined in [analytics.ts:8](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L8)* ___ diff --git a/packages/core/docs/classes/analytics.client.md b/packages/core/docs/classes/analytics.client.md index d48af2723..a07a09067 100644 --- a/packages/core/docs/classes/analytics.client.md +++ b/packages/core/docs/classes/analytics.client.md @@ -16,7 +16,6 @@ * [alias](analytics.client.md#alias) * [catch](analytics.client.md#catch) -* [configure](analytics.client.md#configure) * [disable](analytics.client.md#disable) * [enable](analytics.client.md#enable) * [flush](analytics.client.md#flush) @@ -25,6 +24,7 @@ * [middleware](analytics.client.md#middleware) * [reset](analytics.client.md#reset) * [screen](analytics.client.md#screen) +* [setup](analytics.client.md#setup) * [track](analytics.client.md#track) * [useNativeConfiguration](analytics.client.md#usenativeconfiguration) @@ -38,7 +38,7 @@ **● ready**: *`false`* = false -*Defined in analytics.ts:15* +*Defined in [analytics.ts:96](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L96)* Whether the client is ready to send events to Segment. @@ -54,7 +54,7 @@ ___ ▸ **alias**(newId: *`string`*): `Promise`<`void`> -*Defined in analytics.ts:174* +*Defined in [analytics.ts:260](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L260)* Merge two user identities, effectively connecting two sets of user data as one. This may not be supported by all integrations. @@ -75,7 +75,7 @@ ___ ▸ **catch**(handler: *[ErrorHandler]()*): `this` -*Defined in analytics.ts:28* +*Defined in [analytics.ts:109](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L109)* Catch React-Native bridge errors @@ -89,31 +89,6 @@ These errors are emitted when calling the native counterpart. **Returns:** `this` -___ - - -### configure - -▸ **configure**(): [Configuration](../interfaces/analytics.chainedconfiguration.configuration.md) - -*Defined in analytics.ts:102* - -Configure the Analytics module. - -This method returns a fluent-style API to configure the SDK : - -```js -analytics - .configure() - .using(Mixpanel, GoogleAnalytics) - .trackAppLifecycle() - .ios() - .trackDeepLinks() - .setup("YOUR_WRITE_KEY") -``` - -**Returns:** [Configuration](../interfaces/analytics.chainedconfiguration.configuration.md) - ___ @@ -121,7 +96,7 @@ ___ ▸ **disable**(): `Promise`<`void`> -*Defined in analytics.ts:213* +*Defined in [analytics.ts:299](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L299)* Completely disable the sending of any analytics data. @@ -136,7 +111,7 @@ ___ ▸ **enable**(): `Promise`<`void`> -*Defined in analytics.ts:203* +*Defined in [analytics.ts:289](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L289)* Enable the sending of analytics data. Enabled by default. @@ -151,7 +126,7 @@ ___ ▸ **flush**(): `Promise`<`void`> -*Defined in analytics.ts:194* +*Defined in [analytics.ts:280](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L280)* Trigger an upload of all queued events. @@ -166,7 +141,7 @@ ___ ▸ **group**(groupId: *`string`*, traits?: *`JsonMap`*): `Promise`<`void`> -*Defined in analytics.ts:161* +*Defined in [analytics.ts:247](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L247)* Associate a user with a group, organization, company, project, or w/e _you_ call them. @@ -188,7 +163,7 @@ ___ ▸ **identify**(user: *`string`*, traits?: *`JsonMap`*): `Promise`<`void`> -*Defined in analytics.ts:149* +*Defined in [analytics.ts:235](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L235)* Associate a user with their unique ID and record traits about them. @@ -210,7 +185,7 @@ ___ ▸ **middleware**(middleware: *[Middleware]()*): `this` -*Defined in analytics.ts:66* +*Defined in [analytics.ts:147](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L147)* Append a new middleware to the middleware chain. @@ -248,7 +223,7 @@ ___ ▸ **reset**(): `Promise`<`void`> -*Defined in analytics.ts:184* +*Defined in [analytics.ts:270](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L270)* Reset any user state that is cached on the device. @@ -263,7 +238,7 @@ ___ ▸ **screen**(name: *`string`*, properties?: *`JsonMap`*): `Promise`<`void`> -*Defined in analytics.ts:135* +*Defined in [analytics.ts:221](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L221)* Record the screens or views your users see. @@ -278,6 +253,36 @@ When a user views a screen in your app, you'll want to record that here. For som **Returns:** `Promise`<`void`> +___ + + +### setup + +▸ **setup**(writeKey: *`string`*, configuration?: *[Configuration](../interfaces/analytics.configuration.md)*): `Promise`<`void`> + +*Defined in [analytics.ts:186](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L186)* + +Setup the Analytics module. All calls made before are queued and executed if the configuration was successful. + +```js +await analytics.setup('YOUR_WRITE_KEY', { + using: [Mixpanel, GoogleAnalytics], + trackAppLifecycleEvents: true, + ios: { + trackDeepLinks: true + } +}) +``` + +**Parameters:** + +| Param | Type | Default value | Description | +| ------ | ------ | ------ | ------ | +| writeKey | `string` | - | Your Segment.io write key | +| `Default value` configuration | [Configuration](../interfaces/analytics.configuration.md) | {} | An optional [Configuration](../interfaces/analytics.configuration.md) object. | + +**Returns:** `Promise`<`void`> + ___ @@ -285,7 +290,7 @@ ___ ▸ **track**(event: *`string`*, properties?: *`JsonMap`*): `Promise`<`void`> -*Defined in analytics.ts:117* +*Defined in [analytics.ts:203](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L203)* Record the actions your users perform. @@ -307,7 +312,7 @@ ___ ▸ **useNativeConfiguration**(): `this` -*Defined in analytics.ts:78* +*Defined in [analytics.ts:159](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L159)* Use the native configuration. diff --git a/packages/core/docs/interfaces/analytics.chainedconfiguration.android.md b/packages/core/docs/interfaces/analytics.chainedconfiguration.android.md deleted file mode 100644 index b964cf060..000000000 --- a/packages/core/docs/interfaces/analytics.chainedconfiguration.android.md +++ /dev/null @@ -1,114 +0,0 @@ -[@segment/analytics-react-native](../README.md) > [ChainedConfiguration](../modules/analytics.chainedconfiguration.md) > [Android](../interfaces/analytics.chainedconfiguration.android.md) - -# Interface: Android - -## Hierarchy - - [Base](analytics.chainedconfiguration.base.md) - -**↳ Android** - -## Index - -### Methods - -* [android](analytics.chainedconfiguration.android.md#android) -* [disableDeviceId](analytics.chainedconfiguration.android.md#disabledeviceid) -* [flushInterval](analytics.chainedconfiguration.android.md#flushinterval) -* [ios](analytics.chainedconfiguration.android.md#ios) -* [setup](analytics.chainedconfiguration.android.md#setup) - ---- - -## Methods - - - -### android - -▸ **android**(): [Android](analytics.chainedconfiguration.android.md) - -*Inherited from [Base](analytics.chainedconfiguration.base.md).[android](analytics.chainedconfiguration.base.md#android)* - -*Defined in analytics.ts:252* - -Access Android specific settings - -**Returns:** [Android](analytics.chainedconfiguration.android.md) - -___ - - -### disableDeviceId - -▸ **disableDeviceId**(): `this` - -*Defined in analytics.ts:306* - -Disable the collection of the device identifier. Enabled by default. - -The device identifier is obtained using : - -* `android.provider.Settings.Secure.ANDROID_ID` -* `android.os.Build.SERIAL` -* or Telephony Identifier retrieved via TelephonyManager as available - -**Returns:** `this` - -___ - - -### flushInterval - -▸ **flushInterval**(every: *`number`*): `this` - -*Defined in analytics.ts:313* - -Set the interval at which the client should flush events. The client will automatically flush events to Segment every [flushInterval](analytics.chainedconfiguration.android.md#flushinterval) duration, regardless of [flushAt](analytics.chainedconfiguration.configuration.md#flushat). - -**Parameters:** - -| Param | Type | Description | -| ------ | ------ | ------ | -| every | `number` | the interval in milliseconds | - -**Returns:** `this` - -___ - - -### ios - -▸ **ios**(): [iOS](analytics.chainedconfiguration.ios.md) - -*Inherited from [Base](analytics.chainedconfiguration.base.md).[ios](analytics.chainedconfiguration.base.md#ios)* - -*Defined in analytics.ts:248* - -Access iOS specific settings - -**Returns:** [iOS](analytics.chainedconfiguration.ios.md) - -___ - - -### setup - -▸ **setup**(writeKey: *[WriteKey](../#writekey)*): `Promise`<[Client](../classes/analytics.client.md)> - -*Inherited from [Base](analytics.chainedconfiguration.base.md).[setup](analytics.chainedconfiguration.base.md#setup)* - -*Defined in analytics.ts:244* - -Finalize the configuration and initialize the Analytics client. - -**Parameters:** - -| Param | Type | Description | -| ------ | ------ | ------ | -| writeKey | [WriteKey](../#writekey) | your Segment.io write key | - -**Returns:** `Promise`<[Client](../classes/analytics.client.md)> - -___ - diff --git a/packages/core/docs/interfaces/analytics.chainedconfiguration.base.md b/packages/core/docs/interfaces/analytics.chainedconfiguration.base.md deleted file mode 100644 index c09508e00..000000000 --- a/packages/core/docs/interfaces/analytics.chainedconfiguration.base.md +++ /dev/null @@ -1,72 +0,0 @@ -[@segment/analytics-react-native](../README.md) > [ChainedConfiguration](../modules/analytics.chainedconfiguration.md) > [Base](../interfaces/analytics.chainedconfiguration.base.md) - -# Interface: Base - -## Hierarchy - -**Base** - -↳ [Configuration](analytics.chainedconfiguration.configuration.md) - -↳ [iOS](analytics.chainedconfiguration.ios.md) - -↳ [Android](analytics.chainedconfiguration.android.md) - -## Index - -### Methods - -* [android](analytics.chainedconfiguration.base.md#android) -* [ios](analytics.chainedconfiguration.base.md#ios) -* [setup](analytics.chainedconfiguration.base.md#setup) - ---- - -## Methods - - - -### android - -▸ **android**(): [Android](analytics.chainedconfiguration.android.md) - -*Defined in analytics.ts:252* - -Access Android specific settings - -**Returns:** [Android](analytics.chainedconfiguration.android.md) - -___ - - -### ios - -▸ **ios**(): [iOS](analytics.chainedconfiguration.ios.md) - -*Defined in analytics.ts:248* - -Access iOS specific settings - -**Returns:** [iOS](analytics.chainedconfiguration.ios.md) - -___ - - -### setup - -▸ **setup**(writeKey: *[WriteKey](../#writekey)*): `Promise`<[Client](../classes/analytics.client.md)> - -*Defined in analytics.ts:244* - -Finalize the configuration and initialize the Analytics client. - -**Parameters:** - -| Param | Type | Description | -| ------ | ------ | ------ | -| writeKey | [WriteKey](../#writekey) | your Segment.io write key | - -**Returns:** `Promise`<[Client](../classes/analytics.client.md)> - -___ - diff --git a/packages/core/docs/interfaces/analytics.chainedconfiguration.configuration.md b/packages/core/docs/interfaces/analytics.chainedconfiguration.configuration.md deleted file mode 100644 index 54000ab53..000000000 --- a/packages/core/docs/interfaces/analytics.chainedconfiguration.configuration.md +++ /dev/null @@ -1,170 +0,0 @@ -[@segment/analytics-react-native](../README.md) > [ChainedConfiguration](../modules/analytics.chainedconfiguration.md) > [Configuration](../interfaces/analytics.chainedconfiguration.configuration.md) - -# Interface: Configuration - -## Hierarchy - - [Base](analytics.chainedconfiguration.base.md) - -**↳ Configuration** - -## Index - -### Methods - -* [android](analytics.chainedconfiguration.configuration.md#android) -* [debug](analytics.chainedconfiguration.configuration.md#debug) -* [flushAt](analytics.chainedconfiguration.configuration.md#flushat) -* [ios](analytics.chainedconfiguration.configuration.md#ios) -* [recordScreenViews](analytics.chainedconfiguration.configuration.md#recordscreenviews) -* [setup](analytics.chainedconfiguration.configuration.md#setup) -* [trackAppLifecycleEvents](analytics.chainedconfiguration.configuration.md#trackapplifecycleevents) -* [trackAttributionData](analytics.chainedconfiguration.configuration.md#trackattributiondata) -* [using](analytics.chainedconfiguration.configuration.md#using) - ---- - -## Methods - - - -### android - -▸ **android**(): [Android](analytics.chainedconfiguration.android.md) - -*Inherited from [Base](analytics.chainedconfiguration.base.md).[android](analytics.chainedconfiguration.base.md#android)* - -*Defined in analytics.ts:252* - -Access Android specific settings - -**Returns:** [Android](analytics.chainedconfiguration.android.md) - -___ - - -### debug - -▸ **debug**(): `this` - -*Defined in analytics.ts:282* - -**Returns:** `this` - -___ - - -### flushAt - -▸ **flushAt**(at: *`number`*): `this` - -*Defined in analytics.ts:277* - -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. `20` by default. - -**Parameters:** - -| Param | Type | -| ------ | ------ | -| at | `number` | - -**Returns:** `this` - -___ - - -### ios - -▸ **ios**(): [iOS](analytics.chainedconfiguration.ios.md) - -*Inherited from [Base](analytics.chainedconfiguration.base.md).[ios](analytics.chainedconfiguration.base.md#ios)* - -*Defined in analytics.ts:248* - -Access iOS specific settings - -**Returns:** [iOS](analytics.chainedconfiguration.ios.md) - -___ - - -### recordScreenViews - -▸ **recordScreenViews**(): `this` - -*Defined in analytics.ts:261* - -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 (before any screens are displayed). - -**Returns:** `this` - -___ - - -### setup - -▸ **setup**(writeKey: *[WriteKey](../#writekey)*): `Promise`<[Client](../classes/analytics.client.md)> - -*Inherited from [Base](analytics.chainedconfiguration.base.md).[setup](analytics.chainedconfiguration.base.md#setup)* - -*Defined in analytics.ts:244* - -Finalize the configuration and initialize the Analytics client. - -**Parameters:** - -| Param | Type | Description | -| ------ | ------ | ------ | -| writeKey | [WriteKey](../#writekey) | your Segment.io write key | - -**Returns:** `Promise`<[Client](../classes/analytics.client.md)> - -___ - - -### trackAppLifecycleEvents - -▸ **trackAppLifecycleEvents**(): `this` - -*Defined in analytics.ts:266* - -Enable the automatic tracking of application lifecycle events, such as "Application Installed", "Application Updated" and "Application Opened". - -**Returns:** `this` - -___ - - -### trackAttributionData - -▸ **trackAttributionData**(): `this` - -*Defined in analytics.ts:270* - -Whether the analytics client should automatically track attribution data from enabled providers using the mobile service. - -**Returns:** `this` - -___ - - -### using - -▸ **using**(...integrations: *[Integration](../#integration)[]*): `this` - -*Defined in analytics.ts:281* - -Register a set of integrations to be used with this Analytics instance. - -**Parameters:** - -| Param | Type | -| ------ | ------ | -| `Rest` integrations | [Integration](../#integration)[] | - -**Returns:** `this` - -___ - diff --git a/packages/core/docs/interfaces/analytics.chainedconfiguration.ios.md b/packages/core/docs/interfaces/analytics.chainedconfiguration.ios.md deleted file mode 100644 index f1ffe96b2..000000000 --- a/packages/core/docs/interfaces/analytics.chainedconfiguration.ios.md +++ /dev/null @@ -1,104 +0,0 @@ -[@segment/analytics-react-native](../README.md) > [ChainedConfiguration](../modules/analytics.chainedconfiguration.md) > [iOS](../interfaces/analytics.chainedconfiguration.ios.md) - -# Interface: iOS - -## Hierarchy - - [Base](analytics.chainedconfiguration.base.md) - -**↳ iOS** - -## Index - -### Methods - -* [android](analytics.chainedconfiguration.ios.md#android) -* [ios](analytics.chainedconfiguration.ios.md#ios) -* [setup](analytics.chainedconfiguration.ios.md#setup) -* [trackAdvertising](analytics.chainedconfiguration.ios.md#trackadvertising) -* [trackDeepLinks](analytics.chainedconfiguration.ios.md#trackdeeplinks) - ---- - -## Methods - - - -### android - -▸ **android**(): [Android](analytics.chainedconfiguration.android.md) - -*Inherited from [Base](analytics.chainedconfiguration.base.md).[android](analytics.chainedconfiguration.base.md#android)* - -*Defined in analytics.ts:252* - -Access Android specific settings - -**Returns:** [Android](analytics.chainedconfiguration.android.md) - -___ - - -### ios - -▸ **ios**(): [iOS](analytics.chainedconfiguration.ios.md) - -*Inherited from [Base](analytics.chainedconfiguration.base.md).[ios](analytics.chainedconfiguration.base.md#ios)* - -*Defined in analytics.ts:248* - -Access iOS specific settings - -**Returns:** [iOS](analytics.chainedconfiguration.ios.md) - -___ - - -### setup - -▸ **setup**(writeKey: *[WriteKey](../#writekey)*): `Promise`<[Client](../classes/analytics.client.md)> - -*Inherited from [Base](analytics.chainedconfiguration.base.md).[setup](analytics.chainedconfiguration.base.md#setup)* - -*Defined in analytics.ts:244* - -Finalize the configuration and initialize the Analytics client. - -**Parameters:** - -| Param | Type | Description | -| ------ | ------ | ------ | -| writeKey | [WriteKey](../#writekey) | your Segment.io write key | - -**Returns:** `Promise`<[Client](../classes/analytics.client.md)> - -___ - - -### trackAdvertising - -▸ **trackAdvertising**(): `this` - -*Defined in analytics.ts:289* - -Whether the analytics client should track advertisting info. - -**Returns:** `this` - -___ - - -### trackDeepLinks - -▸ **trackDeepLinks**(): `this` - -*Defined in analytics.ts:295* - -Whether the analytics client should automatically track deep links. - -You'll still need to call the continueUserActivity and openURL methods on the analytics client. - -**Returns:** `this` - -___ - diff --git a/packages/core/docs/interfaces/analytics.configuration.md b/packages/core/docs/interfaces/analytics.configuration.md new file mode 100644 index 000000000..f0e2a4c04 --- /dev/null +++ b/packages/core/docs/interfaces/analytics.configuration.md @@ -0,0 +1,127 @@ +[@segment/analytics-react-native](../README.md) > [Configuration](../interfaces/analytics.configuration.md) + +# Interface: Configuration + +## Hierarchy + +**Configuration** + +## Index + +### Properties + +* [android](analytics.configuration.md#android) +* [debug](analytics.configuration.md#debug) +* [flushAt](analytics.configuration.md#flushat) +* [ios](analytics.configuration.md#ios) +* [recordScreenViews](analytics.configuration.md#recordscreenviews) +* [trackAppLifecycleEvents](analytics.configuration.md#trackapplifecycleevents) +* [trackAttributionData](analytics.configuration.md#trackattributiondata) +* [using](analytics.configuration.md#using) + +--- + +## Properties + + + +### `` android + +**● android**: * `undefined` | `object` +* + +*Defined in [analytics.ts:69](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L69)* + +Android specific settings. + +___ + + +### `` debug + +**● debug**: * `undefined` | `false` | `true` +* + +*Defined in [analytics.ts:38](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L38)* + +___ + + +### `` flushAt + +**● flushAt**: * `undefined` | `number` +* + +*Defined in [analytics.ts:46](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L46)* + +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. + +`20` by default. + +___ + + +### `` ios + +**● ios**: * `undefined` | `object` +* + +*Defined in [analytics.ts:51](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L51)* + +iOS specific settings. + +___ + + +### `` recordScreenViews + +**● recordScreenViews**: * `undefined` | `false` | `true` +* + +*Defined in [analytics.ts:17](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L17)* + +Whether the analytics client should automatically track application lifecycle events, such as "Application Installed", "Application Updated" and "Application Opened". + +Disabled by default. + +___ + + +### `` trackAppLifecycleEvents + +**● trackAppLifecycleEvents**: * `undefined` | `false` | `true` +* + +*Defined in [analytics.ts:26](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L26)* + +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. + +Disabled by default. + +___ + + +### `` trackAttributionData + +**● trackAttributionData**: * `undefined` | `false` | `true` +* + +*Defined in [analytics.ts:32](https://github.com/segmentio/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. + +Disabled by default. + +___ + + +### `` using + +**● using**: *[Integration](../#integration)[]* + +*Defined in [analytics.ts:37](https://github.com/segmentio/analytics-react-native/blob/master/packages/core/src/analytics.ts#L37)* + +Register a set of integrations to be used with this Analytics instance. + +___ + diff --git a/packages/core/docs/modules/analytics.chainedconfiguration.md b/packages/core/docs/modules/analytics.chainedconfiguration.md deleted file mode 100644 index 7f49bdcc0..000000000 --- a/packages/core/docs/modules/analytics.chainedconfiguration.md +++ /dev/null @@ -1,15 +0,0 @@ -[@segment/analytics-react-native](../README.md) > [ChainedConfiguration](../modules/analytics.chainedconfiguration.md) - -# Module: ChainedConfiguration - -## Index - -### Interfaces - -* [Android](../interfaces/analytics.chainedconfiguration.android.md) -* [Base](../interfaces/analytics.chainedconfiguration.base.md) -* [Configuration](../interfaces/analytics.chainedconfiguration.configuration.md) -* [iOS](../interfaces/analytics.chainedconfiguration.ios.md) - ---- - diff --git a/packages/core/ios/RNAnalytics/RNAnalytics.m b/packages/core/ios/RNAnalytics/RNAnalytics.m index 698177a21..b006d7729 100644 --- a/packages/core/ios/RNAnalytics/RNAnalytics.m +++ b/packages/core/ios/RNAnalytics/RNAnalytics.m @@ -33,7 +33,7 @@ +(void)initialize { @synthesize bridge = _bridge; RCT_EXPORT_METHOD(setup:(NSDictionary*)options) { - SEGAnalyticsConfiguration* config = [SEGAnalyticsConfiguration configurationWithWriteKey:options[@"ios"][@"writeKey"]]; + SEGAnalyticsConfiguration* config = [SEGAnalyticsConfiguration configurationWithWriteKey:options[@"writeKey"]]; config.recordScreenViews = [options[@"recordScreenViews"] boolValue]; config.trackApplicationLifecycleEvents = [options[@"trackAppLifecycleEvents"] boolValue]; diff --git a/packages/core/src/__tests__/analytics.spec.ts b/packages/core/src/__tests__/analytics.spec.ts index 8d2fd9406..08f6ceb2a 100644 --- a/packages/core/src/__tests__/analytics.spec.ts +++ b/packages/core/src/__tests__/analytics.spec.ts @@ -24,7 +24,7 @@ beforeEach(async () => { analytics = new Analytics.Client() Object.keys(Bridge).forEach(key => getBridgeStub(key as any).mockClear()) - await analytics.configure().setup('write key') + await analytics.setup('write key') }) afterEach(() => { @@ -53,7 +53,7 @@ it('waits for .setup()', async () => { client.track('test 2') expect(Bridge.track).not.toHaveBeenCalled() - await client.configure().setup('key') + await client.setup('key') expect(Bridge.track).toHaveBeenNthCalledWith(1, 'test 1', {}, ctx) expect(Bridge.track).toHaveBeenNthCalledWith(2, 'test 2', {}, ctx) diff --git a/packages/core/src/__tests__/configuration.spec.ts b/packages/core/src/__tests__/configuration.spec.ts index dd3c7e280..426331931 100644 --- a/packages/core/src/__tests__/configuration.spec.ts +++ b/packages/core/src/__tests__/configuration.spec.ts @@ -1,115 +1,76 @@ -import Bridge from '../bridge' import { configure } from '../configuration' -jest.mock('../bridge') - -const config = () => configure(null as any, jest.fn()) const writeKey = 'test-write-key' -const defaultConfig = { - flushAt: 20, - - debug: false, - recordScreenViews: false, - trackAppLifecycleEvents: false, - trackAttributionData: false, - - android: { - collectDeviceId: true, - writeKey - }, - ios: { - trackAdvertising: false, - trackDeepLinks: false, - writeKey - } -} - -beforeEach(() => { - ;(Bridge.setup as jest.Mock).mockClear() -}) - it('uses the default configuration', async () => { - await config().setup(writeKey) + expect(await configure(writeKey, {})).toEqual({ + debug: false, + flushAt: 20, + recordScreenViews: false, + trackAppLifecycleEvents: false, + trackAttributionData: false, + writeKey, - expect(Bridge.setup).toHaveBeenLastCalledWith(defaultConfig) + android: { + collectDeviceId: true, + flushInterval: undefined + }, + ios: { + trackAdvertising: false, + trackDeepLinks: false + } + }) }) it('produces a valid configuration', async () => { - await config() - .recordScreenViews() - .trackAppLifecycleEvents() - .trackAttributionData() - .flushAt(42) - .debug() - .ios() - .trackAdvertising() - .trackDeepLinks() - .android() - .flushInterval(72) - .disableDeviceId() - .setup(writeKey) - - expect(Bridge.setup).toHaveBeenLastCalledWith({ - flushAt: 42, - + const config = await configure(writeKey, { debug: true, + flushAt: 42, recordScreenViews: true, trackAppLifecycleEvents: true, trackAttributionData: true, android: { collectDeviceId: false, - flushInterval: 72, - writeKey + flushInterval: 72 }, ios: { trackAdvertising: true, - trackDeepLinks: true, - writeKey + trackDeepLinks: true } }) -}) -it('supports per-platform write keys', async () => { - const android = 'write key android' - const ios = 'write key ios' - - await config().setup({ ios, android }) + expect(config).toEqual({ + debug: true, + flushAt: 42, + recordScreenViews: true, + trackAppLifecycleEvents: true, + trackAttributionData: true, + writeKey, - expect(Bridge.setup).toHaveBeenLastCalledWith({ - ...defaultConfig, android: { - ...defaultConfig.android, - writeKey: android + collectDeviceId: false, + flushInterval: 72 }, ios: { - ...defaultConfig.ios, - writeKey: ios + trackAdvertising: true, + trackDeepLinks: true } }) }) it('waits for integrations to register', async () => { - const stub = jest.fn(async t => - setTimeout(() => { - expect(Bridge.setup).not.toHaveBeenCalled() - t() - }, 500) - ) + const stub = jest.fn(t => setTimeout(t, 500)) - await config() - .using(() => ({ then: stub })) - .setup(writeKey) + await configure(writeKey, { + using: [() => ({ then: stub })] + }) expect(stub).toHaveBeenCalled() - expect(Bridge.setup).toHaveBeenCalled() }) it('supports disabled integrations', async () => { - await config() - .using({ disabled: true }) - .setup(writeKey) - - expect(Bridge.setup).toHaveBeenCalled() + await configure(writeKey, { + using: [{ disabled: true }] + }) }) diff --git a/packages/core/src/analytics.ts b/packages/core/src/analytics.ts index a47f73efe..5c70ba073 100644 --- a/packages/core/src/analytics.ts +++ b/packages/core/src/analytics.ts @@ -1,10 +1,91 @@ -import { JsonMap } from './bridge' +import Bridge, { JsonMap } from './bridge' import { configure } from './configuration' import { Middleware, MiddlewareChain } from './middleware' import { ErrorHandler, NativeWrapper } from './wrapper' // prettier-ignore export module Analytics { + export type Integration = (() => PromiseLike) | { disabled: true } + + export interface Configuration { + /** + * Whether the analytics client should automatically track application lifecycle events, such as + * "Application Installed", "Application Updated" and "Application Opened". + * + * Disabled by default. + */ + recordScreenViews?: boolean + /** + * 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. + * + * Disabled by default. + */ + trackAppLifecycleEvents?: boolean + /** + * Whether the analytics client should automatically track attribution data from enabled providers using the mobile service. + * + * Disabled by default. + */ + trackAttributionData?: boolean + + /** + * Register a set of integrations to be used with this Analytics instance. + */ + using?: Integration[] + debug?: boolean + + /** + * 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. + * + * `20` by default. + */ + flushAt?: number + + /** + * iOS specific settings. + */ + ios?: { + /** + * Whether the analytics client should track advertisting info. + * + * Disabled by default. + */ + trackAdvertising?: boolean + /** + * Whether the analytics client should automatically track deep links. + * You'll still need to call the continueUserActivity and openURL methods on the native analytics client. + * + * Disabled by default. + */ + trackDeepLinks?: boolean + } + /** + * Android specific settings. + */ + android?: { + /** + * Set the interval in milliseconds at which the client should flush events. The client will automatically flush + * events to Segment every {@link flushInterval} duration, regardless of {@link flushAt}. + */ + flushInterval?: number + + /** + * Whether the analytics client should client the device identifier. + * The device identifier is obtained using : + * - `android.provider.Settings.Secure.ANDROID_ID` + * - `android.os.Build.SERIAL` + * - or Telephony Identifier retrieved via TelephonyManager as available + * + * Enabled by default. + */ + collectDeviceId?: boolean + } + } + export class Client { /** * Whether the client is ready to send events to Segment. @@ -86,21 +167,26 @@ export module Analytics { } /** - * Configure the Analytics module. + * Setup the Analytics module. All calls made before are queued + * and only executed if the configuration was successful. * - * This method returns a fluent-style API to configure the SDK : * ```js - * analytics - * .configure() - * .using(Mixpanel, GoogleAnalytics) - * .trackAppLifecycle() - * .ios() - * .trackDeepLinks() - * .setup("YOUR_WRITE_KEY") + * await analytics.setup('YOUR_WRITE_KEY', { + * using: [Mixpanel, GoogleAnalytics], + * trackAppLifecycleEvents: true, + * ios: { + * trackDeepLinks: true + * } + * }) * ``` + * + * @param writeKey Your Segment.io write key + * @param configuration An optional {@link Configuration} object. */ - public configure() { - return configure(this, () => this.wrapper.ready()) + public async setup(writeKey: string, configuration: Configuration = {}) { + await Bridge.setup(await configure(writeKey, configuration)) + + this.wrapper.ready() } /** @@ -225,92 +311,4 @@ export module Analytics { } } } - - export type Integration = (() => PromiseLike) | { disabled: true } - - export type WriteKey = - | string - | { - android: string - ios: string - } - - export module ChainedConfiguration { - export interface Base { - /** - * Finalize the configuration and initialize the Analytics client. - * @param writeKey your Segment.io write key - */ - setup(writeKey: WriteKey): Promise - /** - * Access iOS specific settings - */ - ios(): iOS - /** - * Access Android specific settings - */ - android(): Android - } - export interface Configuration extends Base { - /** - * 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 (before any screens are displayed). - */ - recordScreenViews(): this - /** - * Enable the automatic tracking of application lifecycle events, such as - * "Application Installed", "Application Updated" and "Application Opened". - */ - trackAppLifecycleEvents(): this - /** - * Whether the analytics client should automatically track attribution data from enabled providers using the mobile service. - */ - trackAttributionData(): this - /** - * 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. - * `20` by default. - */ - flushAt(at: number): this - /** - * Register a set of integrations to be used with this Analytics instance. - */ - using(...integrations: Integration[]): this - debug(): this - } - // tslint:disable-next-line - export interface iOS extends Base { - /** - * Whether the analytics client should track advertisting info. - */ - trackAdvertising(): this - /** - * Whether the analytics client should automatically track deep links. - * - * You'll still need to call the continueUserActivity and openURL methods on the analytics client. - */ - trackDeepLinks(): this - } - export interface Android extends Base { - /** - * Disable the collection of the device identifier. Enabled by default. - * - * The device identifier is obtained using : - * - `android.provider.Settings.Secure.ANDROID_ID` - * - `android.os.Build.SERIAL` - * - or Telephony Identifier retrieved via TelephonyManager as available - */ - disableDeviceId(): this - /** - * Set the interval at which the client should flush events. The client will automatically flush - * events to Segment every {@link flushInterval} duration, regardless of {@link flushAt}. - * - * @param every the interval in milliseconds - */ - flushInterval(every: number): this - } - } } diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index b31921bed..733256097 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -1,79 +1,53 @@ import { Analytics } from './analytics' import Bridge from './bridge' -import { toggle } from './utils' -export function configure( - analytics: Analytics.Client, - done: () => void -): Analytics.ChainedConfiguration.Configuration { - const promises: Array> = [] - const config: Bridge.Configuration = { - flushAt: 20, - - debug: false, - recordScreenViews: false, - trackAppLifecycleEvents: false, - trackAttributionData: false, - - android: { - collectDeviceId: true, - writeKey: '' - }, - ios: { - trackAdvertising: false, - trackDeepLinks: false, - writeKey: '' - } - } - - const baseMatcher = { - android: () => ({ - ...baseMatcher, - disableDeviceId: toggle(config.android, 'collectDeviceId', false), - flushInterval(interval: number) { - config.android.flushInterval = interval - - return this - } - }), - ios: () => ({ - ...baseMatcher, - trackAdvertising: toggle(config.ios, 'trackAdvertising', true), - trackDeepLinks: toggle(config.ios, 'trackDeepLinks', true) - }), - setup: async (writeKey: Analytics.WriteKey) => { - if (typeof writeKey === 'string') { - config.ios.writeKey = writeKey - config.android.writeKey = writeKey - } else { - config.ios.writeKey = writeKey.ios - config.android.writeKey = writeKey.android - } - - await Promise.all(promises) - await Bridge.setup(config) - done() +const defaults = { + android: ({ + collectDeviceId = true, + flushInterval + }: Partial) => ({ + collectDeviceId, + flushInterval + }), + ios: ({ + trackAdvertising = false, + trackDeepLinks = false + }: Partial) => ({ + trackAdvertising, + trackDeepLinks + }) +} - return analytics - } - } +export const configure = async ( + writeKey: string, + { + flushAt = 20, + debug = false, + recordScreenViews = false, + trackAppLifecycleEvents = false, + trackAttributionData = false, + using = [], + + ios = {}, + android = {} + }: Analytics.Configuration +): Promise => { + await Promise.all( + using.map( + async integration => + typeof integration === 'function' ? await integration() : null + ) + ) return { - ...baseMatcher, - debug: toggle(config, 'debug', true), - flushAt: toggle(config, 'flushAt'), - recordScreenViews: toggle(config, 'recordScreenViews', true), - trackAppLifecycleEvents: toggle(config, 'trackAppLifecycleEvents', true), - trackAttributionData: toggle(config, 'trackAttributionData', true), - using(...integrations: Analytics.Integration[]) { - promises.push( - ...integrations.map( - async integration => - typeof integration === 'function' ? integration() : null - ) - ) - - return this - } + debug, + flushAt, + recordScreenViews, + trackAppLifecycleEvents, + trackAttributionData, + writeKey, + + android: defaults.android(android), + ios: defaults.ios(ios) } } diff --git a/packages/core/src/make-pkg.ts b/packages/core/src/make-pkg.ts index 662c49bd2..995c54f0d 100644 --- a/packages/core/src/make-pkg.ts +++ b/packages/core/src/make-pkg.ts @@ -1,3 +1,3 @@ import { version } from '../package.json' -console.log(JSON.stringify({ version })) +console.log(JSON.stringify({ version }, null, 2)) diff --git a/packages/core/src/modules.d.ts b/packages/core/src/modules.d.ts index 3fcabd23a..23290407e 100644 --- a/packages/core/src/modules.d.ts +++ b/packages/core/src/modules.d.ts @@ -2,22 +2,21 @@ declare module '*.json' declare module 'react-native' { export namespace NativeModules.RNAnalytics { export interface Configuration { + writeKey: string recordScreenViews: boolean trackAppLifecycleEvents: boolean trackAttributionData: boolean debug: boolean flushAt: number - ios: { - trackAdvertising: boolean - trackDeepLinks: boolean - writeKey: string - } android: { flushInterval?: number - writeKey: string collectDeviceId: boolean } + ios: { + trackAdvertising: boolean + trackDeepLinks: boolean + } } export type JsonValue = diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index b5035e59e..d399f858e 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -1,18 +1,3 @@ -export const toggle = ( - obj: O, - key: K, - defaultValue?: T -) => - function(this: S, value?: T) { - if (typeof defaultValue !== 'undefined') { - obj[key] = defaultValue - } else if (typeof value !== 'undefined') { - obj[key] = value - } - - return this - } as T extends O[K] ? (this: S) => S : (this: S, a: O[K]) => S - export function assertNever(never: never) { throw new Error('Expected never, got ' + never) } diff --git a/packages/test-app/generate.sh b/packages/test-app/generate.sh index cbe91a2d6..2d77621fb 100755 --- a/packages/test-app/generate.sh +++ b/packages/test-app/generate.sh @@ -26,11 +26,12 @@ cat << EOF >> App.js buildId = '$CIRCLE_WORKFLOW_ID' analytics - .configure() - .using($integrations_require) - .debug() - .setup('$SEGMENT_WRITE_TOKEN') - .then(() => console.log('Analytics ready')) + .setup('$SEGMENT_WRITE_TOKEN', { + using: [$integrations_require], + debug: true + }) + .then(() => console.log('Analytics ready')) + .catch(err => console.error('Analytics error', err)) EOF ../android-workaround.js