Skip to content

feat: integrate Clickstream Swift SDK #7

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 2 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ License: [Apache-2.0](https://github.com/joelkanyi/Joomia/blob/main/LICENSE)
## Swift SDK Example
iOS example app **Shopping** App is forked from https://github.com/Djallil14/SwiftUI-FakeShopping-App. To get started with the iOS example, refer to the [iOS Example README](ios/README.md).

You can refer this [PR](https://github.com/aws-samples/clickstream-sdk-samples/pull/7/files) to learn how to integrate Clickstream Swift SDK.

More references:

[Clickstream Swift SDK Repositry](https://github.com/awslabs/clickstream-swift)
Expand Down
10 changes: 10 additions & 0 deletions ios/ModerneShopping/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,22 @@
//
// Created by Zhu, Xiaowei on 2023/5/24.
//
import Clickstream
import UIKit

class AppDelegate: NSObject, UIApplicationDelegate {
public static var allEventNumber: Int = 0
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
AppDelegate.allEventNumber = UserDefaults.standard.integer(forKey: "allEventNumber")
/// Initialize Clickstream SDK
do {
try ClickstreamAnalytics.initSDK()
let configuration = try ClickstreamAnalytics.getClickstreamConfiguration()
configuration.isLogEvents = true
configuration.isTrackScreenViewEvents = false
} catch {
print("Failed to initialize ClickstreamAnalytics with \(error)")
}
return true
}

Expand Down
18 changes: 18 additions & 0 deletions ios/ModerneShopping/TestClickstreamApi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// TestClickstreamApi.h
// ModerneShopping
//
// Created by Zhu, Xiaowei on 2023/12/18.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface TestClickstreamApi : NSObject

- (void)testClickstreamApi;

@end

NS_ASSUME_NONNULL_END
40 changes: 40 additions & 0 deletions ios/ModerneShopping/TestClickstreamApi.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// TestClickstreamApi.m
// ModerneShopping
//
// Created by Zhu, Xiaowei on 2023/12/18.
//

#import <Foundation/Foundation.h>
#import "TestClickstreamApi.h"
@import Clickstream;


@implementation TestClickstreamApi

/// This method for show how to invoke Clickstream Swift API from Objective-C
-(void) testClickstreamApi{
/// Initialize Clickstream SDK in Objective-C
NSError *error = nil;
[ClickstreamObjc initSDKAndReturnError:&error];
if (error) {
NSLog(@"Fail to initialize ClickstreamAnalytics: %@", error.localizedDescription);
}

/// Record an event with item
NSDictionary *attributes = @{
ClickstreamItemKey.ITEM_ID: @"123",
@"event_category": @"recommended"
};
NSDictionary *item_book = @{
ClickstreamItemKey.ITEM_ID: @123,
ClickstreamItemKey.ITEM_NAME: @"Nature",
ClickstreamItemKey.ITEM_CATEGORY: @"book",
ClickstreamItemKey.PRICE: @99.9,
@"book_publisher": @"Nature Research"
};
[ClickstreamObjc recordEvent:@"view_item" :attributes: @[item_book]];
};
@end


15 changes: 15 additions & 0 deletions ios/ModerneShopping/ViewModel/CartViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Djallil Elkebir on 2021-09-03.
//

import Clickstream
import SwiftUI

class CartViewModel: ObservableObject {
Expand All @@ -18,6 +19,13 @@ class CartViewModel: ObservableObject {
/// - addedProduct: product we want to add
/// - quantity: quantity of product we want to add
func addToCart(addedProduct: Product, quantity: Int) {
let attributes: ClickstreamAttribute = [
"product_id": addedProduct.id,
"product_title": addedProduct.title,
"product_price": addedProduct.price,
"product_category": addedProduct.category,
]
ClickstreamAnalytics.recordEvent("add_to_cart", attributes)
AppDelegate.addEvent()

let products = cartProductDic.map(\.key)
Expand Down Expand Up @@ -60,6 +68,13 @@ class CartViewModel: ObservableObject {
}

func removeFromCart(toRemove: Product) {
let attributes: ClickstreamAttribute = [
"product_id": toRemove.id,
"product_title": toRemove.title,
"product_price": toRemove.price,
"product_category": toRemove.category,
]
ClickstreamAnalytics.recordEvent("cart_delete", attributes)
AppDelegate.addEvent()
cartProductDic.removeValue(forKey: toRemove)
}
Expand Down
12 changes: 12 additions & 0 deletions ios/ModerneShopping/ViewModel/UserViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Djallil Elkebir on 2021-09-06.
//

import Clickstream
import SwiftUI

class UserViewModel: ObservableObject {
Expand Down Expand Up @@ -43,6 +44,16 @@ class UserViewModel: ObservableObject {
self.isLoading = false
if let userAPIResults: UserAPIResults = self.user {
let user = userAPIResults.results[0]
ClickstreamAnalytics.setUserId(user.login.uuid)
let userAttribute = [
"_user_name": user.name.first + " " + user.name.last,
"_user_email": user.email,
"_user_gender": user.gender,
"_user_country": user.location.country,
"_user_city": user.location.city
]
ClickstreamAnalytics.addUserAttributes(userAttribute)
ClickstreamAnalytics.recordEvent("user_login")
AppDelegate.addEvent()
}
}
Expand All @@ -65,6 +76,7 @@ class UserViewModel: ObservableObject {
self.user = nil
self.isLoading = false
}
ClickstreamAnalytics.setUserId(nil)
}

/// validate if the username respect our conditions
Expand Down
3 changes: 3 additions & 0 deletions ios/ModerneShopping/Views/CartViews/CartView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Djallil Elkebir on 2021-09-02.
//

import Clickstream
import SwiftUI

struct CartView: View {
Expand Down Expand Up @@ -40,6 +41,7 @@ struct CartView: View {
}
Text("Total: \(cartProducts.totalPrice.format(f: ".2"))$")
Button(action: {
ClickstreamAnalytics.recordEvent("check_out_click")
AppDelegate.addEvent()
withAnimation { cartProducts.showShowcaseSheet.toggle()
}
Expand Down Expand Up @@ -76,6 +78,7 @@ struct CartView: View {
var trailingItem: some View {
Button(action: { withAnimation {
showDelete.toggle()
ClickstreamAnalytics.recordEvent("cart_show_delete_click")
AppDelegate.addEvent()
}}) {
Image(systemName: "slider.horizontal.3")
Expand Down
6 changes: 6 additions & 0 deletions ios/ModerneShopping/Views/CartViews/CheckOutView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Djallil Elkebir on 2021-09-07.
//

import Clickstream
import SwiftUI

struct CheckOutView: View {
Expand Down Expand Up @@ -63,6 +64,11 @@ struct CheckOutView: View {
.font(.caption)
Button(action: {
print("Paying ...")
let attribute: ClickstreamAttribute = [
"final_price": price,
"product_count": products.count,
]
ClickstreamAnalytics.recordEvent("purchase", attribute)
AppDelegate.addEvent()
}) {
Text("Click Here to Pay").bold()
Expand Down
7 changes: 7 additions & 0 deletions ios/ModerneShopping/Views/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Djallil Elkebir on 2021-09-02.
//

import Clickstream
import SwiftUI

struct HomeView: View {
Expand All @@ -25,6 +26,10 @@ struct HomeView: View {
.padding()
CustomPicker(choosenCategory: $pickedCategory)
.onChange(of: pickedCategory, perform: { _ in
let attribute: ClickstreamAttribute = [
"category_name": pickedCategory.rawValue
]
ClickstreamAnalytics.recordEvent("category_click", attribute)
AppDelegate.addEvent()
DispatchQueue.main.async {
productsList.loadProducts(with: pickedCategory)
Expand Down Expand Up @@ -58,6 +63,7 @@ struct HomeView: View {
}.navigationBarTitleDisplayMode(.large)
.navigationBarItems(
leading: NavigationLink(destination: ProfilView().environmentObject(user).onAppear {
ClickstreamAnalytics.recordEvent("home_profile_click")
AppDelegate.addEvent()
}) {
leadingBarItem(user: user.user?.results[0])
Expand All @@ -79,6 +85,7 @@ struct TrailingBarItem: View {
@EnvironmentObject var cart: CartViewModel
var body: some View {
NavigationLink(destination: CartView(cartProducts: cart).onAppear {
ClickstreamAnalytics.recordEvent("home_cart_click")
AppDelegate.addEvent()
}) {
Image(systemName: "cart")
Expand Down
13 changes: 13 additions & 0 deletions ios/ModerneShopping/Views/MainView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import AdSupport
import AppTrackingTransparency
import Clickstream
import SwiftUI

struct MainView: View {
Expand All @@ -20,6 +21,10 @@ struct MainView: View {
Image(systemName: "house")
Text("Home")
}.onAppear {
let attribute: ClickstreamAttribute = [
"tab_name": "home_tab"
]
ClickstreamAnalytics.recordEvent("view_home", attribute)
AppDelegate.addEvent()
}
CartView(cartProducts: cartItems)
Expand All @@ -28,6 +33,10 @@ struct MainView: View {
Image(systemName: "cart")
Text("Cart")
}.onAppear {
let attribute: ClickstreamAttribute = [
"tab_name": "cart_tab"
]
ClickstreamAnalytics.recordEvent("view_cart", attribute)
AppDelegate.addEvent()
}
ProfilView()
Expand All @@ -36,6 +45,10 @@ struct MainView: View {
Image(systemName: "person")
Text("Profile")
}.onAppear {
let attribute: ClickstreamAttribute = [
"tab_name": "profile_tab"
]
ClickstreamAnalytics.recordEvent("view_profile", attribute)
AppDelegate.addEvent()
}
}
Expand Down
13 changes: 13 additions & 0 deletions ios/ModerneShopping/Views/ProductViews/ProductCarouselCard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Djallil Elkebir on 2021-09-08.
//

import Clickstream
import SwiftUI

struct ProductCarouselCard: View {
Expand Down Expand Up @@ -37,6 +38,18 @@ struct ProductCarouselCard: View {
.cornerRadius(18)
.shadow(color: .darkText.opacity(0.1), radius: 4, x: 1, y: 2).onAppear {
if !isViewCovered(in: geometry) {
let attributes: ClickstreamAttribute = [
ClickstreamAnalytics.Item.ITEM_ID: "123",
ClickstreamAnalytics.Item.CURRENCY: "USD",
]
let item_product: ClickstreamAttribute = [
ClickstreamAnalytics.Item.ITEM_ID: product.id,
ClickstreamAnalytics.Item.ITEM_NAME: product.title,
ClickstreamAnalytics.Item.PRICE: product.price,
ClickstreamAnalytics.Item.ITEM_CATEGORY: product.category,
"place_of_origin": "USA",
]
ClickstreamAnalytics.recordEvent("product_exposure", attributes, [item_product])
AppDelegate.addEvent()
}
}
Expand Down
13 changes: 13 additions & 0 deletions ios/ModerneShopping/Views/ProductViews/ProductListItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Djallil Elkebir on 2021-09-02.
//

import Clickstream
import SwiftUI

struct ProductListItem: View {
Expand All @@ -28,6 +29,18 @@ struct ProductListItem: View {
.offset(y: 3)
}
}.padding(8).onAppear {
let attributes: ClickstreamAttribute = [
ClickstreamAnalytics.Item.ITEM_ID: "123",
ClickstreamAnalytics.Item.CURRENCY: "USD",
]
let item_product: ClickstreamAttribute = [
ClickstreamAnalytics.Item.ITEM_ID: product.id,
ClickstreamAnalytics.Item.ITEM_NAME: product.title,
ClickstreamAnalytics.Item.PRICE: product.price,
ClickstreamAnalytics.Item.ITEM_CATEGORY: product.category,
"place_of_origin": "USA",
]
ClickstreamAnalytics.recordEvent("product_exposure", attributes, [item_product])
AppDelegate.addEvent()
}
}
Expand Down
8 changes: 8 additions & 0 deletions ios/ModerneShopping/Views/ProductViews/ProductView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Djallil Elkebir on 2021-09-01.
//

import Clickstream
import SwiftUI

struct ProductView: View {
Expand Down Expand Up @@ -80,6 +81,13 @@ struct ProductView: View {
}
}.navigationBarTitleDisplayMode(.large)
.onAppear {
let attributes: ClickstreamAttribute = [
"product_id": product.id,
"product_title": product.title,
"product_price": product.price,
"product_category": product.category,
]
ClickstreamAnalytics.recordEvent("product_click", attributes)
AppDelegate.addEvent()
ProductView.isShow = true
}.onDisappear {
Expand Down
4 changes: 4 additions & 0 deletions ios/ModerneShopping/Views/ProfilViews/ProfilButtons.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Djallil Elkebir on 2021-09-06.
//

import Clickstream
import SwiftUI

struct ProfilButtons: View {
Expand All @@ -24,6 +25,7 @@ struct ProfilButtons: View {
.frame(maxWidth: .infinity, maxHeight: .infinity)
.foregroundColor(.black)
}.onAppear {
ClickstreamAnalytics.recordEvent("update_account_click")
AppDelegate.addEvent()
}
}, isActive: $isAccountActive) {
Expand All @@ -46,6 +48,7 @@ struct ProfilButtons: View {
.frame(maxWidth: .infinity, maxHeight: .infinity)
.foregroundColor(.black)
}.onAppear {
ClickstreamAnalytics.recordEvent("history_click")
AppDelegate.addEvent()
}
}, isActive: $isHistoryActive) {
Expand All @@ -67,6 +70,7 @@ struct ProfilButtons: View {
.frame(maxWidth: .infinity, maxHeight: .infinity)
.foregroundColor(.black)
}.onAppear {
ClickstreamAnalytics.recordEvent("orders_click")
AppDelegate.addEvent()
}
}, isActive: $isOrdersActive) {
Expand Down
Loading