Skip to content

Commit 941bcc9

Browse files
committed
Add new tracking modifiers
1 parent c567ea6 commit 941bcc9

File tree

6 files changed

+427
-1421
lines changed

6 files changed

+427
-1421
lines changed

ForPDA.xcodeproj/project.pbxproj

Lines changed: 269 additions & 1365 deletions
Large diffs are not rendered by default.

Modules/Sources/AnalyticsClient/UI/AnalyticsModifier.swift

Lines changed: 0 additions & 40 deletions
This file was deleted.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// TracePerformanceView+Modifier.swift
3+
// AnalyticsClient
4+
//
5+
// Created by Ilia Lubianoi on 18.03.2025.
6+
//
7+
8+
import SwiftUI
9+
import SentrySwiftUI
10+
11+
// MARK: - View
12+
13+
public struct TracePerformanceView<Content: View>: View {
14+
15+
let viewName: String?
16+
let content: Content
17+
18+
public init(
19+
_ viewName: String? = nil,
20+
@ViewBuilder content: () -> Content
21+
) {
22+
self.viewName = viewName
23+
self.content = content()
24+
}
25+
26+
public var body: some View {
27+
SentryTracedView(viewName) {
28+
content
29+
}
30+
}
31+
}
32+
33+
// MARK: - Modifier
34+
35+
struct TracePerformanceModifier: ViewModifier {
36+
37+
let viewName: String
38+
39+
func body(content: Content) -> some View {
40+
content
41+
.sentryTrace(viewName)
42+
}
43+
}
44+
45+
// MARK: - Modifier Extension
46+
47+
public extension View {
48+
func tracePerformance(viewName: String) -> some View {
49+
return modifier(TracePerformanceModifier(viewName: viewName))
50+
}
51+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//
2+
// TrackAnalyticsModifier.swift
3+
// ForPDA
4+
//
5+
// Created by Ilia Lubianoi on 26.11.2024.
6+
//
7+
8+
import SwiftUI
9+
import PostHog
10+
11+
// MARK: - Modifier
12+
13+
struct TrackAnalyticsModifier: ViewModifier {
14+
let screenName: String
15+
let properties: [String: Any]?
16+
17+
func body(content: Content) -> some View {
18+
content
19+
.postHogScreenView(screenName, properties)
20+
}
21+
}
22+
23+
// MARK: - Modifier Extension
24+
25+
public extension View {
26+
func trackAnalytics(screenName: String, properties: [String: Any]? = nil) -> some View {
27+
return modifier(TrackAnalyticsModifier( screenName: screenName, properties: properties))
28+
}
29+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//
2+
// TrackingModifier.swift
3+
// AnalyticsClient
4+
//
5+
// Created by Ilia Lubianoi on 18.03.2025.
6+
//
7+
8+
import SwiftUI
9+
10+
// MARK: - Modifier
11+
12+
struct TrackingModifier<V: View>: ViewModifier {
13+
14+
let viewName: String
15+
let properties: [String: Any]?
16+
17+
init(
18+
for type: V.Type,
19+
waitForFullDisplay: Bool? = nil,
20+
properties: [String : Any]? = nil
21+
) {
22+
self.viewName = Self.getScreenName(from: type)
23+
self.properties = properties
24+
}
25+
26+
func body(content: Content) -> some View {
27+
content
28+
.tracePerformance(viewName: viewName)
29+
.trackAnalytics(screenName: viewName, properties: properties)
30+
}
31+
32+
private static func getScreenName(from type: V.Type) -> String {
33+
var result = ""
34+
for char in String(describing: type) {
35+
if char.isUppercase && !result.isEmpty {
36+
result.append(" ")
37+
}
38+
result.append(char)
39+
}
40+
return result
41+
}
42+
}
43+
44+
// MARK: - Modifier Extension
45+
46+
public extension View {
47+
/// Adds analytics & performance tracking to the view
48+
/// - Parameters:
49+
/// - type: type of screen that it's being used on (necessary for name extraction)
50+
/// - properties: analytics sent to PostHog, default is nil
51+
func tracking<V: View>(
52+
for type: V.Type,
53+
_ properties: [String: Any]? = nil
54+
) -> some View {
55+
return modifier(
56+
TrackingModifier(
57+
for: type,
58+
properties: properties
59+
)
60+
)
61+
}
62+
}

Modules/Sources/AppFeature/AppView.swift

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,17 @@ public struct AppView: View {
9494
path: $store.scope(state: \.articlesPath, action: \.articlesPath)
9595
) {
9696
ArticlesListScreen(store: store.scope(state: \.articlesList, action: \.articlesList))
97-
.trackAnalytics("Articles List Screen")
97+
.tracking(for: ArticlesListScreen.self)
9898
} destination: { store in
9999
WithPerceptionTracking {
100100
switch store.case {
101101
case let .article(store):
102102
ArticleScreen(store: store)
103-
.trackAnalytics("Article Screen", ["id": store.articlePreview.id])
103+
.tracking(for: ArticleScreen.self, ["id": store.articlePreview.id])
104104

105105
case let .profile(store):
106106
ProfileScreen(store: store)
107-
.trackAnalytics("Profile Screen", ["id": store.userId ?? 0])
107+
.tracking(for: ProfileScreen.self, ["id": store.userId ?? 0])
108108

109109
case let .settingsPath(path):
110110
SettingsPath(path)
@@ -122,7 +122,7 @@ public struct AppView: View {
122122
path: $store.scope(state: \.favoritesRootPath, action: \.favoritesRootPath)
123123
) {
124124
FavoritesRootScreen(store: store.scope(state: \.favoritesRoot, action: \.favoritesRoot))
125-
.trackAnalytics("Favorites Root Screen")
125+
.tracking(for: FavoritesRootScreen.self)
126126
} destination: { store in
127127
switch store.case {
128128
case let .forumPath(path):
@@ -144,7 +144,7 @@ public struct AppView: View {
144144
path: $store.scope(state: \.forumPath, action: \.forumPath)
145145
) {
146146
ForumsListScreen(store: store.scope(state: \.forumsList, action: \.forumsList))
147-
.trackAnalytics("Forums List Screen")
147+
.tracking(for: ForumsListScreen.self)
148148
} destination: { store in
149149
ForumPath(store)
150150
}
@@ -160,12 +160,12 @@ public struct AppView: View {
160160
path: $store.scope(state: \.profilePath, action: \.profilePath)
161161
) {
162162
ProfileScreen(store: store.scope(state: \.profile, action: \.profile))
163-
.trackAnalytics("Profile Screen")
163+
.tracking(for: ProfileScreen.self)
164164
} destination: { store in
165165
switch store.case {
166166
case let .history(store):
167167
HistoryScreen(store: store)
168-
.trackAnalytics("History Screen")
168+
.tracking(for: HistoryScreen.self)
169169
case let .qmsPath(path):
170170
QMSPath(path)
171171
case let .settingsPath(path):
@@ -183,10 +183,10 @@ public struct AppView: View {
183183
switch store.case {
184184
case let .qmsList(store):
185185
QMSListScreen(store: store)
186-
.trackAnalytics("QMS List Screen")
186+
.tracking(for: QMSListScreen.self)
187187
case let .qms(store):
188188
QMSScreen(store: store)
189-
.trackAnalytics("QMS Screen")
189+
.tracking(for: QMSScreen.self)
190190
}
191191
}
192192

@@ -198,19 +198,19 @@ public struct AppView: View {
198198
switch store.case {
199199
case let .forum(store):
200200
ForumScreen(store: store)
201-
.trackAnalytics("Forum Screen", ["id": store.forumId])
201+
.tracking(for: ForumScreen.self, ["id": store.forumId])
202202

203203
case let .topic(store):
204204
TopicScreen(store: store)
205-
.trackAnalytics("Topic Screen", ["id": store.topicId])
205+
.tracking(for: TopicScreen.self, ["id": store.topicId])
206206

207207
case let .profile(store):
208208
ProfileScreen(store: store)
209-
.trackAnalytics("Profile Screen", ["id": store.userId ?? 0])
209+
.tracking(for: ProfileScreen.self, ["id": store.userId ?? 0])
210210

211211
case let .announcement(store):
212212
AnnouncementScreen(store: store)
213-
.trackAnalytics("Announcement Screen", ["id": store.announcementId])
213+
.tracking(for: AnnouncementScreen.self, ["id": store.announcementId])
214214

215215
case let .settingsPath(path):
216216
SettingsPath(path)
@@ -225,13 +225,13 @@ public struct AppView: View {
225225
switch store.case {
226226
case let .settings(store):
227227
SettingsScreen(store: store)
228-
.trackAnalytics("Settings Screen")
228+
.tracking(for: SettingsScreen.self)
229229
case let .developer(store):
230230
DeveloperScreen(store: store)
231-
.trackAnalytics("Developer Screen")
231+
.tracking(for: DeveloperScreen.self)
232232
case let .notifications(store):
233233
NotificationsScreen(store: store)
234-
.trackAnalytics("Notifications Settings Screen")
234+
.tracking(for: NotificationsScreen.self)
235235
}
236236
}
237237

0 commit comments

Comments
 (0)