GithubHelp home page GithubHelp logo

awslabs / clickstream-swift Goto Github PK

View Code? Open in Web Editor NEW
13.0 4.0 1.0 627 KB

Swift SDK for Clickstream Analytics on AWS

Home Page: https://aws.amazon.com/solutions/implementations/clickstream-analytics-on-aws/

License: Apache License 2.0

Swift 93.28% Shell 0.05% Python 6.67%
analytics aws clickstream sdk-swift aws-clickstream-solution aws-solutions ios

clickstream-swift's Introduction

AWS Solution Clickstream Analytics SDK for Swift

Introduction

Clickstream Swift SDK can help you easily collect and report in-app events from iOS devices to AWS. This SDK is part of an AWS solution - Clickstream Analytics on AWS, which provisions data pipeline to ingest and process event data into AWS services such as S3, Redshift.

The SDK relies on the Amplify for Swift Core Library and is developed according to the Amplify Swift SDK plug-in specification. In addition, we've added features that automatically collect common user events and attributes (e.g., screen view, first open) to simplify data collection for users.

Visit our Documentation site and to learn more about Clickstream Swift SDK.

Platform Support

The Clickstream SDK supports iOS 13+.

API Documentation

Integrate SDK

Clickstream requires Xcode 13.4 or higher to build.

1.Add Package

We use Swift Package Manager to distribute Clickstream Swift SDK, open your project in Xcode and select File > Add Pckages.

Enter the Clickstream Library for Swift GitHub repo URL (https://github.com/awslabs/clickstream-swift) into the search bar, you'll see the Clickstream Library for Swift repository rules for which version of Clickstream you want Swift Package Manager to install. Choose Up to Next Major Version, then click Add Package, make the Clickstream product checked as default, and click Add Package again.

2.Parameter configuration

Downlod your amplifyconfiguration.json file from your Clickstream solution control plane, and paste it to your project root folder:

the json file will be as follows:

{
  "analytics": {
    "plugins": {
      "awsClickstreamPlugin ": {
        "appId": "appId",
        "endpoint": "https://example.com/collect",
        "isCompressEvents": true,
        "autoFlushEventsInterval": 10000,
        "isTrackAppExceptionEvents": false
      }
    }
  }
}

Your appId and endpoint are already set up in it, here's an explanation of each property:

  • appId: the app id of your project in control plane.
  • endpoint: the endpoint url you will upload the event to AWS server.
  • isCompressEvents: whether to compress event content when uploading events, default is true
  • autoFlushEventsInterval: event sending interval, the default is 10s
  • isTrackAppExceptionEvents: whether auto track exception event in app, default is false

3.Initialize the SDK

Once you have configured the parameters, you need to initialize it in your app delegate's application(_:didFinishLaunchingWithOptions:) lifecycle method:

3.1 Initialize the SDK with default configuration

import Clickstream
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    do {
        try ClickstreamAnalytics.initSDK()
    } catch {
        assertionFailure("Fail to initialize ClickstreamAnalytics: \(error)")
    }
    return true
}

3.2 Initialize the SDK with global attributes and custom configuration

The following example code shows how to add traffic source fields as global attributes when initializing the SDK.

import Clickstream
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    do {
        let configuration = ClickstreamConfiguration()
            .withAppId("your appId")
            .withEndpoint("https://example.com/collect")
            .withLogEvents(true)
            .withInitialGlobalAttributes([
                ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_SOURCE: "amazon",
                ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_MEDIUM: "cpc",
                ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN: "summer_promotion",
                ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CAMPAIGN_ID: "summer_promotion_01",
                ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_TERM: "running_shoes",
                ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CONTENT: "banner_ad_1",
                ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID: "amazon_ad_123",
                ClickstreamAnalytics.Attr.TRAFFIC_SOURCE_CLID_PLATFORM: "amazon_ads",
                ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL: "App Store"
            ])
        try ClickstreamAnalytics.initSDK(configuration)
    } catch {
        assertionFailure("Fail to initialize ClickstreamAnalytics: \(error)")
    }
    return true
}

By default, we will use the configurations in amplifyconfiguration.json file. If you add a custom configuration, the added configuration items will override the default values.

You can also add all the configuration parameters you need in the initSDK method without using the amplifyconfiguration.json file.

3.3 SwiftUI configuration

If your project is developed with SwiftUI, you need to create an application delegate and attach it to your App through UIApplicationDelegateAdaptor.

@main
struct YourApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    var body: some Scene {
        WindowGroup {
            YourView()
        }
    }
}

Clickstream Swift SDK depends on method swizzling to automatically record screen views. SwiftUI apps must record screen view events manually, and disable automatic tracking of screen view events by setting configuration.withTrackScreenViewEvents(false) when the SDK is initialized.

4. Update Configuration

import Clickstream

// configure the sdk after initialize.
do {
    let configuration = try ClickstreamAnalytics.getClickstreamConfiguration()
    configuration.withAppId("your appId")
        .withEndpoint("https://example.com/collect")
        .withLogEvents(true)
        .withCompressEvents(true)
        .withSessionTimeoutDuration(1800000)
        .withTrackAppExceptionEvents(true)
        .withTrackScreenViewEvents(true)
        .withTrackUserEngagementEvents(true)
} catch {
    print("Failed to config ClickstreamAnalytics: \(error)")
}

note: this configuation will override the default configuation in amplifyconfiguration.json file

Start using

Recored event.

Add the following code where you need to complete the event report.

import Clickstream

let attributes: ClickstreamAttribute = [
    "Channel": "apple",
    "Successful": true,
    "ProcessDuration": 12.33,
    "UserAge": 20,
]
ClickstreamAnalytics.recordEvent("testEvent", attributes)

// for record an event with event name
ClickstreamAnalytics.recordEvent("button_click")

Record event with items

You can add the following code to log an event with an item.

Note: Only pipelines from version 1.1+ can handle items with custom attribute.

import Clickstream

let attributes: ClickstreamAttribute = [
    ClickstreamAnalytics.Item.ITEM_ID: "123",
    ClickstreamAnalytics.Item.CURRENCY: "USD",
    "event_category": "recommended"
]

let item_book: ClickstreamAttribute = [
    ClickstreamAnalytics.Item.ITEM_ID: 123,
    ClickstreamAnalytics.Item.ITEM_NAME: "Nature",
    ClickstreamAnalytics.Item.ITEM_CATEGORY: "book",
    ClickstreamAnalytics.Item.PRICE: 99.9,
    "book_publisher": "Nature Research"
]
ClickstreamAnalytics.recordEvent("view_item", attributes, [item_book])

Record Screen View events manually

By default, SDK will automatically track the preset _screen_view event when ViewController triggers viewDidAppear.

You can also manually record screen view events whether or not automatic screen view tracking is enabled, add the following code to record a screen view event with two attributes.

  • SCREEN_NAME Required. Your screen's name.
  • SCREEN_UNIQUE_ID Optional. Set the hashValue of your ViewController or UIView. If you do not set, SDK will set a default value based on the current ViewController's hashValue.
import Clickstream

ClickstreamAnalytics.recordEvent(ClickstreamAnalytics.EventName.SCREEN_VIEW, [
    ClickstreamAnalytics.Attr.SCREEN_NAME: "HomeView",
    ClickstreamAnalytics.Attr.SCREEN_UNIQUE_ID: homeView.hashValue
])

Add global attribute

import Clickstream

let globalAttribute: ClickstreamAttribute = [
    ClickstreamAnalytics.Attr.APP_INSTALL_CHANNEL: "apple",
    "class": 6,
    "level": 5.1,
    "isOpenNotification": true,
]
ClickstreamAnalytics.addGlobalAttributes(globalAttribute)

// for delete an global attribute
ClickstreamAnalytics.deleteGlobalAttributes("level")

Login and logout

import Clickstream

// when user login usccess.
ClickstreamAnalytics.setUserId("userId")

// when user logout
ClickstreamAnalytics.setUserId(nil)

When we log into another user, we will clear the before user's user attributes, after setUserId() you need to add new user's attribute.

Add user attribute

import Clickstream

let userAttributes : ClickstreamAttribute=[
    "_user_age": 21,
    "_user_name": "carl"
]
ClickstreamAnalytics.addUserAttributes(userAttributes)

Current login user‘s attributes will be cached in disk, so the next time app launch you don't need to set all user's attribute again, of course you can update the current user's attribute when it changes.

Log the event json in debug mode

import Clickstream

// log the event in debug mode.
do {
    var configuration = try ClickstreamAnalytics.getClickstreamConfiguration()
    configuration.isLogEvents = true
} catch {
    print("Failed to config ClickstreamAnalytics: \(error)")
}

After config configuration.isLogEvents = true and when you record an event, you can see the event json at your Xcode log pannel by filter EventRecorder.

Send event immediately

import Clickstream
// for send event immediately.
ClickstreamAnalytics.flushEvents()

Disable SDK

You can disable the SDK in the scenario you need. After disabling the SDK, the SDK will not handle the logging and sending of any events. Of course you can enable the SDK when you need to continue logging events.

import Clickstream

// disable SDK
ClickstreamAnalytics.disable()

// enable SDK
ClickstreamAnalytics.enable()

How to build&test locally

Config your code format

Install swiftformat plugin in your Xcode, and config shortcut for code format.

Config your code lint

Install swiftlint, and execute the below command at the project root folder:

swiftlint

Build

Open an termial window, at the root project folder to execute:

swift build

Test

swift test

Security

See CONTRIBUTING for more information.

License

This library is licensed under Apache 2.0 License.

clickstream-swift's People

Contributors

amazon-auto avatar aws-solution-clickstream-analytics avatar zhu-xiaowei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

flowgpt

clickstream-swift's Issues

App Launch Crash

Describe the bug

when the app launch, someTimes might crash

Steps To Reproduce

Not a crash that always occurs

Expected behavior

app launch and no crash

Clickstream-Swift Version

0.9.2

Swift version

5.0

Xcode version

15.1

Relevant log output

Crashed: software.aws.solution.Clickstream.SessionClientQueue
0  gomerry                        0x7ecf94 AutoRecordEventClient.handleAppStart() + 79 (Event.swift:79)
1  gomerry                        0x7fc3cc SessionClient.handleAppEnterForeground() + 63 (SessionClient.swift:63)
2  gomerry                        0x7fc068 closure #1 in closure #1 in SessionClient.startActivityTracking() + 79 (SessionClient.swift:79)
3  gomerry                        0x7fca5c partial apply for closure #1 in closure #1 in SessionClient.startActivityTracking() + 4375267932 (<compiler-generated>:4375267932)
4  ???                            0x195483900 (Missing)
5  ???                            0x19548ac88 (Missing)
6  ???                            0x195484c08 (Missing)
7  ???                            0x195484d1c (Missing)
8  ???                            0x1954846e8 (Missing)
9  ???                            0x1942a9fdc (Missing)
10 ???                            0x1942b9574 (Missing)
11 ???                            0x19548558c (Missing)
12 ???                            0x195483d50 (Missing)
13 ???                            0x1954858a8 (Missing)
14 gomerry                        0x7fbff4 closure #1 in SessionClient.startActivityTracking() + 35 (SessionClient.swift:35)
15 gomerry                        0x7e3d90 partial apply for thunk for @escaping @callee_guaranteed (@unowned ApplicationState) -> () + 4375166352 (<compiler-generated>:4375166352)
16 ???                            0x1954a5754 (Missing)
17 ???                            0x1954a50a8 (Missing)
18 ???                            0x1954a93f4 (Missing)
19 ???                            0x1954a2c58 (Missing)
20 ???                            0x1954c2d08 (Missing)
21 ???                            0x1954b29b8 (Missing)
22 ???                            0x19552e640 (Missing)
23 ???                            0x19549e22c (Missing)
24 gomerry                        0x7e3a0c specialized closure #1 in StateMachine.process(_:) + 42 (StateMachine.swift:42)
25 gomerry                        0x7e3d00 partial apply for thunk for @callee_guaranteed () -> () + 4375166208 (<compiler-generated>:4375166208)
26 gomerry                        0x7e3a40 thunk for @escaping @callee_guaranteed () -> () + 4375165504 (<compiler-generated>:4375165504)
27 ???                            0x1942a9fdc (Missing)
28 ???                            0x1942b9574 (Missing)
29 gomerry                        0x7e38ac specialized StateMachine.process(_:) + 39 (StateMachine.swift:39)
30 gomerry                        0x7e2f50 ActivityTracker.handleApplicationStateChange(_:) + 125 (ActivityTracker.swift:125)
31 gomerry                        0x7e30d8 @objc ActivityTracker.handleApplicationStateChange(_:) + 4375163096 (<compiler-generated>:4375163096)
32 ???                            0x18cd0b404 (Missing)
33 ???                            0x18cdb2474 (Missing)
34 ???                            0x18cd95724 (Missing)
35 ???                            0x18cd1fa08 (Missing)
36 ???                            0x187194ffc (Missing)
37 ???                            0x18f035cf0 (Missing)
38 ???                            0x18f03582c (Missing)
39 ???                            0x18ef2f600 (Missing)
40 ???                            0x18f271918 (Missing)
41 ???                            0x18f121fa4 (Missing)
42 ???                            0x18f121dcc (Missing)
43 ???                            0x18f12197c (Missing)
44 ???                            0x18f121848 (Missing)
45 ???                            0x18f803fa8 (Missing)
46 ???                            0x18f89cf98 (Missing)
47 ???                            0x18efcd958 (Missing)
48 ???                            0x18f4407a8 (Missing)
49 ???                            0x18f0a00b8 (Missing)
50 ???                            0x18f09ff28 (Missing)
51 ???                            0x18f09f47c (Missing)
52 ???                            0x18f09f208 (Missing)
53 ???                            0x1a28ed500 (Missing)
54 ???                            0x1a292c51c (Missing)
55 ???                            0x1a28f1294 (Missing)
56 ???                            0x1a292c154 (Missing)
57 ???                            0x1942a9fdc (Missing)
58 ???                            0x1942ada5c (Missing)
59 ???                            0x1a28fb3b0 (Missing)
60 ???                            0x1a28faf4c (Missing)
61 ???                            0x1a28fd72c (Missing)
62 ???                            0x18cda9f54 (Missing)
63 ???                            0x18cdb632c (Missing)
64 ???                            0x18cd3a270 (Missing)
65 ???                            0x18cd4fba8 (Missing)
66 ???                            0x18cd54ed4 (Missing)
67 ???                            0x1c57b1368 (Missing)
68 ???                            0x18f2333d0 (Missing)
69 ???                            0x18f233034 (Missing)
70 gomerry                        0xa334 main + 14 (main.swift:14)
71 ???                            0x1ab3ac960 (Missing)

Is this a regression?

No

Regression additional context

No response

Device

iPhone 7Plus iPhone XR eg

iOS Version

iOS 15 ~ iOS 17

Specific to simulators

No response

Additional context

No response

user_login event user_pseudo_id is incorrect

Describe the bug

The user_login event data user_pseudo_id is incorrect

image

Steps To Reproduce

Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

Expected behavior

.

Clickstream-Swift Version

0.5.0

Swift version

Xcode version

Relevant log output

<details>
<summary>Log Messages</summary>


INSERT LOG MESSAGES HERE
```

Is this a regression?

Yes

Regression additional context

No response

Device

iPhone 12

iOS Version

iOS 11

Specific to simulators

No response

Additional context

No response

flushEvents cause Swift App crash

Describe the bug

app crash by chance, stack shows it crash in flushEvents.

Steps To Reproduce

.

Expected behavior

do not crash

Clickstream-Swift Version

0.4.2

Swift version

5.8

Xcode version

14.3.1

Relevant log output

Crashed: com.apple.root.background-qos
0  libswiftCore.dylib             0x402ca4 swift_unknownObjectRetain + 20
1  libswiftNetwork.dylib          0x391b0 initializeWithCopy for NWPath + 1292
2  libswiftNetwork.dylib          0x3ab60 outlined init with copy of NWPath + 88
3  libswiftNetwork.dylib          0x36ad0 NWPathMonitor.currentPath.getter + 88
4  gomerry                        0x236ed4 AWSClickstreamPlugin.flushEvents() + 22 (NetworkMonitor.swift:22)
5  gomerry                        0x239898 closure #2 in AWSClickstreamPlugin.configure(using:) + 60 (AWSClickstreamPlugin+Configure.swift:60)
6  gomerry                        0x257348 thunk for @escaping @callee_guaranteed () -> () + 4312625992 (<compiler-generated>:4312625992)
7  libdispatch.dylib              0x3eac _dispatch_client_callout + 20
8  libdispatch.dylib              0x7330 _dispatch_continuation_pop + 504
9  libdispatch.dylib              0x1a908 _dispatch_source_invoke + 1588
10 libdispatch.dylib              0x15944 _dispatch_root_queue_drain + 396
11 libdispatch.dylib              0x16158 _dispatch_worker_thread2 + 164
12 libsystem_pthread.dylib        0xda0 _pthread_wqthread + 228
13 libsystem_pthread.dylib        0xb7c start_wqthread + 8

Is this a regression?

No

Regression additional context

No response

Device

iPhone 11

iOS Version

16.5.1

Specific to simulators

No response

Additional context

No response

fail to build API doc workflow

Describe the bug

see detail from workflow log,

https://github.com/awslabs/clickstream-swift/actions/runs/5067737308/jobs/9099149850

Steps To Reproduce

see above

Expected behavior

Successfully build the API doc.

Also run the jazzy in every PR, only push to gh-pages when it's main branch

Clickstream-Swift Version

main

Swift version

n/a

Xcode version

n/a

Relevant log output

<details>
<summary>Log Messages</summary>


INSERT LOG MESSAGES HERE
```

Is this a regression?

Yes

Regression additional context

No response

Device

n/a

iOS Version

n/a

Specific to simulators

No response

Additional context

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.