Skip to content

Commit d56b150

Browse files
authored
Fixes for userAgent delay. Retrieved async now. (#236)
* Fixes for userAgent delay. Retrieved async now. * Fix test for watchOS/Linux
1 parent 58d0ed5 commit d56b150

File tree

3 files changed

+31
-20
lines changed

3 files changed

+31
-20
lines changed

Sources/Segment/Plugins/Context.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,6 @@ public class Context: PlatformPlugin {
108108
"width": screen.width,
109109
"height": screen.height
110110
]
111-
// user-agent
112-
let userAgent = device.userAgent
113-
context["userAgent"] = userAgent
114111
// locale
115112
if Locale.preferredLanguages.count > 0 {
116113
context["locale"] = Locale.preferredLanguages[0]
@@ -147,6 +144,13 @@ public class Context: PlatformPlugin {
147144
"wifi": wifi
148145
]
149146

147+
// user-agent
148+
// BKS: This use to be in the static section, however it was discovered that on some platforms
149+
// there can be a delay in retrieval. It has to be fetched on the main thread, so we've spun it off
150+
// async and cache it when it comes back.
151+
let userAgent = device.userAgent
152+
context["userAgent"] = userAgent
153+
150154
// other stuff?? ...
151155
}
152156

Sources/Segment/Plugins/Platforms/Vendors/AppleUtils.swift

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import WebKit
1919

2020
internal class iOSVendorSystem: VendorSystem {
2121
private let device = UIDevice.current
22+
@Atomic private static var asyncUserAgent: String? = nil
2223

2324
override var manufacturer: String {
2425
return "Apple"
@@ -65,17 +66,15 @@ internal class iOSVendorSystem: VendorSystem {
6566

6667
override var userAgent: String? {
6768
#if !os(tvOS)
68-
var userAgent: String?
69-
70-
if Thread.isMainThread {
71-
userAgent = WKWebView().value(forKey: "userAgent") as? String
72-
} else {
73-
DispatchQueue.main.sync {
74-
userAgent = WKWebView().value(forKey: "userAgent") as? String
69+
// BKS: It was discovered that on some platforms there can be a delay in retrieval.
70+
// It has to be fetched on the main thread, so we've spun it off
71+
// async and cache it when it comes back.
72+
if Self.asyncUserAgent == nil {
73+
DispatchQueue.main.async {
74+
Self.asyncUserAgent = WKWebView().value(forKey: "userAgent") as? String
7575
}
7676
}
77-
78-
return userAgent
77+
return Self.asyncUserAgent
7978
#else
8079
// webkit isn't on tvos
8180
return "unknown"
@@ -198,6 +197,7 @@ import WebKit
198197

199198
internal class MacOSVendorSystem: VendorSystem {
200199
private let device = ProcessInfo.processInfo
200+
@Atomic private static var asyncUserAgent: String? = nil
201201

202202
override var manufacturer: String {
203203
return "Apple"
@@ -238,16 +238,15 @@ internal class MacOSVendorSystem: VendorSystem {
238238
}
239239

240240
override var userAgent: String? {
241-
var userAgent: String?
242-
if Thread.isMainThread {
243-
userAgent = WKWebView().value(forKey: "userAgent") as? String
244-
} else {
245-
DispatchQueue.main.sync {
246-
userAgent = WKWebView().value(forKey: "userAgent") as? String
241+
// BKS: It was discovered that on some platforms there can be a delay in retrieval.
242+
// It has to be fetched on the main thread, so we've spun it off
243+
// async and cache it when it comes back.
244+
if Self.asyncUserAgent == nil {
245+
DispatchQueue.main.async {
246+
Self.asyncUserAgent = WKWebView().value(forKey: "userAgent") as? String
247247
}
248248
}
249-
250-
return userAgent
249+
return Self.asyncUserAgent
251250
}
252251

253252
override var connection: ConnectionStatus {

Tests/Segment-Tests/Analytics_Tests.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ final class Analytics_Tests: XCTestCase {
123123
let outputReader = OutputReaderPlugin()
124124
analytics.add(plugin: outputReader)
125125

126+
#if !os(watchOS) && !os(Linux)
127+
// prime the pump for userAgent, since it's retrieved async.
128+
let vendorSystem = VendorSystem.current
129+
while vendorSystem.userAgent == nil {
130+
RunLoop.main.run(until: Date.distantPast)
131+
}
132+
#endif
133+
126134
waitUntilStarted(analytics: analytics)
127135

128136
// add a referrer

0 commit comments

Comments
 (0)