Skip to content

Commit 487d139

Browse files
committed
Updated tests
1 parent 4103acc commit 487d139

File tree

17 files changed

+505
-189
lines changed

17 files changed

+505
-189
lines changed

Package.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ let package = Package(
4242
.copy("TestHelpers/addliveplugin.js"),
4343
.copy("TestHelpers/MyEdgeFunctions.js"),
4444
.copy("TestHelpers/badtest.js"),
45+
.copy("TestHelpers/runtimeBundle.js"),
46+
.copy("TestHelpers/runtimeBundleNoProcess.js")
4547
]),
4648
]
4749
)

Sources/AnalyticsLive/LivePlugins/AnalyticsJS.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public class AnalyticsJS: JSExport {
4848

4949
internal func originMarkerEnrichment(event: RawEvent?) -> RawEvent? {
5050
return Self.insertOrigin(event: event, data: [
51-
"type": "signals",
51+
"type": "js",
5252
"version": currentLivePluginVersion ?? ""
5353
])
5454
}

Sources/AnalyticsLive/LivePlugins/Bundler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ internal class Bundler {
1111
static var sessionConfig = URLSessionConfiguration.default
1212

1313
class func getLocalBundleFolderURL() -> URL {
14-
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
14+
let paths = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
1515
var result = paths[0]
1616
result.appendPathComponent("segmentJSBundles")
1717
if let identifier = Bundle.main.bundleIdentifier {

Sources/AnalyticsLive/LivePlugins/EmbeddedJS.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public struct EmbeddedJS {
2323
public static let edgeFnBaseSetupScript = """
2424
class LivePlugin {
2525
constructor(type, destination) {
26-
console.log("js: LivePlugin.constructor() called");
26+
//console.log("js: LivePlugin.constructor() called");
2727
this._type = type;
2828
this._destination = destination;
2929
}
@@ -39,7 +39,7 @@ public struct EmbeddedJS {
3939
update(settings, type) { }
4040
4141
execute(event) {
42-
console.log("js: LivePlugin.execute() called");
42+
//console.log("js: LivePlugin.execute() called");
4343
var result = event;
4444
switch(event.type) {
4545
case "identify":
@@ -66,7 +66,7 @@ public struct EmbeddedJS {
6666
}
6767
6868
track(event) {
69-
console.log("js: Super.track() called");
69+
//console.log("js: Super.track() called");
7070
return event;
7171
}
7272
@@ -79,7 +79,7 @@ public struct EmbeddedJS {
7979
}
8080
8181
screen(event) {
82-
console.log("js: Super.screen() called");
82+
//console.log("js: Super.screen() called");
8383
return event;
8484
}
8585

Sources/AnalyticsLive/Signals/AutoTracking/UIKit/SignalUINavController.swift

Lines changed: 16 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -67,92 +67,44 @@ internal class NavigationSwizzler {
6767
}
6868

6969
extension UINavigationController {
70+
private func getScreenName(from viewController: UIViewController?) -> String? {
71+
return viewController?.accessibilityLabel ?? viewController?.title ?? viewController?.navigationItem.title
72+
}
73+
74+
private func emitNavigationSignal(to currentVC: UIViewController?, from previousVC: UIViewController?, fallback: String) {
75+
let navSignal = NavigationSignal(
76+
currentScreen: getScreenName(from: currentVC) ?? fallback,
77+
previousScreen: getScreenName(from: previousVC)
78+
)
79+
Signals.emit(signal: navSignal, source: .autoUIKit)
80+
}
81+
7082
@objc dynamic func swizzled_pushViewController(_ viewController: UIViewController, animated: Bool) {
71-
// Get info before we push
7283
let fromVC = topViewController
73-
74-
// Call original implementation
7584
self.swizzled_pushViewController(viewController, animated: animated)
76-
77-
// Emit 'leaving' signal for the screen we're leaving
78-
if let fromScreen = fromVC?.accessibilityLabel ?? fromVC?.title ?? fromVC?.navigationItem.title {
79-
let leavingSignal = NavigationSignal(action: .leaving, screen: fromScreen)
80-
Signals.emit(signal: leavingSignal, source: .autoSwiftUI)
81-
}
82-
83-
// Emit 'entering' signal for the screen we're pushing to
84-
if let toScreen = viewController.accessibilityLabel ?? viewController.title ?? viewController.navigationItem.title {
85-
let enteringSignal = NavigationSignal(action: .entering, screen: toScreen)
86-
Signals.emit(signal: enteringSignal, source: .autoSwiftUI)
87-
}
85+
emitNavigationSignal(to: viewController, from: fromVC, fallback: "Unknown <push>")
8886
}
8987

9088
@objc dynamic func swizzled_popViewController(animated: Bool) -> UIViewController? {
91-
// Get info before we pop
9289
let fromVC = topViewController
9390
let toVC = viewControllers.count > 1 ? viewControllers[viewControllers.count - 2] : nil
94-
95-
// Call original implementation
9691
let result = self.swizzled_popViewController(animated: animated)
97-
98-
// Emit 'leaving' signal for the screen we're popping from
99-
if let fromScreen = fromVC?.accessibilityLabel ?? fromVC?.title ?? fromVC?.navigationItem.title {
100-
let leavingSignal = NavigationSignal(action: .leaving, screen: fromScreen)
101-
Signals.emit(signal: leavingSignal, source: .autoSwiftUI)
102-
}
103-
104-
// Emit 'entering' signal for the screen we're popping back to
105-
if let toScreen = toVC?.accessibilityLabel ?? toVC?.title ?? toVC?.navigationItem.title {
106-
let enteringSignal = NavigationSignal(action: .entering, screen: toScreen)
107-
Signals.emit(signal: enteringSignal, source: .autoSwiftUI)
108-
}
109-
92+
emitNavigationSignal(to: toVC, from: fromVC, fallback: "Unknown <pop>")
11093
return result
11194
}
11295

11396
@objc dynamic func swizzled_popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]? {
114-
// Get info before we pop
11597
let fromVC = topViewController
116-
117-
// Call original implementation
11898
let result = self.swizzled_popToViewController(viewController, animated: animated)
119-
120-
// Emit 'leaving' signal for current screen
121-
if let fromScreen = fromVC?.accessibilityLabel ?? fromVC?.title ?? fromVC?.navigationItem.title {
122-
let leavingSignal = NavigationSignal(action: .leaving, screen: fromScreen)
123-
Signals.emit(signal: leavingSignal, source: .autoSwiftUI)
124-
}
125-
126-
// Emit 'entering' signal for target screen
127-
if let toScreen = viewController.accessibilityLabel ?? viewController.title ?? viewController.navigationItem.title {
128-
let enteringSignal = NavigationSignal(action: .entering, screen: toScreen)
129-
Signals.emit(signal: enteringSignal, source: .autoSwiftUI)
130-
}
131-
99+
emitNavigationSignal(to: viewController, from: fromVC, fallback: "Unknown <popTo>")
132100
return result
133101
}
134-
135102

136103
@objc dynamic func swizzled_popToRootViewController(animated: Bool) -> [UIViewController]? {
137-
// Get info before we pop
138104
let fromVC = topViewController
139105
let rootVC = viewControllers.first
140-
141-
// Call original implementation
142106
let result = self.swizzled_popToRootViewController(animated: animated)
143-
144-
// Emit 'leaving' signal for current screen
145-
if let fromScreen = fromVC?.accessibilityLabel ?? fromVC?.title ?? fromVC?.navigationItem.title {
146-
let leavingSignal = NavigationSignal(action: .leaving, screen: fromScreen)
147-
Signals.emit(signal: leavingSignal, source: .autoSwiftUI)
148-
}
149-
150-
// Emit 'entering' signal for target screen
151-
if let toScreen = rootVC?.accessibilityLabel ?? rootVC?.title ?? rootVC?.navigationItem.title {
152-
let enteringSignal = NavigationSignal(action: .entering, screen: toScreen)
153-
Signals.emit(signal: enteringSignal, source: .autoSwiftUI)
154-
}
155-
107+
emitNavigationSignal(to: rootVC, from: fromVC, fallback: "Unknown <popToRoot>")
156108
return result
157109
}
158110
}

Sources/AnalyticsLive/Signals/AutoTracking/UIKit/SignalUIViewController.swift

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -50,69 +50,66 @@ internal class ModalSwizzler {
5050
}
5151

5252
extension UIViewController {
53+
private func extractBasicName(from vc: UIViewController?) -> String? {
54+
return vc?.accessibilityLabel ?? vc?.title ?? vc?.navigationItem.title
55+
}
56+
57+
private func extractSwiftUIHostingName() -> String? {
58+
guard let hostingController = self as? UIHostingController<AnyView> else { return nil }
59+
60+
let mirror = Mirror(reflecting: hostingController.rootView)
61+
let typeName = String(describing: mirror.subjectType)
62+
.replacingOccurrences(of: "ModifiedContent<", with: "")
63+
.replacingOccurrences(of: ", RootModifier>", with: "")
64+
.replacingOccurrences(of: ", _TraitWritingModifier<.*>>", with: "", options: .regularExpression)
65+
.replacingOccurrences(of: "AnyView", with: "")
66+
.trimmingCharacters(in: .whitespacesAndNewlines)
67+
68+
return typeName.isEmpty ? nil : typeName
69+
}
70+
5371
var meaningfulName: String {
54-
// Try all our previous methods first
55-
if let name = self.accessibilityLabel ?? self.title ?? self.navigationItem.title {
56-
return name
57-
}
72+
// Try basic name extraction first
73+
if let name = extractBasicName(from: self) { return name }
5874

59-
// If we're in a navigation controller, try to get its title
75+
// If we're a nav controller, try the top VC
6076
if let nav = self as? UINavigationController,
61-
let topVC = nav.topViewController,
62-
let navTitle = topVC.accessibilityLabel ?? topVC.title ?? topVC.navigationItem.title {
63-
return navTitle
64-
}
77+
let name = extractBasicName(from: nav.topViewController) { return name }
6578

66-
// If we have a navigation controller, try its top view controller
67-
if let nav = self.navigationController,
68-
let navTitle = nav.topViewController?.accessibilityLabel ??
69-
nav.topViewController?.title ??
70-
nav.topViewController?.navigationItem.title {
71-
return navTitle
72-
}
79+
// If we have a nav controller, try its top VC
80+
if let name = extractBasicName(from: navigationController?.topViewController) { return name }
7381

74-
// If we've got a hosting controller, try to get the SwiftUI view name
75-
if let hostingController = self as? UIHostingController<AnyView> {
76-
let mirror = Mirror(reflecting: hostingController.rootView)
77-
let value = String(describing: mirror.subjectType)
78-
.replacingOccurrences(of: "ModifiedContent<", with: "")
79-
.replacingOccurrences(of: ", RootModifier>", with: "")
80-
.replacingOccurrences(of: ", _TraitWritingModifier<.*>>", with: "", options: .regularExpression)
81-
.replacingOccurrences(of: "AnyView", with: "")
82-
.trimmingCharacters(in: .whitespacesAndNewlines)
83-
if value.isEmpty == false {
84-
return value
85-
}
86-
}
82+
// Try SwiftUI hosting controller
83+
if let name = extractSwiftUIHostingName() { return name }
8784

88-
// Clean up the type name if we have to use it
85+
// Fall back to type name
8986
return String(describing: type(of: self))
9087
}
9188

9289
@objc dynamic func swizzled_present(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)? = nil) {
90+
let fromScreen = self.meaningfulName
9391
let modalScreen = viewControllerToPresent.meaningfulName
9492

95-
// Call original implementation
9693
self.swizzled_present(viewControllerToPresent, animated: animated, completion: completion)
9794

98-
// Just emit the modal signal and save the name
99-
let modalSignal = NavigationSignal(action: .modal, screen: modalScreen)
100-
Signals.emit(signal: modalSignal, source: .autoSwiftUI)
95+
let navSignal = NavigationSignal(currentScreen: modalScreen, previousScreen: fromScreen)
96+
Signals.emit(signal: navSignal, source: .autoUIKit)
97+
10198
ModalSwizzler.shared.currentModalName = modalScreen
10299
}
103100

104101
@objc dynamic func swizzled_dismiss(animated: Bool, completion: (() -> Void)? = nil) {
105-
// Get the saved modal name
106102
let modalScreen = ModalSwizzler.shared.currentModalName ?? self.meaningfulName
103+
let backToScreen = presentingViewController?.meaningfulName
107104

108-
// Call original implementation
109105
self.swizzled_dismiss(animated: animated, completion: completion)
110106

111-
// Just emit leaving for the modal
112-
let leavingSignal = NavigationSignal(action: .leaving, screen: modalScreen)
113-
Signals.emit(signal: leavingSignal, source: .autoSwiftUI)
107+
let navSignal = NavigationSignal(
108+
currentScreen: backToScreen ?? "Unknown <dismissed>",
109+
previousScreen: modalScreen
110+
)
111+
Signals.emit(signal: navSignal, source: .autoUIKit)
114112

115-
// Clear the saved name
116113
ModalSwizzler.shared.currentModalName = nil
117114
}
118115
}

Sources/AnalyticsLive/Signals/Context.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public struct StaticContext: Codable {
5454

5555
static func configureRuntimeVersion(engine: JSEngine) {
5656
guard _signalsRuntimeVersion == nil else { return }
57-
let jsVersion = /*engine.value(for: "SEGMENT_SIGNALS_RUNTIME_VERSION") as? String ??*/ SignalsRuntime.version
57+
let jsVersion = /*engine.value(for: "SEGMENT_SIGNALS_RUNTIME_VERSION") as? String// ??*/ SignalsRuntime.version
5858
_signalsRuntimeVersion = jsVersion
5959
}
6060
}

Sources/AnalyticsLive/Signals/Minilytics/MiniAnalytics.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ internal class MiniAnalytics {
149149
// MARK: - Network Stuff
150150

151151
extension MiniAnalytics {
152-
private static let defaultAPIHost = "signals.segment.io/v1"
153-
//private static let defaultAPIHost = "signals.segment.build/v1"
152+
//private static let defaultAPIHost = "signals.segment.io/v1"
153+
private static let defaultAPIHost = "signals.segment.build/v1"
154154

155155
func segmentURL(for host: String, path: String) -> URL? {
156156
let s = "https://\(host)\(path)"

Sources/AnalyticsLive/Signals/Runtime/SignalsJS.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// GENERATED - DO NOT EDIT
22
// Source: https://github.com/segment-integrations/signals-specs/blob/@segment/analytics-signals-runtime@2.2.0/packages/signals-runtime/src/mobile/get-runtime-code.generated.ts
33
// Release: @segment/analytics-signals-runtime@2.2.0
4-
// Generated: Fri Jul 18 11:01:15 PDT 2025
4+
// Generated: Wed Jul 23 10:43:08 PDT 2025
55
//
66
// This JavaScript is stored as chunked base64 because:
77
// 1. The original JS is minified into one very long line

0 commit comments

Comments
 (0)