Skip to content

Commit

Permalink
Merge pull request #164 from TelemetryDeck/feature/navigation-rename
Browse files Browse the repository at this point in the history
Extract navigation code to separate files + rename for consistency
  • Loading branch information
Jeehut authored Jun 28, 2024
2 parents 7be3246 + 527a990 commit a28c7e7
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 68 deletions.
9 changes: 9 additions & 0 deletions Sources/TelemetryClient/Presets/NavigationStatus.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation

/// This internal singleton keeps track of the last used navigation path so
/// that the ``TelemetryDeck.navigationPathChanged(to:customUserID:)`` function has a `from` source to work off of.
class NavigationStatus {
static let shared = NavigationStatus()

var previousNavigationPath: String?
}
75 changes: 75 additions & 0 deletions Sources/TelemetryClient/Presets/TelemetryDeck+Navigation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import Foundation

extension TelemetryDeck {
/// Send a signal that represents a navigation event with a source and a destination
///
/// This is a convenience method that will internally send a completely normal TelemetryDeck signals with the type
/// `TelemetryDeck.Route.Transition.navigation` and the necessary parameters.
///
/// Since TelemetryDeck navigation signals need a source and a destination, this method will store the last
/// used destination for use in the `navigate(to:)` method.
///
/// ## Navigation Paths
/// Navigation Paths are strings that describe a location or view in your application or website. They must be
/// delineated by either `.` or `/` characters. Delineation characters at the beginning and end of the string are
/// ignored. Use the empty string `""` for navigation from outside the app. Examples are `index`,
/// `settings.user.changePassword`, or `/blog/ios-market-share`.
///
/// - Parameters:
/// - from: The navigation path at the beginning of the navigation event, identifying the view the user is leaving
/// - to: The navigation path at the end of the navigation event, identifying the view the user is arriving at
/// - customUserID: An optional string specifying a custom user identifier. If provided, it will override the default user identifier from the configuration. Default is `nil`.
public static func navigationPathChanged(from source: String, to destination: String, customUserID: String? = nil) {
NavigationStatus.shared.previousNavigationPath = destination

self.signal(
"TelemetryDeck.Navigation.pathChanged",
parameters: [
"TelemetryDeck.Navigation.schemaVersion": "1",
"TelemetryDeck.Navigation.identifier": "\(source) -> \(destination)",
"TelemetryDeck.Navigation.sourcePath": source,
"TelemetryDeck.Navigation.destinationPath": destination
],
customUserID: customUserID
)
}

/// Send a signal that represents a navigation event with a destination and a default source.
///
/// This is a convenience method that will internally send a completely normal TelemetryDeck signals with the type
/// `TelemetryDeck.Route.Transition.navigation` and the necessary parameters.
///
/// ## Navigation Paths
/// Navigation Paths are strings that describe a location or view in your application or website. They must be
/// delineated by either `.` or `/` characters. Delineation characters at the beginning and end of the string are
/// ignored. Use the empty string `""` for navigation from outside the app. Examples are `index`,
/// `settings.user.changePassword`, or `/blog/ios-market-share`.
///
/// ## Automatic Navigation Tracking
/// Since TelemetryDeck navigation signals need a source and a destination, this method will keep track of the last
/// used destination and will automatically insert it as a source the next time you call this method.
///
/// This is very convenient, but will produce incorrect graphs if you don't call it from every screen in your app.
/// Suppose you have 3 tabs "Home", "User" and "Settings", but only set up navigation in "Home" and "Settings". If
/// a user taps "Home", "User" and "Settings" in that order, that'll produce an incorrect navigation signal with
/// source "Home" and destination "Settings", a path that the user did not take.
///
/// - Parameters:
/// - to: The navigation path representing the view the user is arriving at.
/// - customUserID: An optional string specifying a custom user identifier. If provided, it will override the default user identifier from the configuration. Default is `nil`.
public static func navigationPathChanged(to destination: String, customUserID: String? = nil) {
let source = NavigationStatus.shared.previousNavigationPath ?? ""

Self.navigationPathChanged(from: source, to: destination, customUserID: customUserID)
}

@available(*, unavailable, renamed: "navigationPathChanged(from:to:customUserID:)")
public static func navigate(from source: String, to destination: String, customUserID: String? = nil) {
self.navigationPathChanged(from: source, to: destination, customUserID: customUserID)
}

@available(*, unavailable, renamed: "navigationPathChanged(to:customUserID:)")
public static func navigate(to destination: String, customUserID: String? = nil) {
self.navigationPathChanged(to: destination, customUserID: customUserID)
}
}
68 changes: 0 additions & 68 deletions Sources/TelemetryClient/TelemetryDeck.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import Foundation

/// This internal singleton keeps track of the last used navigation path so
/// that the `navigate(to:)` function has a source to work off of.
class TelemetryDeckNavigationStatus {
var previousNavigationPath: String?
static let shared = TelemetryDeckNavigationStatus()
}

/// A namespace for TelemetryDeck related functionalities.
public enum TelemetryDeck {
/// This alias makes it easier to migrate the configuration type into the TelemetryDeck namespace in future versions when deprecated code is fully removed.
Expand Down Expand Up @@ -40,67 +33,6 @@ public enum TelemetryDeck {
TelemetryManager.send(signalName, for: customUserID, floatValue: floatValue, with: parameters)
}

/// Send a signal that represents a navigation event with a source and a destination
///
/// This is a convenience method that will internally send a completely normal TelemetryDeck signals with the type
/// `TelemetryDeck.Route.Transition.navigation` and the necessary parameters.
///
/// Since TelemetryDeck navigation signals need a source and a destination, this method will store the last
/// used destination for use in the `navigate(to:)` method.
///
/// ## Navigation Paths
/// Navigation Paths are strings that describe a location or view in your application or website. They must be
/// delineated by either `.` or `/` characters. Delineation characters at the beginning and end of the string are
/// ignored. Use the empty string `""` for navigation from outside the app. Examples are `index`,
/// `settings.user.changePassword`, or `/blog/ios-market-share`.
///
/// - Parameters:
/// - from: The navigation path at the beginning of the navigation event, identifying the view the user is leaving
/// - to: The navigation path at the end of the navigation event, identifying the view the user is arriving at
/// - customUserID: An optional string specifying a custom user identifier. If provided, it will override the default user identifier from the configuration. Default is `nil`.
public static func navigate(from source: String, to destination: String, customUserID: String? = nil) {
TelemetryDeckNavigationStatus.shared.previousNavigationPath = destination

TelemetryManager.send(
"TelemetryDeck.Navigation.pathChanged",
for: customUserID,
with: [
"TelemetryDeck.Navigation.schemaVersion": "1",
"TelemetryDeck.Navigation.identifier": "\(source) -> \(destination)",
"TelemetryDeck.Navigation.sourcePath": source,
"TelemetryDeck.Navigation.destinationPath": destination
]
)
}

/// Send a signal that represents a navigation event with a destination and a default source.
///
/// This is a convenience method that will internally send a completely normal TelemetryDeck signals with the type
/// `TelemetryDeck.Route.Transition.navigation` and the necessary parameters.
///
/// ## Navigation Paths
/// Navigation Paths are strings that describe a location or view in your application or website. They must be
/// delineated by either `.` or `/` characters. Delineation characters at the beginning and end of the string are
/// ignored. Use the empty string `""` for navigation from outside the app. Examples are `index`,
/// `settings.user.changePassword`, or `/blog/ios-market-share`.
///
/// ## Automatic Navigation Tracking
/// Since TelemetryDeck navigation signals need a source and a destination, this method will keep track of the last
/// used destination and will automatically insert it as a source the next time you call this method.
///
/// This is very convenient, but will produce incorrect graphs if you don't call it from every screen in your app.
/// Suppose you have 3 tabs "Home", "User" and "Settings", but only set up navigation in "Home" and "Settings". If
/// a user taps "Home", "User" and "Settings" in that order, that'll produce an incorrect navigation signal with
/// source "Home" and destination "Settings", a path that the user did not take.
///
/// - Parameters:
/// - to: The navigation path representing the view the user is arriving at.
/// - customUserID: An optional string specifying a custom user identifier. If provided, it will override the default user identifier from the configuration. Default is `nil`.
public static func navigate(to destination: String, customUserID: String? = nil) {
let source = TelemetryDeckNavigationStatus.shared.previousNavigationPath ?? ""
Self.navigate(from: source, to: destination, customUserID: customUserID)
}

/// Do not call this method unless you really know what you're doing. The signals will automatically sync with
/// the server at appropriate times, there's no need to call this.
///
Expand Down

0 comments on commit a28c7e7

Please sign in to comment.