-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #56 from WalletConnect/pulse-analytics
Pulse analytics
- Loading branch information
Showing
32 changed files
with
542 additions
and
43 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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 |
---|---|---|
@@ -0,0 +1,28 @@ | ||
enum AnalyticsEvent: Equatable { | ||
case MODAL_LOADED | ||
case MODAL_OPEN(connected: Bool) | ||
case MODAL_CLOSE(connected: Bool) | ||
case CLICK_ALL_WALLETS | ||
case SELECT_WALLET(name: String, platform: Method) | ||
case CLICK_NETWORKS | ||
// case OPEN_ACTIVITY_VIEW // | ||
case SWITCH_NETWORK(network: Chain) | ||
case CONNECT_SUCCESS(method: Method, name: String) | ||
case CONNECT_ERROR(message: String) | ||
case DISCONNECT_SUCCESS | ||
case DISCONNECT_ERROR | ||
case CLICK_WALLET_HELP | ||
case CLICK_NETWORK_HELP | ||
case CLICK_GET_WALLET | ||
|
||
|
||
enum Method: String { | ||
case qrcode = "qrcode" | ||
case mobile = "mobile" | ||
} | ||
|
||
// enum Platform: String { | ||
// case qrcode = "QR" | ||
// case mobile = "mobile" | ||
// } | ||
} |
This file contains 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 |
---|---|---|
@@ -0,0 +1,4 @@ | ||
protocol AnalyticsEventMapper { | ||
func eventName(for event: AnalyticsEvent) -> String | ||
func parameters(for event: AnalyticsEvent) -> [String: String] | ||
} |
This file contains 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 |
---|---|---|
@@ -0,0 +1,3 @@ | ||
protocol AnalyticsProvider { | ||
func track(_ event: AnalyticsEvent) | ||
} |
17 changes: 17 additions & 0 deletions
17
Sources/Web3Modal/Analytics/Convenience/AnalyticsEvent+ResultBuilders.swift
This file contains 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 |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import Foundation | ||
|
||
/// A builder resulting in an array of analytics event groups | ||
@resultBuilder enum AnalyticsEventGroupBuilder { | ||
/// Return an array of analytics event groups given a closure containing statements of analytics event groups | ||
static func buildBlock(_ eventGroups: AnalyticsEventGroup...) -> [AnalyticsEventGroup] { | ||
eventGroups | ||
} | ||
} | ||
|
||
/// A builder resulting in an array of analytics events | ||
@resultBuilder enum AnalyticsEventBuilder { | ||
/// Return an array of analytics events given a closure containing statements of analytics events. | ||
static func buildBlock(_ events: AnalyticsEvent...) -> [AnalyticsEvent] { | ||
events | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
Sources/Web3Modal/Analytics/Convenience/AnalyticsEventGroup.swift
This file contains 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 |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/// A group of analytics events tracked together in response to a common trigger | ||
struct AnalyticsEventGroup { | ||
// MARK: Properties | ||
|
||
/// The trigger causing the analytics events to be tracked | ||
let trigger: AnalyticsEventTrigger | ||
|
||
/// The events being tracked | ||
let events: [AnalyticsEvent] | ||
|
||
// MARK: Initializers | ||
|
||
init(_ trigger: AnalyticsEventTrigger, events: [AnalyticsEvent]) { | ||
self.trigger = trigger | ||
self.events = events | ||
} | ||
} | ||
|
||
extension AnalyticsEventGroup { | ||
/// Initialize with a trigger and event builder | ||
init(_ trigger: AnalyticsEventTrigger, @AnalyticsEventBuilder events: () -> [AnalyticsEvent]) { | ||
self.init(trigger, events: events()) | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
Sources/Web3Modal/Analytics/Convenience/AnalyticsEventTrackingModifier.swift
This file contains 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 |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import SwiftUI | ||
|
||
/// A view modifier that tracks analytics events | ||
struct AnalyticsEventTrackingModifier: ViewModifier { | ||
|
||
@EnvironmentObject var analyticsService: AnalyticsService | ||
|
||
/// The groups of analytics events to track | ||
let groups: [AnalyticsEventGroup] | ||
|
||
func body(content: Content) -> some View { | ||
content | ||
.onAppear { | ||
trackAll(in: groups(for: .onAppear)) | ||
} | ||
.onDisappear { | ||
trackAll(in: groups(for: .onDisappear)) | ||
} | ||
.onTapGesture { | ||
trackAll(in: groups(for: .onTapGesture)) | ||
} | ||
} | ||
|
||
// MARK: Helpers | ||
|
||
/// Returns the group for the given trigger | ||
private func groups(for trigger: AnalyticsEventTrigger) -> [AnalyticsEventGroup] { | ||
groups.filter { $0.trigger == trigger } | ||
} | ||
|
||
/// Track all events in the given group | ||
private func trackAll(in group: [AnalyticsEventGroup]) { | ||
groups | ||
.flatMap { $0.events } | ||
.forEach { event in | ||
analyticsService.track(event) | ||
} | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
Sources/Web3Modal/Analytics/Convenience/AnalyticsEventTrigger.swift
This file contains 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 |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/// A trigger that causes analytics events to be tracked | ||
enum AnalyticsEventTrigger { | ||
case onAppear | ||
case onDisappear | ||
case onTapGesture | ||
} |
This file contains 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 |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import SwiftUI | ||
|
||
extension View { | ||
|
||
func track(@AnalyticsEventGroupBuilder _ groups: () -> [AnalyticsEventGroup]) -> some View { | ||
let groups = groups() | ||
let modifier = AnalyticsEventTrackingModifier(groups: groups) | ||
return self.modifier(modifier) | ||
} | ||
|
||
func track(_ event: AnalyticsEvent) { | ||
let service: AnalyticsService = Environment(\.analyticsService).wrappedValue | ||
service.track(event) | ||
} | ||
|
||
func track(@AnalyticsEventBuilder _ events: () -> [AnalyticsEvent]) { | ||
let service: AnalyticsService = Environment(\.analyticsService).wrappedValue | ||
let events = events() | ||
events.forEach { event in | ||
service.track(event) | ||
} | ||
} | ||
|
||
/// Track a group of events in response to the trigger with the provided service. | ||
func track(_ trigger: AnalyticsEventTrigger, @AnalyticsEventBuilder _ events: () -> [AnalyticsEvent]) -> some View { | ||
let eventsArray = events() | ||
let group = AnalyticsEventGroup(trigger, events: eventsArray) | ||
return track { group } | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
Sources/Web3Modal/Analytics/Private/AnalyticsService.swift
This file contains 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 |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import Foundation | ||
|
||
class AnalyticsService: AnalyticsProvider, ObservableObject { | ||
private(set) static var shared = AnalyticsService(providers: [ | ||
// LoggingAnalyticsProvider(), | ||
ClickstreamAnalyticsProvider() | ||
]) | ||
|
||
private let providers: [AnalyticsProvider] | ||
var method: AnalyticsEvent.Method = .mobile | ||
|
||
var isAnalyticsEnabled: Bool { | ||
return UserDefaults.standard.bool(forKey: analyticsEnabledKey) | ||
} | ||
|
||
// Key to store the state of analytics | ||
private let analyticsEnabledKey = "com.walletconnect.w3m.analyticsEnabled" | ||
|
||
init(providers: [AnalyticsProvider]) { | ||
self.providers = providers | ||
// Set default value for analytics enabled if it's not already set | ||
if UserDefaults.standard.object(forKey: analyticsEnabledKey) == nil { | ||
UserDefaults.standard.set(true, forKey: analyticsEnabledKey) | ||
} | ||
} | ||
|
||
func track(_ event: AnalyticsEvent) { | ||
guard isAnalyticsEnabled else { return } | ||
|
||
providers.forEach { | ||
$0.track(event) | ||
} | ||
if case .SELECT_WALLET(_, let platform) = event { | ||
self.method = platform | ||
} | ||
} | ||
|
||
func disable() { | ||
UserDefaults.standard.set(false, forKey: analyticsEnabledKey) | ||
} | ||
|
||
func enable() { | ||
UserDefaults.standard.set(true, forKey: analyticsEnabledKey) | ||
} | ||
} | ||
|
||
import SwiftUI | ||
|
||
struct AnalyticsServiceKey: EnvironmentKey { | ||
static var defaultValue: AnalyticsService = .shared | ||
} | ||
|
||
extension EnvironmentValues { | ||
var analyticsService: AnalyticsService { | ||
get { self[AnalyticsServiceKey.self] } | ||
set { self[AnalyticsServiceKey.self] = newValue } | ||
} | ||
} |
Oops, something went wrong.