Skip to content

Instantly share code, notes, and snippets.

@danielctull
Last active October 18, 2021 11:19
Show Gist options
  • Save danielctull/6a093bf81e402822e988c61f52ccaa2b to your computer and use it in GitHub Desktop.
Save danielctull/6a093bf81e402822e988c61f52ccaa2b to your computer and use it in GitHub Desktop.
Exploring the tracking options in view level code.
import SwiftUI
// MARK: - SwiftUI environment definition (CoreTracking)
private struct EmptyTracker: Tracker {
func track(_ event: Event) {}
}
public struct TrackerEnvironmentKey: EnvironmentKey {
public static let defaultValue: Tracker = EmptyTracker()
}
extension EnvironmentValues {
public var tracker: Tracker {
get { self[TrackerEnvironmentKey.self] }
set { self[TrackerEnvironmentKey.self] = newValue }
}
}
// MARK: - On appear tracker view modifier (CoreTracking)
private struct OnAppearTracker: ViewModifier {
@Environment(\.tracker) private var tracker
let event: Event
func body(content: Content) -> some View {
content.onAppear { tracker.track(event) }
}
}
extension View {
public func onAppear(track event: Event) -> some View {
modifier(OnAppearTracker(event: event))
}
}
// MARK: - Tracking event definition (FeatureKit)
public struct AmazingViewDidAppear: Event {}
extension Event where Self == AmazingViewDidAppear {
public static var amazingViewDidAppear: AmazingViewDidAppear { AmazingViewDidAppear() }
}
// MARK: - View code (FeatureUI)
struct AmazingView: View {
var body: some View {
Text("Hello world")
.onAppear(track: .amazingViewDidAppear)
}
}
// This uses the responder chain to allow parent responders to supply the tracker to their children.
import UIKit
// MARK: - UIKit responder definition (CoreTracking)
// Unfortunate hack neccessary to allow tracker to be defined on UIResponder and overridden in the app delegate.
public class ObjectiveCTracker: NSObject, Tracker {
private let tracker: Tracker
public init(tracker: Tracker) {
self.tracker = tracker
}
public func track(_ event: Event) {
tracker.track(event)
}
}
extension UIResponder {
@objc open var tracker: ObjectiveCTracker {
next?.tracker ?? ObjectiveCTracker(tracker: EmptyTracker())
}
}
// MARK: - Tracker definition (Main App)
final class AppDelegate: UIResponder {
override var tracker: ObjectiveCTracker {
ObjectiveCTracker(tracker: CompositeTracker(trackers: [
// segment
// internal logger
]))
}
}
// MARK: - Usage from view controller
final class AmazingViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tracker.track(.amazingViewDidAppear)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment