Skip to content

Commit 6814bd4

Browse files
Release 1.0.9
πŸ‘” Enhance boot up managers 🧡 Improve fetching top view controller πŸ‘” Remove user agent for wrappers πŸ‘” Improve logout logic βœ… Update unit tests πŸ“ˆ Update handling app state πŸ—‘οΈ Clean unused classes πŸ› Fix rotation for survey πŸ› Fix likert scale in landscape mode πŸ› Fix rotation for NPS πŸ› Fix casting answer for survey logic ⬆️ Bump SDK version
1 parent 183659a commit 6814bd4

File tree

30 files changed

+301
-427
lines changed

30 files changed

+301
-427
lines changed

β€ŽSample/UserpilotSwiftSample/UserpilotSample.xcodeproj/project.pbxprojβ€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@
923923
"$(inherited)",
924924
"@executable_path/Frameworks",
925925
);
926-
MARKETING_VERSION = 1.0.8;
926+
MARKETING_VERSION = 1.0.9;
927927
PRODUCT_BUNDLE_IDENTIFIER = com.userpilot.sample.dev;
928928
PRODUCT_NAME = "$(TARGET_NAME)";
929929
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -958,7 +958,7 @@
958958
"$(inherited)",
959959
"@executable_path/Frameworks",
960960
);
961-
MARKETING_VERSION = 1.0.8;
961+
MARKETING_VERSION = 1.0.9;
962962
PRODUCT_BUNDLE_IDENTIFIER = com.userpilot.sample;
963963
PRODUCT_NAME = "$(TARGET_NAME)";
964964
PROVISIONING_PROFILE_SPECIFIER = "";

β€ŽSample/UserpilotSwiftSample/UserpilotSample/Featues/SDKEvents/Cells/SDKEventTableViewCell.swiftβ€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ class SDKEventTableViewCell: UITableViewCell, ReusableTableCellView, TableViewCe
3333
if sdkEvent.analytic == "Identify" ||
3434
sdkEvent.analytic == "Screen" ||
3535
sdkEvent.analytic == "Event" {
36-
containerView.backgroundColor = UIColor(red: 103/255.0, green: 101/255.0, blue: 232/255.0, alpha: 0.102)
36+
containerView.backgroundColor = UIColor(red: 0.4, green: 0.4, blue: 0.9, alpha: 0.15)
3737
} else {
38-
containerView.backgroundColor = UIColor(red: 233/255.0, green: 30/255.0, blue: 99/255.0, alpha: 0.027)
38+
containerView.backgroundColor = UIColor(red: 0.9, green: 0.12, blue: 0.39, alpha: 0.05)
3939
}
4040
}
4141

β€ŽSample/UserpilotSwiftSample/UserpilotSample/Managers/Userpilot/UserpilotManager.swiftβ€Ž

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,21 @@ class UserpilotManager {
103103
extension UserpilotManager: UserpilotNavigationDelegate {
104104

105105
func navigate(to url: URL) {
106-
delay(1) {
107-
if url.scheme == "userpilot-example" {
108-
guard let destination = url.host else {
109-
return
110-
}
111-
if destination == "demo" {
112-
FlowRoutingManager.shared.openViewController(DeepLinkViewController.newInstance())
113-
} else if destination == "identify" {
114-
FlowRoutingManager.shared.openViewController(IdentifyViewController.newInstance())
115-
} else if destination == "screen_one" {
116-
FlowRoutingManager.shared.openViewController(ScreenOneViewController.newInstance())
117-
} else if destination == "screen_two" {
118-
FlowRoutingManager.shared.openViewController(ScreenTwoViewController.newInstance())
119-
}
120-
} else if url.scheme?.contains("http") == true || url.scheme?.contains("https") == true {
121-
UIApplication.shared.open(url, options: [:], completionHandler: nil)
106+
if url.scheme == "userpilot-example" {
107+
guard let destination = url.host else {
108+
return
122109
}
110+
if destination == "demo" {
111+
FlowRoutingManager.shared.openViewController(DeepLinkViewController.newInstance())
112+
} else if destination == "identify" {
113+
FlowRoutingManager.shared.openViewController(IdentifyViewController.newInstance())
114+
} else if destination == "screen_one" {
115+
FlowRoutingManager.shared.openViewController(ScreenOneViewController.newInstance())
116+
} else if destination == "screen_two" {
117+
FlowRoutingManager.shared.openViewController(ScreenTwoViewController.newInstance())
118+
}
119+
} else if url.scheme?.contains("http") == true || url.scheme?.contains("https") == true {
120+
UIApplication.shared.open(url, options: [:], completionHandler: nil)
123121
}
124122
}
125123

β€ŽSources/Userpilot/Analytics/AnalyticsPublisher.swiftβ€Ž

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ internal class AnalyticsPublisher {
9595
return container?.resolve(ExperiencesPublishing.self)
9696
}
9797

98+
private weak var sessionMonitorer: SessionMonitoring? {
99+
return container?.resolve(SessionMonitoring.self)
100+
}
101+
98102
/// Decorator used to modify event properties before sending.
99103
private let autoPropertyDecorator: AutoPropertyDecoratoring
100104

@@ -182,6 +186,7 @@ extension AnalyticsPublisher: AnalyticsPublishing {
182186
}
183187
}
184188
startSession = true
189+
experiencesPublisher?.logout()
185190
screenViewEntity?.resetState()
186191
socketManager.updateSocketState(socketState, forceUpdateState: true)
187192
clearAllCachedProperties(shouldClearCachedIdentifyEvent)
@@ -229,7 +234,7 @@ extension AnalyticsPublisher: AnalyticsPublishing {
229234
func publish(_ event: Event) {
230235
tryCatch {
231236
// Handle App state
232-
guard !UIApplication.shared.isAppInBackgroundOrInactive() else {
237+
guard sessionMonitorer?.isAppActive ?? false else {
233238
cacheEvent(event)
234239
return
235240
}

β€ŽSources/Userpilot/Analytics/SessionMonitor.swiftβ€Ž

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,31 @@ app entering the background or foreground.
2020
internal protocol SessionMonitoring: AnyObject {
2121
/// Starts the session monitoring process, setting up observers for app lifecycle events.
2222
func reset()
23+
24+
/// A flag to mintor app status
25+
var isAppActive: Bool { get }
2326
}
2427

25-
internal class SessionMonitor: SessionMonitoring, BootUp {
28+
internal class SessionMonitor: SessionMonitoring {
2629

2730
/// The analytics publisher responsible for flushing and resuming events.
2831
private let analyticsPublisher: AnalyticsPublishing
2932

3033
/// The storage used to store user-related data.
3134
private let storage: DataStoring
3235

33-
// A flag to prevent calling didEnterForeground twice
36+
/// A flag to prevent calling didEnterForeground twice
3437
private var hasInitializedForeground = false
3538

39+
/// A flag to mintor app status
40+
private var _isAppActive = false
41+
3642
/// Initializes the `SessionMonitor` with a dependency container that resolves an `AnalyticsPublishing` instance.
3743
/// - Parameter container: The dependency injection container used to resolve the required dependencies.
3844
init(container: DIContainer) {
3945
self.analyticsPublisher = container.resolve(AnalyticsPublishing.self)
4046
self.storage = container.resolve(DataStoring.self)
41-
}
42-
43-
/// remove notification observer
44-
deinit {
45-
reset()
46-
}
4747

48-
/// Starts monitoring app lifecycle changes by observing `UIApplication` notifications for
49-
/// background and foreground transitions.
50-
func start() {
5148
// Add observer for when the app enters the background.
5249
NotificationCenter.default.addObserver(
5350
self,
@@ -68,14 +65,24 @@ internal class SessionMonitor: SessionMonitoring, BootUp {
6865
// The problem occurs due to the different lifecycle management between
6966
// these plugins and native iOS apps.
7067
DispatchQueue.main.async { [weak self] in
71-
guard let self = self else { return }
68+
guard let self else { return }
7269
if UIApplication.shared.applicationState == .active && !self.hasInitializedForeground {
7370
self.hasInitializedForeground = true
7471
self.analyticsPublisher.resume()
7572
}
7673
}
7774
}
7875

76+
/// remove notification observer
77+
deinit {
78+
reset()
79+
}
80+
81+
/// Logic to check if the socket is currently open
82+
var isAppActive: Bool {
83+
_isAppActive
84+
}
85+
7986
func reset() {
8087
hasInitializedForeground = false
8188

@@ -98,6 +105,7 @@ internal class SessionMonitor: SessionMonitoring, BootUp {
98105
/// - Parameter notification: The notification object containing information about the event.
99106
@objc
100107
func didEnterBackground(notification: Notification) {
108+
_isAppActive = false
101109
storage.sessionDate = Date()
102110
analyticsPublisher.flush()
103111
}
@@ -107,6 +115,7 @@ internal class SessionMonitor: SessionMonitoring, BootUp {
107115
/// - Parameter notification: The notification object containing information about the event.
108116
@objc
109117
func didEnterForeground(notification: Notification) {
118+
_isAppActive = true
110119
hasInitializedForeground = true
111120
analyticsPublisher.resume()
112121
}

β€ŽSources/Userpilot/DI/DIContainer.swiftβ€Ž

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ internal class DIContainer {
5151
initializers[String(describing: Component.self)] = initializer
5252
}
5353

54+
/// Register the compnenet and resolve it to excute init block
55+
func registerEager<Component>(
56+
_ type: Component.Type,
57+
initializer: @escaping (DIContainer) -> Component
58+
) {
59+
registerLazy(type, initializer: initializer)
60+
_ = resolve(type) // force initialization immediately
61+
}
62+
5463
/**
5564
Registers a lazy initializer for a component type with a default initializer.
5665

β€ŽSources/Userpilot/Experiences/Content/NPS/ContainerView/NPSContainerView.swiftβ€Ž

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -173,15 +173,7 @@ internal class NPSContainerView: UIView {
173173
*/
174174
func resetContentHeight(_ size: CGSize) {
175175
stepsProgressView.setNeedsDisplay()
176-
177-
// Calculate the target height, considering the screen size and a 50-point padding
178-
let targetHeight = min(size.height * 0.7 - 50, viewHeight)
179-
180-
// Update the scroll view height constraint only if necessary
181-
if scrollViewHeightConstraint?.constant != targetHeight {
182-
scrollViewHeightConstraint?.constant = targetHeight
183-
layoutIfNeeded()
184-
}
176+
bindSurveyViews()
185177
}
186178

187179
/**

β€ŽSources/Userpilot/Experiences/Content/NPS/NPSViewModel.swiftβ€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ internal class NPSViewModel {
128128
}
129129

130130
func endNPS(_ completedData: CompletedData?) {
131-
experiencesPublisher.activeOneTimeFlag()
132131
if completedData?.button.buttonAction == .deepLink,
133132
let deepLink = completedData?.button.iosDeepLink,
134133
let url = URL(string: deepLink) {

β€ŽSources/Userpilot/Experiences/Content/Survey/StepView/Base/SurveyContainerView.swiftβ€Ž

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,7 @@ internal class SurveyContainerView: UIView {
129129
*/
130130
func resetContentHeight(_ size: CGSize) {
131131
stepsProgressView.setNeedsDisplay()
132-
133-
// Calculate the target height, considering the screen size and a 50-point padding
134-
let targetHeight = min(size.height * 0.7 - 50, viewHeight)
135-
136-
// Update the scroll view height constraint only if necessary
137-
if scrollViewHeightConstraint?.constant != targetHeight {
138-
scrollViewHeightConstraint?.constant = targetHeight
139-
layoutIfNeeded()
140-
}
132+
bindSurveyViews()
141133
}
142134

143135
/**

β€ŽSources/Userpilot/Experiences/Content/Survey/StepView/Dialog/SurveyDialogViewController.swiftβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ internal class SurveyDialogViewController: DialogViewController {
6363
coordinator.animate(alongsideTransition: { [weak self] _ in
6464
guard let self else { return }
6565
self.surveyContainerView.resetContentHeight(size)
66+
self.resetWidth(size)
6667
}, completion: nil)
6768
}
6869

0 commit comments

Comments
Β (0)