Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ref: Changing the redact logic #4327

Merged
merged 55 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
55 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
b78b307
fix: Dont redact clipped views
brustolin Sep 11, 2024
fa35276
Update CHANGELOG.md
brustolin Sep 11, 2024
5046131
Update CHANGELOG.md
brustolin Sep 11, 2024
1b5790f
Merge branch 'main' into fix/redact-under-translucent
brustolin Sep 11, 2024
31c1cdc
Merge branch 'fix/redact-under-translucent' into fix/out-of-clip-redact
brustolin Sep 11, 2024
ee68606
Update UIRedactBuilder.swift
brustolin Sep 11, 2024
293027a
feat: Redact logic
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
32774d5
Merge branch 'fix/redact-under-translucent' into fix/redact-logic
brustolin Sep 12, 2024
993390e
Format code
getsentry-bot Sep 12, 2024
33921f0
Update CHANGELOG.md
brustolin Sep 12, 2024
25dc3f8
Merge branch 'fix/redact-logic' of https://github.com/getsentry/sentr…
brustolin Sep 12, 2024
fb56b85
Merge branch 'fix/redact-under-translucent' into fix/out-of-clip-redact
brustolin Sep 12, 2024
6c69214
Merge branch 'fix/out-of-clip-redact' into fix/redact-logic
brustolin Sep 12, 2024
988420b
fix tests
brustolin Sep 12, 2024
878ff3b
some ref
brustolin Sep 12, 2024
19eae17
Format code
getsentry-bot Sep 12, 2024
73d292c
Update UIRedactBuilder.swift
brustolin Sep 12, 2024
87263c7
Merge branch 'fix/redact-logic' of https://github.com/getsentry/sentr…
brustolin Sep 12, 2024
c1ea803
Update UIRedactBuilder.swift
brustolin Sep 12, 2024
5ddbb30
Update UIRedactBuilder.swift
brustolin Sep 12, 2024
895a25e
redact as enforced
brustolin Sep 13, 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
4d7ab08
Update UIRedactBuilder.swift
brustolin Sep 13, 2024
3bc34ab
Update UIRedactBuilder.swift
brustolin Sep 13, 2024
bd2b4ee
renaming
brustolin Sep 16, 2024
291bbaf
Merge branch 'fix/redact-under-translucent' into fix/redact-logic
brustolin Sep 16, 2024
a8a39c2
Merge branch 'main' into fix/redact-logic
brustolin Sep 17, 2024
d98a655
Format code
getsentry-bot Sep 17, 2024
57a9d0c
Update UIRedactBuilder.swift
brustolin Sep 17, 2024
f634c33
Merge branch 'fix/redact-logic' of https://github.com/getsentry/sentr…
brustolin Sep 17, 2024
2118ebf
Revert "Merge branch 'fix/redact-logic' of https://github.com/getsent…
brustolin Sep 17, 2024
c76c9e0
Update CHANGELOG.md
brustolin Sep 17, 2024
4e42327
Format code
getsentry-bot Sep 17, 2024
677b7f4
Merge branch 'main' into fix/redact-logic
brustolin Sep 17, 2024
d9bce05
Apply suggestions from code review
brustolin Sep 18, 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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@
### Fixes

- Resumes replay when the app becomes active (#4303)
- Session replay redact view with transformation (#4308)
- Don't redact clipped views (#4325)
brustolin marked this conversation as resolved.
Show resolved Hide resolved
- Correct redact UIView with higher zPosition (#4309)
- Don't redact clipped views (#4325)
- Session replay for crash not created because of a race condition (#4314)
- Double-quoted include, expected angle-bracketed instead (#4298)
- Stop using `redactAllText` as an indicator tha redact is enabled (#4327)

## 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 @@ -102,6 +102,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 /* SRRedactSampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8DA29032C7F2199008BC825 /* SRRedactSampleViewController.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 @@ -361,6 +362,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 /* SRRedactSampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRRedactSampleViewController.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 @@ -606,6 +608,7 @@
D8832B1D2AF52D0500C522B0 /* PageViewController.swift */,
B70038842BB33E7700065A38 /* ReplaceContentViewController.swift */,
D8AE48C82C57DC2F0092A2A6 /* WebViewController.swift */,
D8DA29032C7F2199008BC825 /* SRRedactSampleViewController.swift */,
);
path = ViewControllers;
sourceTree = "<group>";
Expand Down Expand Up @@ -1068,6 +1071,7 @@
D8444E4C275E38090042F4DE /* UIViewControllerExtension.swift in Sources */,
637AFDAE243B02760034958B /* TransactionsViewController.swift in Sources */,
D8832B132AF4F7FE00C522B0 /* TopViewControllerInspector.swift in Sources */,
D8DA29042C7F2199008BC825 /* SRRedactSampleViewController.swift in Sources */,
0AABE2EA28855FF80057ED69 /* PermissionsViewController.swift in Sources */,
7B5525B32938B5B5006A2932 /* DiskWriteException.swift in Sources */,
84BA72A72C93698E0045B828 /* GitInjections.swift in Sources */,
Expand Down
104 changes: 92 additions & 12 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,17 @@
import Foundation

class SRRedactSampleViewController: UIViewController {

@IBOutlet var notRedactedView: UIView!

@IBOutlet var label: UILabel!

override func viewDidLoad() {
super.viewDidLoad()

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

SentrySDK.replay.ignoreView(notRedactedView)
}
}
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 @@ -885,7 +886,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 @@ -1873,6 +1873,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 @@ -1957,7 +1958,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 @@ -3702,10 +3702,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 @@ -4830,6 +4830,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 @@ -4958,7 +4959,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
7 changes: 3 additions & 4 deletions Sources/Sentry/PrivateSentrySDKOnly.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#import "SentryOptions.h"
#import "SentrySDK+Private.h"
#import "SentrySerialization.h"
#import "SentrySessionReplayIntegration.h"
#import "SentrySessionReplayIntegration+Private.h"
#import "SentrySwift.h"
#import "SentryThreadHandle.hpp"
#import "SentryUser+Private.h"
Expand All @@ -21,7 +21,6 @@
#import <SentryFramesTracker.h>
#import <SentryScope+Private.h>
#import <SentryScreenshot.h>
#import <SentrySessionReplayIntegration.h>
#import <SentryUser.h>

#if SENTRY_TARGET_PROFILING_SUPPORTED
Expand Down Expand Up @@ -351,12 +350,12 @@ + (NSString *__nullable)getReplayId

+ (void)addReplayIgnoreClasses:(NSArray<Class> *_Nonnull)classes
{
[SentryViewPhotographer.shared addIgnoreClasses:classes];
[[PrivateSentrySDKOnly getReplayIntegration].viewPhotographer addIgnoreClasses:classes];
}

+ (void)addReplayRedactClasses:(NSArray<Class> *_Nonnull)classes
{
[SentryViewPhotographer.shared addRedactClasses:classes];
[[PrivateSentrySDKOnly getReplayIntegration].viewPhotographer addRedactClasses:classes];
}
#endif

Expand Down
6 changes: 3 additions & 3 deletions Sources/Sentry/SentrySessionReplayIntegration.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ - (BOOL)installWithOptions:(nonnull SentryOptions *)options
}

_replayOptions = options.experimental.sessionReplay;
_viewPhotographer =
[[SentryViewPhotographer alloc] initWithRedactOptions:options.experimental.sessionReplay];

if (options.enableSwizzling) {
_touchTracker = [[SentryTouchTracker alloc]
Expand All @@ -86,8 +88,6 @@ - (BOOL)installWithOptions:(nonnull SentryOptions *)options
}];

[SentryDependencyContainer.sharedInstance.reachability addObserver:self];
[SentryViewPhotographer.shared addIgnoreClasses:_replayOptions.ignoreRedactViewTypes];
[SentryViewPhotographer.shared addRedactClasses:_replayOptions.redactViewTypes];

_installedInstance = self;
return YES;
Expand Down Expand Up @@ -236,7 +236,7 @@ - (void)startWithOptions:(SentryReplayOptions *)replayOptions
fullSession:(BOOL)shouldReplayFullSession
{
[self startWithOptions:replayOptions
screenshotProvider:SentryViewPhotographer.shared
screenshotProvider:_viewPhotographer
breadcrumbConverter:[[SentrySRDefaultBreadcrumbConverter alloc] init]
fullSession:shouldReplayFullSession];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
#if SENTRY_TARGET_REPLAY_SUPPORTED

@class SentrySessionReplay;
@class SentryViewPhotographer;

@interface
SentrySessionReplayIntegration () <SentryIntegrationProtocol, SentrySessionListener,
SentrySessionReplayDelegate>

@property (nonatomic, strong) SentrySessionReplay *sessionReplay;

@property (nonatomic, strong) SentryViewPhotographer *viewPhotographer;

@end

#endif
4 changes: 2 additions & 2 deletions Sources/Swift/Extensions/UIViewExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public extension UIView {

/**
* Marks this view to be redacted during replays.
* - warning: This is an experimental feature and may still have bugs.
* - experiment: This is an experimental feature and may still have bugs.
*/
func sentryReplayRedact() {
SentryRedactViewHelper.redactView(self)
Expand All @@ -16,7 +16,7 @@ public extension UIView {
/**
* Marks this view to be ignored during redact step
* of session replay. All its content will be visible in the replay.
* - warning: This is an experimental feature and may still have bugs.
* - experiment: This is an experimental feature and may still have bugs.
*/
func sentryReplayIgnore() {
SentryRedactViewHelper.ignoreView(self)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,18 @@ public class SentryReplayOptions: NSObject, SentryRedactOptions {
/**
* A list of custom UIView subclasses that need
* to be masked during session replay.
* By default Sentry already mask text elements from UIKit
* By default Sentry already mask text and image elements from UIKit
* Every child of a view that is redacted will also be redacted.
*/
public var redactViewTypes = [AnyClass]()
public var redactViewClasses = [AnyClass]()

/**
* A list of custom UIView subclasses to be ignored
* during masking step of the session replay.
* The view itself and any child will be ignored and not masked.
* The views of given classes will not be redacted but their children may be.
* This property has precedence over `redactViewTypes`.
*/
public var ignoreRedactViewTypes = [AnyClass]()
public var ignoreViewClasses = [AnyClass]()

/**
* Defines the quality of the session replay.
Expand Down
2 changes: 2 additions & 0 deletions Sources/Swift/Protocol/SentryRedactOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ import Foundation
protocol SentryRedactOptions {
var redactAllText: Bool { get }
var redactAllImages: Bool { get }
var redactViewClasses: [AnyClass] { get }
var ignoreViewClasses: [AnyClass] { get }
}
67 changes: 57 additions & 10 deletions Sources/Swift/Tools/SentryViewPhotographer.swift
Original file line number Diff line number Diff line change
@@ -1,32 +1,79 @@
#if canImport(UIKit) && !SENTRY_NO_UIKIT
#if os(iOS) || os(tvOS)

@_implementationOnly import _SentryPrivate
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 {
private let redactBuilder: UIRedactBuilder
private let dispatchQueue = SentryDispatchQueueWrapper()

var renderer: ViewRenderer

init(renderer: ViewRenderer, redactOptions: SentryRedactOptions) {
self.renderer = renderer
redactBuilder = UIRedactBuilder(options: redactOptions)
super.init()
}

static let shared = SentryViewPhotographer()

private let redactBuilder = UIRedactBuilder()
init(redactOptions: SentryRedactOptions) {
self.renderer = DefaultViewRenderer()
self.redactBuilder = UIRedactBuilder(options: redactOptions)
}

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 redact = redactBuilder.redactRegionsFor(view: view)
let imageSize = view.bounds.size
DispatchQueue.global().async {
dispatchQueue.dispatchAsync {
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)
UIColor.blue.setStroke()

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)
let rect = CGRect(origin: CGPoint.zero, size: region.size)
var transform = region.transform
let path = CGPath(rect: rect, transform: &transform)

switch region.type {
case .redact:
(region.color ?? UIImageHelper.averageColor(of: context.currentImage, at: rect.applying(region.transform))).setFill()
context.cgContext.addPath(path)
context.cgContext.fillPath()
case .clipOut:
context.cgContext.addRect(context.cgContext.boundingBoxOfClipPath)
context.cgContext.addPath(path)
context.cgContext.clip(using: .evenOdd)
case .clipBegin:
context.cgContext.saveGState()
context.cgContext.resetClip()
context.cgContext.addPath(path)
context.cgContext.clip()
case .clipEnd:
context.cgContext.restoreGState()
}
}
}
onComplete(screenshot)
Expand Down
Loading
Loading