Skip to content

Commit

Permalink
feat(replay): skip snapshot during view controller transitions (#265)
Browse files Browse the repository at this point in the history
* feat(replay): skip snapshot during view controller transitions

* chore: update CHANGELOG

* fix: check for animated transitions only in root vc
  • Loading branch information
ioannisj authored Nov 28, 2024
1 parent 3c130a8 commit d90f0c7
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Next

- fix: skip capturing a snapshot during view controller transitions ([#265](https://github.com/PostHog/posthog-ios/pull/265))

## 3.15.8 - 2024-11-28

- no user facing changes
Expand Down
8 changes: 7 additions & 1 deletion PostHog/Replay/PostHogReplayIntegration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,8 @@
}

private func toScreenshotWireframe(_ window: UIWindow) -> RRWireframe? {
if !window.isVisible() {
// this will bail on interactive animations (e.g edge slide)
if !window.isVisible() || isAnimatingTransition(window) {
return nil
}

Expand All @@ -394,6 +395,11 @@
return wireframe
}

/// Check if window's root view controller is animating a transition
private func isAnimatingTransition(_ window: UIWindow) -> Bool {
window.rootViewController?.transitionCoordinator?.isAnimated ?? false
}

private func isAssetsImage(_ image: UIImage) -> Bool {
// https://github.com/daydreamboy/lldb_scripts#9-pimage
// do not mask if its an asset image, likely not PII anyway
Expand Down
6 changes: 5 additions & 1 deletion PostHog/Replay/UIView+Util.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@
let renderer = UIGraphicsImageRenderer(size: size, format: rendererFormat)

let image = renderer.image { _ in
drawHierarchy(in: bounds, afterScreenUpdates: false)
// true for afterScreenUpdates so that we capture view *after* any pending animations are committed
// As a side effect, we need to pause view tracker temporarily to avoid recursive calls since this option will cause subviews to layout, which will then trigger another capture
ViewLayoutTracker.paused = true
drawHierarchy(in: bounds, afterScreenUpdates: true)
ViewLayoutTracker.paused = false
}

return image
Expand Down
5 changes: 4 additions & 1 deletion PostHog/Replay/ViewLayoutTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
import UIKit

enum ViewLayoutTracker {
static var hasChanges = false
static var paused = false
private(set) static var hasChanges = false
private static var hasSwizzled = false

static func viewDidLayout(view _: UIView) {
guard !paused else { return }
hasChanges = true
}

static func clear() {
guard !paused else { return }
hasChanges = false
}

Expand Down

0 comments on commit d90f0c7

Please sign in to comment.