Last active
October 18, 2021 11:19
-
-
Save danielctull/6a093bf81e402822e988c61f52ccaa2b to your computer and use it in GitHub Desktop.
Exploring the tracking options in view level code.
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
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 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 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