Skip to contentSkip to navigationSkip to topbar
Page toolsOn this page
Looking for more inspiration?Visit the

Analytics-Swift Typewriter


Typewriter(link takes you to an external page) is a tool for generating strongly-typed Segment analytics libraries based on your pre-defined Tracking Plan spec.

At a high-level, Typewriter can take an event from your Tracking Plan, like this "Order Completed" event, and generate a typed analytics call in different languages:

1
// Example client in your web app
2
const typewriter = require('./analytics')
3
4
typewriter.orderCompleted({
5
orderID: 'ck-f306fe0e-cc21-445a-9caa-08245a9aa52c',
6
total: 39.99
7
})
1
// Example client in your iOS app
2
SEGTypewriterAnalytics.orderCompleted(
3
orderID: "ck-f306fe0e-cc21-445a-9caa-08245a9aa52c",
4
total: 39.99
5
)

These generated clients are embedded with metadata from your Tracking Plan, which contextualizes your analytics instrumentation, and reduces or eliminates incorrect instrumentations in your production environments. In your editor, you can access event names, descriptions, property names, types and more:

Code editor showing event name suggestions like orderCompleted with description.

You can also configure Typewriter to validate analytic events at runtime, which can alert you to instrumentation errors during development and testing. Typewriter can warn you about missing required properties, invalid enum values, regex mismatches, and any other advanced JSON Schema(link takes you to an external page) you configure in your Tracking Plan.

Example run-time validation warning where JavaScript error shows pattern mismatch and missing property 'tracking_plan_id'.

You can use this with a test suite to automatically fail your unit tests if the instrumentation generates any violations:

Example unit test failing due to Typewriter violation: properties.id should be string.

If you use a statically typed language (such as TypeScript, Java, Objective-C, or Swift), you get access to compile-time warnings about your instrumentation:

Example compile-time validation warning in which type error: 'string' not assignable to 'number' in ProductsItem price.

Typewriter also helps teams adopt analytics best practices, such as avoiding autogenerated event names and carefully considering what properties are tracked.


Prerequisites

prerequisites page anchor

Typewriter is built using Node.js(link takes you to an external page). It requires node@8.x or later and npm@5.2.x or later to function.

You can check if you have Node and NPM installed by running the following commands in your command-line window:

1
$ node --version
2
# v10.15.3
3
4
$ npm --version
5
# 6.9.0
6
7
$ npx --version
8
# 6.9.0

If you don't have these, you'll need to install node(link takes you to an external page). Installing node also installs npm and npx for you. If you're on macOS, you can install it with Homebrew(link takes you to an external page):

$ brew install node

Once you've installed Node and NPM, run the --version commands again to verify that they were installed correctly.


(information)

Info

Use Typewriter v7 with the analytics-ios SDK .

To get started using Typewriter with Swift:

  1. Make sure you have node installed using the instructions in the prerequisites above.

  2. Install analytics-swift in your app. Follow the Analytics-Swift Quickstart Guide.

  3. Run npx typewriter init to use the Typewriter quickstart wizard that generates a typewriter.yml configuration, along with your first Typewriter client. When you run the command, it creates a typewriter.yml file in your repository. For more information on the format of this file, see the Typewriter Configuration Reference.


    Each time you update your Tracking Plan, run npx typewriter to regenerate your Typewriter client.

  4. Import your new Typewriter client into your project using XCode. If you place your generated files into a folder in your project, import the project as a group not a folder reference.


    When you add the generated client to your Xcode Project you can use as a Swift extension method on any Analytics client object:

    1
    Analytics.main.orderCompleted(OrderCompleted(
    2
    orderID: "ck-f306fe0e-cc21-445a-9caa-08245a9aa52c",
    3
    total: 39.99
    4
    ))

To update or add a new event to a Typewriter client, first apply your changes to your Tracking Plan. Then run the following:

1
# Run this in the directory that contains your repo's `typewriter.yml` file.
2
$ npx typewriter

Typewriter requires a Segment API token to fetch Tracking Plans from the Segment Public API(link takes you to an external page).

You must be a workspace owner to create Segment API tokens.

To create an API token:

  1. Click on the Tokens tab on the Access Management(link takes you to an external page) page and click Create Token.
  2. Choose Segment's Public API.
  3. Add a description for the token and assign access. If you choose Workspace Member, you only need to select Tracking Plan Read-Only for the Resource Role, as Typewriter only needs the Tracking Plan Read-Only role.
  4. Click Create.

How does Typewriter look for a Segment API token?

how-does-typewriter-look-for-a-segment-api-token page anchor

Typewriter looks for an API token in three ways, in the following order:

  1. If a token is piped through, it will use that token. For example, echo $TW_TOKEN | typewriter build.
  2. Typewriter executes a token script from the typewriter.yml. See Token Script for more information.
  3. Typewriter reads the contents of the ~/.typewriter file.

The quickstart wizard prompts you for an API token and stores it in ~/.typewriter for you.

Segment recommends you use a Token Script to share an API token with your team. When you use a token script, you can supply your API token as an environment variable (echo $TYPEWRITER_TOKEN), from an .env. file (source .env; echo $TYPEWRITER_TOKEN) or using any other CLI tool for providing secrets.

Segment also recommends you to pipe through your API Token as this will let you keep your token secret, but it also allows you to share it across your team.

(warning)

Warning

Segment is keeping the Token Script execution for compatibility purposes only in Typewriter v8. Segment might deprecate this feature in the future, and encourages you to execute your script and pipe in the token. For example, echo $TW_TOKEN | typewriter build.


Segment strongly recommends that you store your Tracking Plan (plan.json) in a version control system. This guarantees that Typewriter will generate the same client, regardless of any changes you make to your Tracking Plan in the Segment app. Otherwise, changes to your Tracking Plan could lead to broken builds.

Segment recommends that you only check in the plan.json, and generate your Typewriter client during the application build step (by calling npx typewriter). You can do this in git with the following .gitignore:

1
# Make sure to update `analytics` to the full path to your Typewriter client.
2
analytics/*
3
!analytics/plan.json

If this isn't possible you can also check in the full generated client. Segment, however, doesn't recommend this method.


Typewriter stores its configuration in a typewriter.yml file in the root of your repository. A sample configuration might look like this:

1
# Segment Typewriter Configuration Reference (https://github.com/segmentio/typewriter)
2
# Just run `npx typewriter` to re-generate a client with the latest versions of these events.
3
4
scripts:
5
# You can supply a Segment API token using a `script.token` command. See `Token Script` below.
6
token: source .env; echo $TYPEWRITER_TOKEN
7
# You can format any of Typewriter's auto-generated files using a `script.after` command.
8
# See `Formatting Generated Files` below.
9
after: ./node_modules/.bin/prettier --write analytics/plan.json
10
11
client:
12
# Which Segment SDK you are generating for.
13
# Valid values: analytics.js, analytics-node, analytics-react-native, swift, kotlin.
14
sdk: analytics-node
15
# The target language for your Typewriter client.
16
# Valid values: javascript, typescript, kotlin, swift.
17
language: typescript
18
19
trackingPlans:
20
# The Segment Protocols Tracking Plan that you are generating a client for.
21
# Provide your workspace slug and Tracking Plan id, both of which can be found
22
# in the URL when viewing the Tracking Plan editor. For example:
23
# https://app.segment.com/segment-demo/protocols/tracking-plans/rs_QhWHOgp7xg8wkYxilH3scd2uRID
24
# You also need to supply a path to a directory to save your Typewriter client.
25
- id: rs_QhWHOgp7xg8wkYxilH3scd2uRID
26
workspaceSlug: segment-demo
27
path: ./analytics

At any time, you can regenerate this file by running the Typewriter quickstart wizard:

$ npx typewriter init

(warning)

Warning

Segment is keeping the Token Script execution for compatibility purposes only in Typewriter v8. Segment might deprecate this feature in the future, and encourages you to execute your script and pipe in the token. For example, echo $TW_TOKEN | typewriter build.

If your team has a standard way to supply secrets (passwords and tokens) in development environments, whether that's an .env file or an AWS-backed secret store, you can configure Typewriter to use it to get a Segment API token.

To configure this, create a token script called scripts.token in your typewriter.yml. This script is a string that contains a shell command that, when executed, outputs a valid Segment API token. Here's an insecure example:

1
scripts:
2
# NOTE: NEVER commit a Segment API token to your version control system.
3
token: echo "OIEGO$*hf83hfh034fnosnfiOEfowienfownfnoweunfoiwenf..."

To give a real example, Segment stores secrets in segmentio/chamber(link takes you to an external page) which is backed by AWS Parameter Store(link takes you to an external page). Providing access to a token in chamber looks like this:

1
scripts:
2
token: aws-okta exec dev-privileged -- chamber export typewriter | jq -r .typewriter_token

To learn more about the typewriter.yml configuration format, see the Configuration Reference.


Formatting generated files

formatting-generated-files page anchor

In your typewriter.yml, you can configure a script (scripts.after) that fires after generating a Typewriter client. You can use this to apply your team's style guide to any of Typewriter's auto-generated files.

For example, if you want to apply your prettier(link takes you to an external page) formatting to plan.json (the local snapshot of your Tracking Plan), you can use an after script like this:

1
scripts:
2
after: ./node_modules/.bin/prettier --write ./analytics/plan.json

To learn more about the typewriter.yml configuration format, see the Configuration Reference.


As mentioned in the Best Practices section above, Segment recommends that you only check in the plan.json, and not the generated clients, into your version control. Segment instead recommends building these clients as part of the build step for your application.

In your CI environment, this usually involves a step to build the Typewriter client. Make sure to build the production client before deploying the application, as explained in Tracking Plan Violation Handling.

1
# An example (simplified) CircleCI configuration:
2
jobs:
3
test:
4
steps:
5
- npx typewriter development
6
- yarn run test
7
8
deploy:
9
steps:
10
- npx typewriter production
11
- yarn run deploy

If you're interested in contributing, open an issue on GitHub(link takes you to an external page) and Segment can help you get started.


Segment welcomes feedback you may have on your experience with Typewriter. To contact Segment, open an issue on GitHub(link takes you to an external page).