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

Feat: Add custom redact modifier for SwiftUI #4362

Merged
merged 70 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
70 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
f9b75cb
Feat: Custom redact for SwiftUI
brustolin Sep 17, 2024
2bfa15c
Update SentryReplayView.swift
brustolin Sep 17, 2024
75e1cd4
merged
brustolin Sep 18, 2024
5645096
wip
brustolin Sep 20, 2024
063a3ec
Update SentryReplayView.swift
brustolin Sep 20, 2024
492e6db
SwiftUI Custom redact
brustolin Sep 23, 2024
a5a182d
Merge branch 'main' into feat/swiftui-redact
brustolin Sep 23, 2024
c711b15
revert
brustolin Sep 23, 2024
0a38d93
Update SwiftUIViewController.swift
brustolin Sep 23, 2024
ea8f421
Update AppDelegate.swift
brustolin Sep 23, 2024
0e3281c
Apply suggestions from code review
brustolin Sep 23, 2024
02e8733
Update CHANGELOG.md
brustolin Sep 23, 2024
51e21b0
Update UIRedactBuilder.swift
brustolin Sep 23, 2024
fcdfb9a
remove watchOS
brustolin Sep 23, 2024
73bc265
rename modifier
brustolin Sep 24, 2024
745e53b
Refactoring
brustolin Sep 24, 2024
e33b010
Update project.pbxproj
brustolin Sep 24, 2024
daa0bf6
Update SentryTracedView.swift
brustolin Sep 24, 2024
bf26a44
Update Tests/SentryTests/SwiftUI/SentryRedactModifierTests.swift
brustolin Sep 24, 2024
7323444
Update SentryReplayView.swift
brustolin Sep 24, 2024
4c59a39
Merge branch 'feat/swiftui-redact' of https://github.com/getsentry/se…
brustolin Sep 24, 2024
e804604
Merge branch 'main' into feat/swiftui-redact
brustolin Sep 24, 2024
cac4026
Update SentryReplayView.swift
brustolin Sep 24, 2024
61eeb03
Update SentryReplayView.swift
brustolin Sep 24, 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
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Features

- Custom redact modifier for SwiftUI ()

## 8.37.0-beta.1

### Features
Expand All @@ -16,8 +22,8 @@

- Resumes replay when the app becomes active (#4303)
- Session replay redact view with transformation (#4308)
- Correct redact UIView with higher zPosition (#4309)
- Don't redact clipped views (#4325)
- Correct redact UIView with higher zPosition (#4309)
- Session replay for crash not created because of a race condition (#4314)
- Double-quoted include, expected angle-bracketed instead (#4298)
- Discontinue use of NSApplicationSupportDirectory in favor of NSCachesDirectory (#4335)
Expand Down
2 changes: 1 addition & 1 deletion Samples/iOS-Swift/iOS13-Swift/SwiftUIView.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import SentrySwiftUI
import SwiftUI

struct SwiftUIView: View {
struct SwiftUIView: View {
brustolin marked this conversation as resolved.
Show resolved Hide resolved
var body: some View {
SentryTracedView("SwiftUI View") {
Text("SwiftUI!")
Expand Down
2 changes: 1 addition & 1 deletion Samples/iOS-Swift/iOS13-Swift/SwiftUIViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class SwiftUIViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

brustolin marked this conversation as resolved.
Show resolved Hide resolved
addChild(swiftUIView)
view.addSubview(swiftUIView.view)

Expand Down
2 changes: 1 addition & 1 deletion Samples/iOS-SwiftUI/iOS-SwiftUI/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ struct ContentView: View {
Button(action: captureTransactionAction) {
Text("Capture Transaction")
}

}
VStack(spacing: 16) {
Button(action: {
Expand Down Expand Up @@ -200,6 +199,7 @@ struct ContentView: View {
Text("Form Screen")
}
}
.replayRedact()
brustolin marked this conversation as resolved.
Show resolved Hide resolved
}
SecondView()
}
Expand Down
3 changes: 3 additions & 0 deletions Samples/iOS-SwiftUI/iOS-SwiftUI/SwiftUIApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ struct SwiftUIApp: App {
options.debug = true
options.tracesSampleRate = 1.0
options.profilesSampleRate = 1.0
options.experimental.sessionReplay.sessionSampleRate = 1.0
options.experimental.sessionReplay.redactAllImages = false
options.experimental.sessionReplay.redactAllText = false
options.initialScope = { scope in
scope.injectGitInformation()
return scope
Expand Down
4 changes: 4 additions & 0 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,7 @@
D8918B222849FA6D00701F9A /* SentrySDKIntegrationTestsBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8918B212849FA6D00701F9A /* SentrySDKIntegrationTestsBase.swift */; };
D8A3649C2C91AA3300AC569B /* SentryReplayApi.m in Sources */ = {isa = PBXBuildFile; fileRef = D8A3649B2C91AA3300AC569B /* SentryReplayApi.m */; };
D8A3649D2C91AA3300AC569B /* SentryReplayApi.h in Headers */ = {isa = PBXBuildFile; fileRef = D8A3649A2C91AA3300AC569B /* SentryReplayApi.h */; settings = {ATTRIBUTES = (Public, ); }; };
D8A65B5D2C98656800974B74 /* SentryReplayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8A65B5C2C98656000974B74 /* SentryReplayView.swift */; };
D8AB40DB2806EC1900E5E9F7 /* SentryScreenshotIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = D8AB40DA2806EC1900E5E9F7 /* SentryScreenshotIntegration.h */; };
D8ACE3C72762187200F5A213 /* SentryNSDataSwizzling.m in Sources */ = {isa = PBXBuildFile; fileRef = D8ACE3C42762187200F5A213 /* SentryNSDataSwizzling.m */; };
D8ACE3C82762187200F5A213 /* SentryNSDataTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = D8ACE3C52762187200F5A213 /* SentryNSDataTracker.m */; };
Expand Down Expand Up @@ -1964,6 +1965,7 @@
D8918B212849FA6D00701F9A /* SentrySDKIntegrationTestsBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySDKIntegrationTestsBase.swift; sourceTree = "<group>"; };
D8A3649A2C91AA3300AC569B /* SentryReplayApi.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryReplayApi.h; path = Public/SentryReplayApi.h; sourceTree = "<group>"; };
D8A3649B2C91AA3300AC569B /* SentryReplayApi.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryReplayApi.m; sourceTree = "<group>"; };
D8A65B5C2C98656000974B74 /* SentryReplayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryReplayView.swift; sourceTree = "<group>"; };
D8AB40DA2806EC1900E5E9F7 /* SentryScreenshotIntegration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryScreenshotIntegration.h; path = include/SentryScreenshotIntegration.h; sourceTree = "<group>"; };
D8ACE3C42762187200F5A213 /* SentryNSDataSwizzling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SentryNSDataSwizzling.m; sourceTree = "<group>"; };
D8ACE3C52762187200F5A213 /* SentryNSDataTracker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SentryNSDataTracker.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3727,6 +3729,7 @@
D8199DB529376ECC0074249E /* SentrySwiftUI.h */,
D88D25E92B8E0BAC0073C3D5 /* module.modulemap */,
D8199DB629376ECC0074249E /* SentryTracedView.swift */,
D8A65B5C2C98656000974B74 /* SentryReplayView.swift */,
);
path = SentrySwiftUI;
sourceTree = "<group>";
Expand Down Expand Up @@ -5209,6 +5212,7 @@
files = (
D8199DC129376EEC0074249E /* SentryTracedView.swift in Sources */,
D8199DBF29376EE20074249E /* SentryInternal.m in Sources */,
D8A65B5D2C98656800974B74 /* SentryReplayView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
44 changes: 44 additions & 0 deletions Sources/SentrySwiftUI/SentryReplayView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#if SENTRY_NO_UIKIT
import SentryWithoutUIKit
#else
import Sentry
#endif
#if canImport(UIKit)
import SwiftUI
import UIKit

@available(iOS 13, macOS 10.15, tvOS 13, watchOS 6.0, *)
struct SentryReplayView: UIViewRepresentable {
brustolin marked this conversation as resolved.
Show resolved Hide resolved
func makeUIView(context: Context) -> UIView {
let result = UIView()
result.sentryReplayRedact()
return result
}

func updateUIView(_ uiView: UIView, context: Context) {
// This is blank on purpose. UIViewRepresentable requires this function.
}
}

struct SentryReplayModifier: ViewModifier {
func body(content: Content) -> some View {
content.background(SentryReplayView())
}
}

@available(iOS 13, macOS 10.15, tvOS 13, watchOS 6.0, *)
public extension View {

/// Marks the view as containing sensitive information that should be redacted during replays.
///
/// When this modifier is applied, any sensitive content within the view will be hidden or masked
/// during session replays to ensure user privacy. This is useful for views containing personal
/// data or confidential information that shouldn't be visible when the replay is reviewed.
///
/// - Returns: A modifier that redacts sensitive information during session replays.
///
func replayRedact() -> some View {
brustolin marked this conversation as resolved.
Show resolved Hide resolved
modifier(SentryReplayModifier())
}
}
#endif
3 changes: 1 addition & 2 deletions Sources/Swift/Tools/UIRedactBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ class UIRedactBuilder {
redacting: &redactingRegions,
rootFrame: view.frame,
transform: CGAffineTransform.identity)

return redactingRegions.reversed()
}

Expand All @@ -181,7 +180,7 @@ class UIRedactBuilder {

private func mapRedactRegion(fromView view: UIView, redacting: inout [RedactRegion], rootFrame: CGRect, transform: CGAffineTransform, forceRedact: Bool = false) {
guard !redactClassesIdentifiers.isEmpty && !view.isHidden && view.alpha != 0 else { return }

brustolin marked this conversation as resolved.
Show resolved Hide resolved
let layer = view.layer.presentation() ?? view.layer

let newTransform = concatenateTranform(transform, with: layer)
Expand Down
Loading