-
Notifications
You must be signed in to change notification settings - Fork 109
update README for beta release #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,344 +1,57 @@ | ||
| # Analytics-Swift | ||
|
|
||
| NOTE: This project is currently in the Pilot phase and is covered by Segment's [First Access & Beta Preview Terms](https://segment.com/legal/first-access-beta-preview/). We encourage you | ||
| to try out this new library. Please provide feedback via Github issues/PRs, and feel free to submit pull requests. This library will eventually | ||
| supplant our `analytics-ios` library, but customers should not use this library for production applications during our Pilot phase. | ||
| NOTE: This project is currently in the Beta phase and is covered by Segment's [First Access & Beta Preview Terms](https://segment.com/legal/first-access-beta-preview/). We encourage you | ||
| to try out this new library. Please provide feedback via Github issues/PRs, and feel free to submit pull requests. | ||
|
|
||
| The hassle-free way to add Segment analytics to your Swift app (iOS/tvOS/watchOS/macOS/Linux). | ||
| The hassle-free way to add Segment analytics to your Swift app (iOS/tvOS/watchOS/macOS/Linux/iPadOS). Analytics helps you measure your users, product, and business. It unlocks insights into your app's funnel, core business metrics, and whether you have product-market fit. | ||
|
|
||
| ## Table of Contents | ||
| - [Installation](#installation) | ||
| - [Usage](#usage) | ||
| - [Setting up the client](#setting-up-the-client) | ||
| - [Client Options](#client-options) | ||
| - [Client Methods](#client-methods) | ||
| - [track](#track) | ||
| - [identify](#identify) | ||
| - [screen](#screen) | ||
| - [group](#group) | ||
| - [add](#add) | ||
| - [find](#find) | ||
| - [remove](#remove) | ||
| - [flush](#flush) | ||
| - [Plugin Architecture](#plugin-architecture) | ||
| - [Fundamentals](#fundamentals) | ||
| - [Advanced Concepts](#advanced-concepts) | ||
| - [Contributing](#contributing) | ||
| - [Code of Conduct](#code-of-conduct) | ||
| - [License](#license) | ||
| ## How to get started | ||
| 1. **Collect analytics data** from your app(s). | ||
| - The top 200 Segment companies collect data from 5+ source types (web, mobile, server, CRM, etc.). | ||
| 2. **Send the data to analytics tools** (for example, Google Analytics, Amplitude, Mixpanel). | ||
| - Over 250+ Segment companies send data to eight categories of destinations such as analytics tools, warehouses, email marketing and remarketing systems, session recording, and more. | ||
| 3. **Explore your data** by creating metrics (for example, new signups, retention cohorts, and revenue generation). | ||
| - The best Segment companies use retention cohorts to measure product market fit. Netflix has 70% paid retention after 12 months, 30% after 7 years. | ||
|
|
||
| ## Installation | ||
| Add the Swift package as a dependency either via your package.swift, or via Xcode's File->Swift Packages->Add Package Dependency menu item. | ||
| [Segment](https://segment.com) collects analytics data and allows you to send it to more than 250 apps (such as Google Analytics, Mixpanel, Optimizely, Facebook Ads, Slack, Sentry) just by flipping a switch. You only need one Segment code snippet, and you can turn integrations on and off at will, with no additional code. [Sign up with Segment today](https://app.segment.com/signup). | ||
|
|
||
| `[email protected]:segmentio/analytics-swift.git` | ||
| ### Why? | ||
| 1. **Power all your analytics apps with the same data**. Instead of writing code to integrate all of your tools individually, send data to Segment, once. | ||
|
|
||
| Once completed, Analytics can be referenced by importing Segment's Analytics package | ||
| 2. **Install tracking for the last time**. We're the last integration you'll ever need to write. You only need to instrument Segment once. Reduce all of your tracking code and advertising tags into a single set of API calls. | ||
|
|
||
| `import Segment` | ||
| 3. **Send data from anywhere**. Send Segment data from any device, and we'll transform and send it on to any tool. | ||
|
|
||
| ## Usage | ||
| ### Setting up the client | ||
| The Analytics client will typically be set up at application launch time, such as `applicationDidFinishLaunching`. | ||
| 4. **Query your data in SQL**. Slice, dice, and analyze your data in detail with Segment SQL. We'll transform and load your customer behavioral data directly from your apps into Amazon Redshift, Google BigQuery, or Postgres. Save weeks of engineering time by not having to invent your own data warehouse and ETL pipeline. | ||
|
|
||
| Typically the following call may be all that's required. | ||
| For example, you can capture data on any app: | ||
| ```kotlin | ||
| analytics.track('Order Completed', Properties(price = 99.84)) | ||
| ``` | ||
| Then, query the resulting data in SQL: | ||
| ```sql | ||
| select * from app.order_completed | ||
| order by price desc | ||
| ``` | ||
|
|
||
| ```swift | ||
| Analytics(configuration: Configuration("<YOUR_WRITE_KEY>")) | ||
| ``` | ||
|
|
||
| ### Configuration Options | ||
| When creating a new client, you can configure it in various ways. Some examples are listed below. | ||
|
|
||
| ```swift | ||
| let config = Configuration(writeKey: "<YOUR_WRITE_KEY>") | ||
| .flushAt(3) | ||
| .trackApplicationLifecycleEvents(true) | ||
| .flushInterval(10) | ||
|
|
||
| let analytics = Analytics(configuration: config) | ||
| ``` | ||
|
|
||
| | Name | Default | Description | | ||
| | ---- | ------- | ----- | | ||
| | writeKey | *required* | Your Segment writeKey | | ||
| | application | `nil` | application specific object | | ||
| | trackApplicationLifecycleEvents | `true` | automatically track Lifecycle events | | ||
| | trackDeepLinks | `true` | automatically track deep links | | ||
| | flushAt | `20` | count of events at which we flush events | | ||
| | flushInterval | `30` (seconds) | interval in seconds at which we flush events | ||
| | defaultSettings | `{}` | Settings object that will be used as fallback in case of network failure | ||
| | autoAddSegmentDestination | `true` | automatically add SegmentDestination plugin, disable in case you want to add plugins to SegmentDestination | ||
| | apiHost | `api.segment.io/v1` | set a default apiHost to which Segment sends event | ||
|
|
||
| You may notice that some configuration options such as IDFA collection and automatic screen tracking from our previous library have been removed. | ||
| These options have been moved to distinct plugins that can be found in our [Plugin Examples repo](https://github.com/segmentio/analytics-example-plugins/tree/main/plugins/swift). | ||
| ## Client Methods | ||
|
|
||
| ### track | ||
| The track method is how you record any actions your users perform, along with any properties that describe the action. | ||
|
|
||
| Method signatures: | ||
| ```swift | ||
| func track(name: String) | ||
| // This signature provides a typed version of properties. | ||
| func track<P: Codable>(name: String, properties: P?) | ||
| // Generic dictionary for properties | ||
| func track(name: String, properties: [String: Any]?) | ||
| ``` | ||
|
|
||
| Example usage: | ||
| ```swift | ||
| struct TrackProperties: Codable { | ||
| let someValue: String | ||
| } | ||
|
|
||
| // ... | ||
|
|
||
| analytics.track(name: "My Event", TrackProperties(someValue: "Hello")) | ||
|
|
||
| analytics.track(name: "Another Event", ["someValue": "Goodbye"]) | ||
| ``` | ||
|
|
||
| ### identify | ||
| The identify call lets you tie a user to their actions and record traits about them. This includes a unique user ID and any optional traits you know about them like their email, name, etc. The traits option can include any information you might want to tie to the user, but when using any of the reserved user traits, you should make sure to only use them for their intended meaning. | ||
|
|
||
| Method signatures: | ||
| ```swift | ||
| // These signatures provide for a typed version of user traits | ||
| func identify<T: Codable>(userId: String, traits: T) | ||
| func identify<T: Codable>(traits: T) | ||
| func identify(userId: String) | ||
| ``` | ||
|
|
||
| Example Usage: | ||
| ```swift | ||
| struct MyTraits: Codable { | ||
| let favoriteColor: String | ||
| } | ||
| ## Documentation | ||
|
|
||
| // ... | ||
| You can find usage documentation at [https://segment.com/docs/sources/mobile/swift-ios/](https://segment.com/docs/sources/mobile/swift-ios/). | ||
|
|
||
| analytics.identify("[email protected]", MyTraits(favoriteColor: "fuscia")) | ||
| ``` | ||
|
|
||
| ### screen | ||
| The screen call lets you record whenever a user sees a screen in your mobile app, along with any properties about the screen. | ||
|
|
||
| Method signatures: | ||
| ```swift | ||
| func screen(title: String, category: String? = nil) | ||
| func screen<P: Codable>(title: String, category: String? = nil, properties: P?) | ||
| ``` | ||
|
|
||
| Example Usage: | ||
| ```swift | ||
| analytics.screen(title: "SomeScreen") | ||
| ``` | ||
|
|
||
| You can enable automatic screen tracking by using the [example plugin](https://github.com/segmentio/analytics-example-plugins/blob/main/plugins/swift/UIKitScreenTracking.swift). | ||
|
|
||
| Once the plugin has been added to your project add it to your Analytics instance: | ||
| ```swift | ||
| analytics.add(plugin: UIKitScreenTracking() | ||
| ``` | ||
|
|
||
| ### group | ||
| The group API call is how you associate an individual user with a group—be it a company, organization, account, project, team or whatever other crazy name you came up with for the same concept! This includes a unique group ID and any optional group traits you know about them like the company name industry, number of employees, etc. The traits option can include any information you might want to tie to the group, but when using any of the reserved group traits, you should make sure to only use them for their intended meaning. | ||
| Method signatures: | ||
| ```swift | ||
| func group(groupId: String) | ||
| func group<T: Codable>(groupId: String, traits: T?) | ||
| ``` | ||
|
|
||
| Example Usage: | ||
| ```swift | ||
| struct MyTraits: Codable { | ||
| let username: String | ||
| let email: String | ||
| let plan: String | ||
| } | ||
|
|
||
| // ... | ||
|
|
||
| analytics.group("user-123", MyTraits( | ||
| username: "MisterWhiskers", | ||
| email: "[email protected]", | ||
| plan: "premium")) | ||
| ``` | ||
|
|
||
| ### add | ||
| Add API allows you to add a plugin to the analytics timeline. It will return the plugin instance in | ||
| case you wish to store it for access later. | ||
|
|
||
| Method signature: | ||
| ```swift | ||
| @discardableResult func add(plugin: Plugin) -> Plugin | ||
| ``` | ||
|
|
||
| Example Usage: | ||
| ```swift | ||
| analytics.add(plugin: UIKitScreenTracking()) | ||
| ``` | ||
|
|
||
| ### find | ||
| Find a registered plugin from the analytics timeline. It will return the first plugin | ||
| of the specified type. | ||
|
|
||
| Method signature: | ||
| ```swift | ||
| func find<T: Plugin>(pluginType: T.Type) -> T? | ||
| ``` | ||
|
|
||
| Example Usage: | ||
| ```swift | ||
| let plugin = analytics.find(pluginType: SomePlugin.self) | ||
| ``` | ||
|
|
||
| ### remove | ||
| Remove a registered plugin from the analytics timeline. | ||
|
|
||
| Method signature: | ||
| ```swift | ||
| func remove(plugin: Plugin) | ||
| ``` | ||
|
|
||
| Example Usage: | ||
| ```swift | ||
| analytics.remove(plugin: somePlugin) | ||
| ``` | ||
|
|
||
| ### flush | ||
| Flushes the current queue of events. | ||
|
|
||
| Example Usage: | ||
| ```swift | ||
| analytics.flush() | ||
| ``` | ||
|
|
||
| ## Plugin Architecture | ||
| Our new plugin architecture enables you to modify/augment how the analytics client works completely. From modifying event payloads to changing analytics functionality, plugins are the easiest way to get things done. | ||
| Plugins are run through a timeline, which executes plugins in order of insertion based on their types. | ||
| We have the following [types] | ||
| - `before` _Executed before event processing begins_ | ||
| - `enrichment` _Executed as the first level of event processing_ | ||
| - `destination` _Executed as events begin to pass off to destinations_ | ||
| - `after` _Executed after all event processing is completed. This can be used to perform cleanup operations, etc_ | ||
| - `utility` _Executed only when called manually, such as Logging_ | ||
|
|
||
| ### Fundamentals | ||
| We have 3 types of basic plugins that you can use as a foundation for modifying functionality | ||
|
|
||
| - `Plugin` | ||
| The most trivial plugin interface that will act on any event payload going through the timeline. | ||
| For example if you wanted to add something to the context object of any event payload as an enrichment. | ||
| ```swift | ||
| class SomePlugin: Plugin { | ||
| let type: PluginType = .enrichment | ||
| let analytics: Analytics | ||
|
|
||
| init() { | ||
| } | ||
|
|
||
| override fun execute(event: BaseEvent): BaseEvent? { | ||
| var workingEvent = event | ||
| if var context = workingEvent?.context?.dictionaryValue { | ||
| context[keyPath: "foo.bar"] = 12 | ||
| workingEvent?.context = try? JSON(context) | ||
| } | ||
| return workingEvent | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| - `EventPlugin` | ||
| A plugin interface that will act only on specific event types. You can choose the event types by only overriding the event functions you want. | ||
| For example if you only wanted to act on `track` & `identify` events | ||
| ```swift | ||
| class SomePlugin: EventPlugin { | ||
| let type: PluginType = .enrichment | ||
| let analytics: Analytics | ||
|
|
||
| init() { | ||
| } | ||
|
|
||
| func identify(event: IdentifyEvent) -> IdentifyEvent? { | ||
| // code to modify identify event | ||
| return event | ||
| } | ||
|
|
||
| func track(event: TrackEvent) -> TrackEvent? { | ||
| // code to modify track event | ||
| return event | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| - `DestinationPlugin` | ||
| A plugin interface most commonly used for device-mode destinations. This plugin contains an internal timeline that follows the same process as the analytics timeline, | ||
| allowing you to modify/augment how events reach the particular destination. | ||
| For example if you wanted to implement a device mode destination plugin for AppsFlyer | ||
| ```swift | ||
| internal struct AppsFlyerSettings: Codable { | ||
| let appsFlyerDevKey: String | ||
| let appleAppID: String | ||
| let trackAttributionData: Bool? | ||
| } | ||
|
|
||
| @objc | ||
| class AppsFlyerDestination: UIResponder, DestinationPlugin, UserActivities, RemoteNotifications { | ||
|
|
||
| let timeline: Timeline = Timeline() | ||
| let type: PluginType = .destination | ||
| let key: String = "AppsFlyer" | ||
| var analytics: Analytics? | ||
|
|
||
| internal var settings: AppsFlyerSettings? = nil | ||
|
|
||
| init() { | ||
| } | ||
|
|
||
| public func update(settings: Settings, type: UpdateType) { | ||
| if type == .initial { | ||
| // AppsFlyerLib is a singleton, we only want to set it up once. | ||
| guard let settings: AppsFlyerSettings = settings.integrationSettings(key: self.name) else {return} | ||
| self.settings = settings | ||
|
|
||
| AppsFlyerLib.shared().appsFlyerDevKey = settings.appsFlyerDevKey | ||
| AppsFlyerLib.shared().appleAppID = settings.appleAppID | ||
| AppsFlyerLib.shared().isDebug = true | ||
| AppsFlyerLib.shared().deepLinkDelegate = self | ||
|
|
||
| analytics?.track(name: "AppsFlyer Loaded") | ||
| } | ||
|
|
||
| // additional update logic | ||
| } | ||
|
|
||
| // ... | ||
|
|
||
| analytics.add(plugin: AppsFlyerPlugin(name: "AppsFlyer")) | ||
| analytics.track("AppsFlyer Event") | ||
| ``` | ||
|
|
||
| ### Advanced concepts | ||
| - `update(settings:type:)` | ||
| Use this function to react to any settings updates. This will be implicitly called when settings are updated. | ||
| - OS Lifecycle hooks | ||
| Plugins can also hook into lifecycle events by conforming to the platform appropriate protocol. These functions will get called implicitly as the lifecycle events are processed. | ||
| `iOSLifecycleEvents` | ||
| `macOSLifecycleEvents` | ||
| `watchOSLifecycleEvents` | ||
| `LinuxLifecycleEvents` | ||
| ## Contributing | ||
|
|
||
| See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow. | ||
|
|
||
| ## Integrating with Segment | ||
|
|
||
| Interested in integrating your service with us? Check out our [Partners page](https://segment.com/partners/) for more details. | ||
|
|
||
| ## Code of Conduct | ||
|
|
||
| Before contributing, please also see our [code of conduct](CODE_OF_CONDUCT.md). | ||
|
|
||
| ## License | ||
|
|
||
| ``` | ||
| MIT License | ||
|
|
||
| Copyright (c) 2021 Segment | ||
|
|
@@ -360,3 +73,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| ``` | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is incorrect. Not sure where
Propertiesis coming from so hard to discuss how to fix.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's also mentioning Kotlin in the Swift repo. Examples of this can be found in Stacy's docs.