Skip to content

Commit

Permalink
ref: Session replay performance for SwiftUI (#4419)
Browse files Browse the repository at this point in the history
Improved Performance for SwiftUI session replay
  • Loading branch information
brustolin authored Oct 10, 2024
1 parent 40e71d9 commit 6a7ed71
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ via the option `swizzleClassNameExclude`.
### Improvements

- Serializing profile on a BG Thread (#4377) to avoid potentially slightly blocking the main thread.
- Session Replay performance for SwiftUI (#4419)

## 8.38.0-beta.1

Expand Down
2 changes: 1 addition & 1 deletion Sources/Sentry/SentrySessionReplayIntegration.m
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ - (void)startWithOptions:(SentryReplayOptions *)replayOptions

[self.sessionReplay
startWithRootView:SentryDependencyContainer.sharedInstance.application.windows.firstObject
fullSession:[self shouldReplayFullSession:replayOptions.sessionSampleRate]];
fullSession:shouldReplayFullSession];

[_notificationCenter addObserver:self
selector:@selector(pause)
Expand Down
6 changes: 6 additions & 0 deletions Sources/Swift/Tools/SentryViewPhotographer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,24 @@ class SentryViewPhotographer: NSObject, SentryViewScreenshotProvider {
dispatchQueue.dispatchAsync {
let screenshot = UIGraphicsImageRenderer(size: imageSize, format: .init(for: .init(displayScale: 1))).image { context in

let imageRect = CGRect(origin: .zero, size: imageSize)
context.cgContext.addRect(CGRect(origin: CGPoint.zero, size: imageSize))
context.cgContext.clip(using: .evenOdd)
UIColor.blue.setStroke()

context.cgContext.interpolationQuality = .none
image.draw(at: .zero)

var latestRegion: RedactRegion?
for region in redact {
let rect = CGRect(origin: CGPoint.zero, size: region.size)
var transform = region.transform
let path = CGPath(rect: rect, transform: &transform)

defer { latestRegion = region }

guard latestRegion?.canReplace(as: region) != true && imageRect.intersects(path.boundingBoxOfPath) else { continue }

switch region.type {
case .redact, .redactSwiftUI:
(region.color ?? UIImageHelper.averageColor(of: context.currentImage, at: rect.applying(region.transform))).setFill()
Expand Down
6 changes: 5 additions & 1 deletion Sources/Swift/Tools/UIRedactBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ struct RedactRegion {
self.type = type
self.color = color
}

func canReplace(as other: RedactRegion) -> Bool {
size == other.size && transform == other.transform && type == other.type
}
}

class UIRedactBuilder {
Expand Down Expand Up @@ -170,7 +174,7 @@ class UIRedactBuilder {
}

//The swiftUI type needs to appear first in the list so it always get masked
return swiftUIRedact + otherRegions.reversed()
return (otherRegions + swiftUIRedact).reversed()
}

private func shouldIgnore(view: UIView) -> Bool {
Expand Down
15 changes: 15 additions & 0 deletions Tests/SentryTests/SentryViewPhotographerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,21 @@ class SentryViewPhotographerTests: XCTestCase {
assertColor(pixel2, .white)
}

func testSkipSameRegion() throws {
let label1 = UILabel(frame: CGRect(x: 0, y: 0, width: 50, height: 25))
label1.text = "Test"
label1.textColor = .red

let label2 = UILabel(frame: CGRect(x: 0, y: 0, width: 50, height: 25))
label2.text = "Test"
label2.textColor = .green

let image = try XCTUnwrap(prepare(views: [label1, label2]))
let pixel1 = color(at: CGPoint(x: 10, y: 10), in: image)

assertColor(pixel1, .green)
}

private func assertColor(_ color1: UIColor, _ color2: UIColor) {
let sRGBColor1 = color1.cgColor.converted(to: CGColorSpace(name: CGColorSpace.sRGB)!, intent: .defaultIntent, options: nil)
let sRGBColor2 = color2.cgColor.converted(to: CGColorSpace(name: CGColorSpace.sRGB)!, intent: .defaultIntent, options: nil)
Expand Down

0 comments on commit 6a7ed71

Please sign in to comment.