Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c57613f
wip
brustolin Aug 29, 2024
8459cc9
test in progress
brustolin Sep 2, 2024
364cb77
fix: Session Replay redact for transformed views
brustolin Sep 3, 2024
0bcb7df
Update CHANGELOG.md
brustolin Sep 3, 2024
15f94cd
ref
brustolin Sep 3, 2024
c1fa693
Update SentryViewPhotographerTests.swift
brustolin Sep 3, 2024
ffdf298
Update Main.storyboard
brustolin Sep 3, 2024
10ca7fd
Apply suggestions from code review
brustolin Sep 5, 2024
594d8a6
Update Sources/Swift/Tools/UIRedactBuilder.swift
brustolin Sep 5, 2024
cfb1ec7
ref
brustolin Sep 5, 2024
4cc5ba8
Merge branch 'fix/redact-under-translucent' of https://github.com/get…
brustolin Sep 5, 2024
2fae00a
ref
brustolin Sep 6, 2024
b1d9eec
ref
brustolin Sep 6, 2024
adc9c57
Merge branch 'main' into fix/redact-under-translucent
brustolin Sep 6, 2024
e0f6d24
ref
brustolin Sep 9, 2024
1b5790f
Merge branch 'main' into fix/redact-under-translucent
brustolin Sep 11, 2024
ee68606
Update UIRedactBuilder.swift
brustolin Sep 11, 2024
0b3d916
Update UIRedactBuilder.swift
brustolin Sep 12, 2024
30077ce
Merge branch 'main' into fix/redact-under-translucent
brustolin Sep 12, 2024
35bb1e7
Update SRRedactSampleViewController.swift
brustolin Sep 12, 2024
cf60b5e
fix: Don't redact clipped views (#4325)
brustolin Sep 13, 2024
7878f04
Correct redact UIView with higher zPosition (#4309)
brustolin Sep 13, 2024
48489b5
Merge branch 'main' into fix/redact-under-translucent
brustolin Sep 13, 2024
3bc34ab
Update UIRedactBuilder.swift
brustolin Sep 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Fixes

- Resumes replay when the app becomes active (#4303)
- Session replay redact view with transformation (#4308)

## 8.36.0

Expand Down
4 changes: 4 additions & 0 deletions Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
D8D7BB4A2750067900044146 /* UIAssert.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8D7BB492750067900044146 /* UIAssert.swift */; };
D8D7BB4C2750095800044146 /* UIViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8D7BB4B2750095800044146 /* UIViewExtension.swift */; };
D8D7BB4E27501B9400044146 /* SpanObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8D7BB4D27501B9400044146 /* SpanObserver.swift */; };
D8DA29042C7F2199008BC825 /* UITestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8DA29032C7F2199008BC825 /* UITestViewController.swift */; };
D8DBDA76274D591F00007380 /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8DBDA75274D591F00007380 /* TableViewController.swift */; };
D8DBDA78274D5FC400007380 /* SplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8DBDA77274D5FC400007380 /* SplitViewController.swift */; };
D8F01DEA2A1376B5008F4996 /* InfoForBreadcrumbController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F01DE92A1376B5008F4996 /* InfoForBreadcrumbController.swift */; };
Expand Down Expand Up @@ -354,6 +355,7 @@
D8D7BB492750067900044146 /* UIAssert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAssert.swift; sourceTree = "<group>"; };
D8D7BB4B2750095800044146 /* UIViewExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewExtension.swift; sourceTree = "<group>"; };
D8D7BB4D27501B9400044146 /* SpanObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpanObserver.swift; sourceTree = "<group>"; };
D8DA29032C7F2199008BC825 /* UITestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestViewController.swift; sourceTree = "<group>"; };
D8DBDA75274D591F00007380 /* TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = "<group>"; };
D8DBDA77274D5FC400007380 /* SplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitViewController.swift; sourceTree = "<group>"; };
D8F01DE92A1376B5008F4996 /* InfoForBreadcrumbController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoForBreadcrumbController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -588,6 +590,7 @@
D8832B1D2AF52D0500C522B0 /* PageViewController.swift */,
B70038842BB33E7700065A38 /* ReplaceContentViewController.swift */,
D8AE48C82C57DC2F0092A2A6 /* WebViewController.swift */,
D8DA29032C7F2199008BC825 /* UITestViewController.swift */,
);
path = ViewControllers;
sourceTree = "<group>";
Expand Down Expand Up @@ -932,6 +935,7 @@
D8444E4C275E38090042F4DE /* UIViewControllerExtension.swift in Sources */,
637AFDAE243B02760034958B /* TransactionsViewController.swift in Sources */,
D8832B132AF4F7FE00C522B0 /* TopViewControllerInspector.swift in Sources */,
D8DA29042C7F2199008BC825 /* UITestViewController.swift in Sources */,
0AABE2EA28855FF80057ED69 /* PermissionsViewController.swift in Sources */,
7B5525B32938B5B5006A2932 /* DiskWriteException.swift in Sources */,
D8F3D062274EBD4800B56F8C /* SpanExtension.swift in Sources */,
Expand Down
92 changes: 82 additions & 10 deletions Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Foundation

class TargetView: UIView {

}

class UITestViewController: UIViewController {

@IBOutlet var transparentView: UIView!

@IBOutlet var label: UILabel!

override func viewDidLoad() {
super.viewDidLoad()

transparentView.backgroundColor = .green
transparentView.transform = CGAffineTransform(rotationAngle: 45 * .pi / 180.0)

SentrySDK.replayIgnore(transparentView)
}

@IBAction func showAlert(_ sender: UIButton) {

}

}
8 changes: 4 additions & 4 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,7 @@
D820CDB82BB1895F00BA339D /* SentrySessionReplayIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = D820CDB52BB1895F00BA339D /* SentrySessionReplayIntegration.h */; };
D82859432C3E753C009A28AA /* SentrySessionReplaySyncC.c in Sources */ = {isa = PBXBuildFile; fileRef = D82859422C3E753C009A28AA /* SentrySessionReplaySyncC.c */; };
D82859442C3E753C009A28AA /* SentrySessionReplaySyncC.h in Headers */ = {isa = PBXBuildFile; fileRef = D82859412C3E753C009A28AA /* SentrySessionReplaySyncC.h */; };
D82915632C85EF0C00A6CDD4 /* SentryViewPhotographerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D82915622C85EF0C00A6CDD4 /* SentryViewPhotographerTests.swift */; };
D8292D7D2A39A027009872F7 /* UrlSanitizedTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8292D7C2A39A027009872F7 /* UrlSanitizedTests.swift */; };
D82DD1CD2BEEB1A0001AB556 /* SentrySRDefaultBreadcrumbConverterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D82DD1CC2BEEB1A0001AB556 /* SentrySRDefaultBreadcrumbConverterTests.swift */; };
D8370B6A273DF1E900F66E2D /* SentryNSURLSessionTaskSearch.m in Sources */ = {isa = PBXBuildFile; fileRef = D8370B68273DF1E900F66E2D /* SentryNSURLSessionTaskSearch.m */; };
Expand Down Expand Up @@ -883,7 +884,6 @@
D8AFC01A2BD7A20B00118BE1 /* SentryViewScreenshotProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8AFC0192BD7A20B00118BE1 /* SentryViewScreenshotProvider.swift */; };
D8AFC03D2BDA79BF00118BE1 /* SentryReplayVideoMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8AFC03C2BDA79BF00118BE1 /* SentryReplayVideoMaker.swift */; };
D8AFC0572BDA895400118BE1 /* UIRedactBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8AFC0562BDA895400118BE1 /* UIRedactBuilder.swift */; };
D8AFC05A2BDA89C100118BE1 /* RedactRegionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8AFC0582BDA899A00118BE1 /* RedactRegionTests.swift */; };
D8B0542E2A7D2C720056BAF6 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = D8B0542D2A7D2C720056BAF6 /* PrivacyInfo.xcprivacy */; };
D8B088B629C9E3FF00213258 /* SentryTracerConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = D8B088B429C9E3FF00213258 /* SentryTracerConfiguration.h */; };
D8B088B729C9E3FF00213258 /* SentryTracerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = D8B088B529C9E3FF00213258 /* SentryTracerConfiguration.m */; };
Expand Down Expand Up @@ -1871,6 +1871,7 @@
D820CDB62BB1895F00BA339D /* SentrySessionReplayIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySessionReplayIntegration.m; sourceTree = "<group>"; };
D82859412C3E753C009A28AA /* SentrySessionReplaySyncC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentrySessionReplaySyncC.h; path = include/SentrySessionReplaySyncC.h; sourceTree = "<group>"; };
D82859422C3E753C009A28AA /* SentrySessionReplaySyncC.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SentrySessionReplaySyncC.c; sourceTree = "<group>"; };
D82915622C85EF0C00A6CDD4 /* SentryViewPhotographerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryViewPhotographerTests.swift; sourceTree = "<group>"; };
D8292D7A2A38AF04009872F7 /* HTTPHeaderSanitizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPHeaderSanitizer.swift; sourceTree = "<group>"; };
D8292D7C2A39A027009872F7 /* UrlSanitizedTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UrlSanitizedTests.swift; sourceTree = "<group>"; };
D82DD1CC2BEEB1A0001AB556 /* SentrySRDefaultBreadcrumbConverterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySRDefaultBreadcrumbConverterTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1953,7 +1954,6 @@
D8AFC0192BD7A20B00118BE1 /* SentryViewScreenshotProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryViewScreenshotProvider.swift; sourceTree = "<group>"; };
D8AFC03C2BDA79BF00118BE1 /* SentryReplayVideoMaker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryReplayVideoMaker.swift; sourceTree = "<group>"; };
D8AFC0562BDA895400118BE1 /* UIRedactBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIRedactBuilder.swift; sourceTree = "<group>"; };
D8AFC0582BDA899A00118BE1 /* RedactRegionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedactRegionTests.swift; sourceTree = "<group>"; };
D8AFC0612BDBEDF100118BE1 /* SentrySessionReplayIntegration+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentrySessionReplayIntegration+Private.h"; path = "include/SentrySessionReplayIntegration+Private.h"; sourceTree = "<group>"; };
D8B0542D2A7D2C720056BAF6 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
D8B088B429C9E3FF00213258 /* SentryTracerConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryTracerConfiguration.h; path = include/SentryTracerConfiguration.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3696,10 +3696,10 @@
D84541192A2DC55100E2B11C /* SentryBinaryImageCache+Private.h */,
D8292D7C2A39A027009872F7 /* UrlSanitizedTests.swift */,
D8F8F5562B835BC600AC5465 /* SentryMsgPackSerializerTests.m */,
D8AFC0582BDA899A00118BE1 /* RedactRegionTests.swift */,
D8F67AEF2BE0D31A00C9197B /* UIImageHelperTests.swift */,
D8F67AF22BE10F7600C9197B /* UIRedactBuilderTests.swift */,
51B15F7F2BE88D510026A2F2 /* URLSessionTaskHelperTests.swift */,
D82915622C85EF0C00A6CDD4 /* SentryViewPhotographerTests.swift */,
);
name = Tools;
sourceTree = "<group>";
Expand Down Expand Up @@ -4822,6 +4822,7 @@
63FE722420DA66EC00CDBAE8 /* SentryCrashMonitor_NSException_Tests.m in Sources */,
7B5AB65D27E48E5200F1D1BA /* TestThreadInspector.swift in Sources */,
7BF9EF742722A85B00B5BBEF /* SentryClassRegistrator.m in Sources */,
D82915632C85EF0C00A6CDD4 /* SentryViewPhotographerTests.swift in Sources */,
D8DBE0CA2C0E093000FAB1FD /* SentryTouchTrackerTests.swift in Sources */,
D8F67AF42BE10F9600C9197B /* UIRedactBuilderTests.swift in Sources */,
63B819141EC352A7002FDF4C /* SentryInterfacesTests.m in Sources */,
Expand Down Expand Up @@ -4950,7 +4951,6 @@
62BAD74E2BA1C58D00EBAAFC /* EncodeMetricTests.swift in Sources */,
7BE0DC29272A9E1C004FA8B7 /* SentryBreadcrumbTrackerTests.swift in Sources */,
63FE722520DA66EC00CDBAE8 /* SentryCrashFileUtils_Tests.m in Sources */,
D8AFC05A2BDA89C100118BE1 /* RedactRegionTests.swift in Sources */,
D86130122BB563FD004C0F5E /* SentrySessionReplayIntegrationTests.swift in Sources */,
7BFC16BA2524D4AF00FF6266 /* SentryMessage+Equality.m in Sources */,
7B4260342630315C00B36EDD /* SampleError.swift in Sources */,
Expand Down
51 changes: 44 additions & 7 deletions Sources/Swift/Tools/SentryViewPhotographer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,65 @@ import CoreGraphics
import Foundation
import UIKit

protocol ViewRenderer {
func render(view: UIView) -> UIImage
}

class DefaultViewRenderer: ViewRenderer {
func render(view: UIView) -> UIImage {
let image = UIGraphicsImageRenderer(size: view.bounds.size).image { _ in
view.drawHierarchy(in: view.bounds, afterScreenUpdates: false)
}
return image
}
}

@objcMembers
class SentryViewPhotographer: NSObject, SentryViewScreenshotProvider {

static let shared = SentryViewPhotographer()

private let redactBuilder = UIRedactBuilder()

var renderer: ViewRenderer

init(renderer: ViewRenderer) {
self.renderer = renderer
super.init()
}

private convenience override init() {
self.init(renderer: DefaultViewRenderer())
}

func image(view: UIView, options: SentryRedactOptions, onComplete: @escaping ScreenshotCallback ) {
let image = UIGraphicsImageRenderer(size: view.bounds.size).image { _ in
view.drawHierarchy(in: view.bounds, afterScreenUpdates: false)
}
let image = renderer.render(view: view)

let redact = redactBuilder.redactRegionsFor(view: view, options: options)
let imageSize = view.bounds.size
DispatchQueue.global().async {
let screenshot = UIGraphicsImageRenderer(size: imageSize, format: .init(for: .init(displayScale: 1))).image { context in

context.cgContext.addRect(CGRect(origin: CGPoint.zero, size: imageSize))
context.cgContext.clip(using: .evenOdd)

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

for region in redact {
(region.color ?? UIImageHelper.averageColor(of: context.currentImage, at: region.rect)).setFill()
context.fill(region.rect)
context.cgContext.saveGState()
context.cgContext.concatenate(region.transform)

let rect = CGRect(origin: CGPoint.zero, size: region.size)
switch region.type {
case .redact:
(region.color ?? UIImageHelper.averageColor(of: context.currentImage, at: rect)).setFill()
context.fill(rect)
context.cgContext.restoreGState()
case .clip:
context.cgContext.addRect(context.cgContext.boundingBoxOfClipPath)
context.cgContext.addRect(rect)
context.cgContext.restoreGState()
context.cgContext.clip(using: .evenOdd)
}
}
}
onComplete(screenshot)
Expand Down
Loading