Skip to content

Commit 2519a39

Browse files
authored
feat: allow configuring whitelist events to handle (#8)
1 parent bebf22e commit 2519a39

File tree

6 files changed

+75
-10
lines changed

6 files changed

+75
-10
lines changed

ArchDiagram.png

34.4 KB
Loading

DLAnalytics/Impl/AnalyticsManager.swift

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ final class AnalyticsManager {
3838

3939
// MARK: - CombineEvent
4040
public struct CombineEvent: AnalyticsEvent {
41+
public private(set) var type: String
4142
public var name: String
4243
public var payload: [String: Any]
4344
}
@@ -79,10 +80,36 @@ extension AnalyticsManager: AnalyticsService {
7980
}
8081

8182
services.forEach {
82-
var combinedPayload = userProperty
83-
combinedPayload.merge(dict: event.payload)
84-
let combinedEvent = CombineEvent(name: event.name, payload: combinedPayload)
85-
$0.send(event: combinedEvent)
83+
if $0.allowEvents.contains(event.type) {
84+
let combineEvent = buildCombineEvent(event)
85+
$0.send(event: combineEvent)
86+
}
8687
}
8788
}
89+
90+
/// Reset all data related to the user e.g user logout
91+
func send(event: AnalyticsEvent, from viewController: ViewController) {
92+
var services = [AnalyticsService]()
93+
readWriteLock.read {
94+
services = self.analyticsServices
95+
}
96+
97+
services.forEach {
98+
if $0.allowEvents.isEmpty || $0.allowEvents.contains(event.type) {
99+
let combineEvent = buildCombineEvent(event)
100+
$0.send(event: combineEvent, from: viewController)
101+
}
102+
}
103+
}
104+
105+
/// Combine event form share event with the current event
106+
private func buildCombineEvent(_ event: AnalyticsEvent) -> CombineEvent {
107+
var combinedPayload = userProperty
108+
combinedPayload.merge(dict: event.payload)
109+
return CombineEvent(
110+
type: event.type,
111+
name: event.name,
112+
payload: combinedPayload
113+
)
114+
}
88115
}

DLAnalytics/Model/Analytics.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,9 @@ public enum Analytics {
3333
public static func reset() {
3434
AnalyticsManager.sharedInstance.reset()
3535
}
36+
37+
/// Support some cases want to track from or present some screens inside specific consumer (Analytics services)
38+
public static func send(event: AnalyticsEvent, from viewController: ViewController) {
39+
AnalyticsManager.sharedInstance.send(event: event, from: viewController)
40+
}
3641
}

DLAnalytics/Protocol/AnalyticsEvent.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
import Foundation
1010

1111
public protocol AnalyticsEvent {
12+
var type: String { get }
1213
var name: String { get }
1314
var payload: [String: Any] { get }
1415
}
16+
17+
public extension AnalyticsEvent {
18+
var type: String { "\(Self.self)" }
19+
}

DLAnalytics/Protocol/AnalyticsService.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,18 @@
77
//
88

99
import Foundation
10+
#if os(iOS)
11+
import UIKit
12+
public typealias ViewController = UIViewController
13+
#elseif os(macOS)
14+
import AppKit
15+
public typealias ViewController = NSViewController
16+
#endif
1017

1118
public protocol AnalyticsService {
19+
/// Whitelist events handle by the service. Handle all events as default if it does not specify
20+
var allowEvents: Set<String> { get }
21+
1222
/// To support identify the user we need to help set these properties as global properties
1323
func setUserIdentifyProperty(_ property: [String: String])
1424

@@ -17,4 +27,13 @@ public protocol AnalyticsService {
1727

1828
/// Send an event to Analytics
1929
func send(event: AnalyticsEvent)
30+
31+
/// Send an event to Analytics from a ViewController
32+
func send(event: AnalyticsEvent, from viewController: ViewController)
33+
}
34+
35+
public extension AnalyticsService {
36+
var allowEvents: Set<String> { Set<String>() }
37+
38+
func send(event: AnalyticsEvent, from viewController: ViewController) {}
2039
}

README.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[![Platform](https://img.shields.io/cocoapods/p/DLAnalytics.svg?style=flat)](http://cocoapods.org/pods/DLAnalytics)
77
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
88

9-
An abstract Analytics Framework supports:
9+
Abstract Analytics Framework supports:
1010

1111
- Unify Analytics.
1212
- Modularize, Centralize Analytics.
@@ -26,18 +26,27 @@ An abstract Analytics Framework supports:
2626

2727
```
2828
class ClientAnalyticsImpl: AnalyticsService {
29+
// Specify whitelist events. Accept all events by default
30+
var allowEvents: Set<String> {
31+
Set<String>(arrayLiteral: "\(InputOTPEvent.self)", "\(CheckoutEvent.self)")
32+
}
33+
2934
func setUserIdentifyProperty(_ property: [String : String]) {
30-
print("setUserIdentifyProperty: To support identify the user")
35+
// To support identify the user"
3136
}
3237
3338
func reset() {
34-
print("reset: To reset all data related to the user e.g user logout")
39+
// reset all data related to the user e.g user logout"
3540
}
3641
3742
func send(event: AnalyticsEvent) {
38-
// Here is the specific Analytics implementation e.g FireBaseAnalytics, MixPanel, etc.
43+
// Specific Analytics implementation e.g FireBaseAnalytics, MixPanel, etc.
3944
print("### Send an event name: \(event.name), payload = \(event.payload)")
4045
}
46+
47+
func send(event: AnalyticsEvent, from viewController: DLAnalytics.ViewController) {
48+
print("### Send an event name: \(event.name), controller = \(ViewController.self)" )
49+
}
4150
}
4251
```
4352

@@ -85,11 +94,11 @@ Analytics.registerAnalyticsService(analyticsService)
8594
```
8695
/// Simulate tracking event InputOTP success
8796
Analytics.send(event: InputOTPEvent.inputOTPSuccess())
88-
Analytics.send(event: CheckoutEvent.success)
97+
Analytics.send(event: CheckoutEvent.success, from viewController: checkoutVC)
8998
9099
/// Output:
91100
Send an event name: InputOTP, payload = ["OTPValid": "1"]
92-
Send an event name: Checkout_Success, payload = [:]
101+
Send an event name: Checkout_Success, controller = CheckoutViewController
93102
```
94103

95104
## Installation

0 commit comments

Comments
 (0)