Skip to content

Commit beb7ff7

Browse files
authored
feat(Session Replay): Track touches for replay (#4041)
Added a touch tracker to send touch events with replays
1 parent e70a2e1 commit beb7ff7

19 files changed

+718
-24
lines changed

.swiftlint.yml

+1-10
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ excluded:
1010
- SentryTestUtils/Dynamic/**
1111

1212
only_rules:
13-
#- attributes
1413
- class_delegate_protocol
1514
- closing_brace
1615
- closure_end_indentation
@@ -19,16 +18,13 @@ only_rules:
1918
- colon
2019
- comma
2120
- compiler_protocol_init
22-
#- conditional_returns_on_newline
2321
- control_statement
2422
- custom_rules
2523
- cyclomatic_complexity
2624
- dynamic_inline
27-
- empty_count
2825
- empty_parameters
2926
- empty_parentheses_with_trailing_closure
3027
- explicit_init
31-
#- file_header
3228
- file_length
3329
- first_where
3430
- force_cast
@@ -45,8 +41,6 @@ only_rules:
4541
- legacy_nsgeometry_functions
4642
- line_length
4743
- mark
48-
#- missing_docs
49-
#- nesting
5044
- nimble_operator
5145
- number_separator
5246
- object_literal
@@ -65,13 +59,11 @@ only_rules:
6559
- shorthand_operator
6660
- sorted_imports
6761
- statement_position
68-
- switch_case_on_newline
6962
- syntactic_sugar
7063
- todo
7164
- trailing_comma
7265
- trailing_newline
7366
- trailing_semicolon
74-
#- trailing_whitespace
7567
- type_body_length
7668
- type_name
7769
- unused_closure_parameter
@@ -90,12 +82,11 @@ identifier_name:
9082
- i
9183
- _
9284
min_length:
93-
- 2
85+
- 1
9486
max_length:
9587
warning: 50
9688
error: 50
9789

98-
9990
line_length:
10091
- 1000
10192
type_name:

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
### Features
66

7+
- Add a touch tracker for replay (#4041)
78
- Add enableMetricKitRawPayload (#4044)
89

910
### Fixes
11+
1012
- `SentryCrashMonitor_CPPException.cpp` compilation using Xcode 16b1 (#4051)
1113

1214
## 8.28.0

Sentry.xcodeproj/project.pbxproj

+16
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,9 @@
891891
D8B76B062808066D000A58C4 /* SentryScreenshotIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B76B042808060E000A58C4 /* SentryScreenshotIntegrationTests.swift */; };
892892
D8B76B0828081461000A58C4 /* TestSentryScreenShot.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B76B0728081461000A58C4 /* TestSentryScreenShot.swift */; };
893893
D8BBD32728FD9FC00011F850 /* SentrySwift.h in Headers */ = {isa = PBXBuildFile; fileRef = D8BBD32628FD9FBF0011F850 /* SentrySwift.h */; settings = {ATTRIBUTES = (Private, ); }; };
894+
D8BC28C82BFF5EBB0054DA4D /* SentryTouchTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8BC28C72BFF5EBB0054DA4D /* SentryTouchTracker.swift */; };
895+
D8BC28CA2BFF68CA0054DA4D /* NumberExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8BC28C92BFF68CA0054DA4D /* NumberExtensions.swift */; };
896+
D8BC28CC2BFF78220054DA4D /* SentryRRWebTouchEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8BC28CB2BFF78220054DA4D /* SentryRRWebTouchEvent.swift */; };
894897
D8BC28D62C00C6DF0054DA4D /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8BC28D42C00C6D30054DA4D /* StringExtensionsTests.swift */; };
895898
D8BD2E6829361A0F00D96C6A /* PrivatesHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = D8BD2E67293619F600D96C6A /* PrivatesHeader.h */; settings = {ATTRIBUTES = (Private, ); }; };
896899
D8BFE37229A3782F002E73F3 /* SentryTimeToDisplayTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = D8BFE37029A3782F002E73F3 /* SentryTimeToDisplayTracker.h */; };
@@ -912,6 +915,7 @@
912915
D8CB742E294B294B00A5F964 /* MockUIScene.m in Sources */ = {isa = PBXBuildFile; fileRef = D8CB742D294B294B00A5F964 /* MockUIScene.m */; };
913916
D8CCFC632A1520C900DE232E /* SentryBinaryImageCacheTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D8CCFC622A1520C900DE232E /* SentryBinaryImageCacheTests.m */; };
914917
D8CE69BC277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D8CE69BB277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m */; };
918+
D8DBE0CA2C0E093000FAB1FD /* SentryTouchTrackerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8DBE0C92C0E093000FAB1FD /* SentryTouchTrackerTests.swift */; };
915919
D8DBE0D22C0EFFC300FAB1FD /* SentryReplayOptionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8DBE0D12C0EFFC300FAB1FD /* SentryReplayOptionsTests.swift */; };
916920
D8F016B32B9622D6007B9AFB /* SentryId.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F016B22B9622D6007B9AFB /* SentryId.swift */; };
917921
D8F016B62B962548007B9AFB /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F016B52B962548007B9AFB /* StringExtensions.swift */; };
@@ -1954,6 +1958,9 @@
19541958
D8B76B042808060E000A58C4 /* SentryScreenshotIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryScreenshotIntegrationTests.swift; sourceTree = "<group>"; };
19551959
D8B76B0728081461000A58C4 /* TestSentryScreenShot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSentryScreenShot.swift; sourceTree = "<group>"; };
19561960
D8BBD32628FD9FBF0011F850 /* SentrySwift.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentrySwift.h; path = include/SentrySwift.h; sourceTree = "<group>"; };
1961+
D8BC28C72BFF5EBB0054DA4D /* SentryTouchTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTouchTracker.swift; sourceTree = "<group>"; };
1962+
D8BC28C92BFF68CA0054DA4D /* NumberExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberExtensions.swift; sourceTree = "<group>"; };
1963+
D8BC28CB2BFF78220054DA4D /* SentryRRWebTouchEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryRRWebTouchEvent.swift; sourceTree = "<group>"; };
19571964
D8BC28D42C00C6D30054DA4D /* StringExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtensionsTests.swift; sourceTree = "<group>"; };
19581965
D8BC83BA2AFCF08C00A662B7 /* SentryUIApplication+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryUIApplication+Private.h"; sourceTree = "<group>"; };
19591966
D8BD2E27292D1F7300D96C6A /* SDK.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = SDK.xcconfig; sourceTree = "<group>"; };
@@ -1978,6 +1985,7 @@
19781985
D8CB742D294B294B00A5F964 /* MockUIScene.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MockUIScene.m; sourceTree = "<group>"; };
19791986
D8CCFC622A1520C900DE232E /* SentryBinaryImageCacheTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryBinaryImageCacheTests.m; sourceTree = "<group>"; };
19801987
D8CE69BB277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryFileIOTrackingIntegrationObjCTests.m; sourceTree = "<group>"; };
1988+
D8DBE0C92C0E093000FAB1FD /* SentryTouchTrackerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTouchTrackerTests.swift; sourceTree = "<group>"; };
19811989
D8DBE0D12C0EFFC300FAB1FD /* SentryReplayOptionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryReplayOptionsTests.swift; sourceTree = "<group>"; };
19821990
D8F016B22B9622D6007B9AFB /* SentryId.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryId.swift; sourceTree = "<group>"; };
19831991
D8F016B52B962548007B9AFB /* StringExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = "<group>"; };
@@ -3593,6 +3601,7 @@
35933601
D861301B2BB5A267004C0F5E /* SentrySessionReplayTests.swift */,
35943602
D8AFC0002BD252B900118BE1 /* SentryOnDemandReplayTests.swift */,
35953603
D82DD1CC2BEEB1A0001AB556 /* SentryBreadcrumbReplayConverterTests.swift */,
3604+
D8DBE0C92C0E093000FAB1FD /* SentryTouchTrackerTests.swift */,
35963605
D8DBE0D12C0EFFC300FAB1FD /* SentryReplayOptionsTests.swift */,
35973606
);
35983607
path = SessionReplay;
@@ -3632,6 +3641,7 @@
36323641
D81988C62BEC18E20020E36C /* SentryRRWebVideoEvent.swift */,
36333642
D8739D132BEE5049007D2F66 /* SentryRRWebSpanEvent.swift */,
36343643
D81988C82BEC19200020E36C /* SentryRRWebBreadcrumbEvent.swift */,
3644+
D8BC28CB2BFF78220054DA4D /* SentryRRWebTouchEvent.swift */,
36353645
);
36363646
path = RRWeb;
36373647
sourceTree = "<group>";
@@ -3864,6 +3874,7 @@
38643874
D8AFC03C2BDA79BF00118BE1 /* SentryReplayVideoMaker.swift */,
38653875
D8F67B1A2BE9728600C9197B /* SentryReplayBreadcrumbConverter.swift */,
38663876
D81988BF2BEBFFF70020E36C /* SentryReplayRecording.swift */,
3877+
D8BC28C72BFF5EBB0054DA4D /* SentryTouchTracker.swift */,
38673878
);
38683879
path = SessionReplay;
38693880
sourceTree = "<group>";
@@ -3892,6 +3903,7 @@
38923903
children = (
38933904
D8F016B52B962548007B9AFB /* StringExtensions.swift */,
38943905
62872B5E2BA1B7F300A4FA7D /* NSLock.swift */,
3906+
D8BC28C92BFF68CA0054DA4D /* NumberExtensions.swift */,
38953907
);
38963908
path = Extensions;
38973909
sourceTree = "<group>";
@@ -4694,6 +4706,7 @@
46944706
D80CD8D22B751447002F710B /* SentryMXManager.swift in Sources */,
46954707
03F84D3527DD4191008FE43F /* SentryThreadHandle.cpp in Sources */,
46964708
0A2D8DA9289BC905008720F6 /* SentryViewHierarchy.m in Sources */,
4709+
D8BC28CC2BFF78220054DA4D /* SentryRRWebTouchEvent.swift in Sources */,
46974710
8EA1ED0B2668F8C400E62B98 /* SentryUIViewControllerSwizzling.m in Sources */,
46984711
7B98D7CF25FB650F00C5A389 /* SentryWatchdogTerminationTrackingIntegration.m in Sources */,
46994712
8E5D38DD261D4A3E000D363D /* SentryPerformanceTrackingIntegration.m in Sources */,
@@ -4708,6 +4721,7 @@
47084721
63FE711920DA4C1000CDBAE8 /* SentryCrashMachineContext.c in Sources */,
47094722
63FE711B20DA4C1000CDBAE8 /* SentryCrashString.c in Sources */,
47104723
7B14089824878F950035403D /* SentryCrashStackEntryMapper.m in Sources */,
4724+
D8BC28C82BFF5EBB0054DA4D /* SentryTouchTracker.swift in Sources */,
47114725
63FE711720DA4C1000CDBAE8 /* SentryCrashStackCursor_Backtrace.c in Sources */,
47124726
63FE70CB20DA4C1000CDBAE8 /* SentryCrashReportFixer.c in Sources */,
47134727
D8CAC0412BA0984500E38F34 /* SentryIntegrationProtocol.swift in Sources */,
@@ -4753,6 +4767,7 @@
47534767
0A2D8D5B289815C0008720F6 /* SentryBaseIntegration.m in Sources */,
47544768
62262B912BA1C520004DA3DD /* CounterMetric.swift in Sources */,
47554769
639FCF991EBC7B9700778193 /* SentryEvent.m in Sources */,
4770+
D8BC28CA2BFF68CA0054DA4D /* NumberExtensions.swift in Sources */,
47564771
D820CDB72BB1895F00BA339D /* SentrySessionReplayIntegration.m in Sources */,
47574772
632F43521F581D5400A18A36 /* SentryCrashExceptionApplication.m in Sources */,
47584773
62A2F4422BA9AE12000C9FDD /* SetMetric.swift in Sources */,
@@ -4782,6 +4797,7 @@
47824797
63FE722420DA66EC00CDBAE8 /* SentryCrashMonitor_NSException_Tests.m in Sources */,
47834798
7B5AB65D27E48E5200F1D1BA /* TestThreadInspector.swift in Sources */,
47844799
7BF9EF742722A85B00B5BBEF /* SentryClassRegistrator.m in Sources */,
4800+
D8DBE0CA2C0E093000FAB1FD /* SentryTouchTrackerTests.swift in Sources */,
47854801
D8F67AF42BE10F9600C9197B /* UIRedactBuilderTests.swift in Sources */,
47864802
63B819141EC352A7002FDF4C /* SentryInterfacesTests.m in Sources */,
47874803
62F05D2B2C0DB1F100916E3F /* SentryLogTestHelper.m in Sources */,

SentryTestUtils/TestCurrentDateProvider.swift

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public class TestCurrentDateProvider: SentryCurrentDateProvider {
77
private var internalSystemTime: UInt64 = 0
88
public var driftTimeForEveryRead = false
99
public var driftTimeInterval = 0.1
10+
private var _systemUptime: TimeInterval = 0
1011

1112
public override init() {
1213

@@ -57,4 +58,11 @@ public class TestCurrentDateProvider: SentryCurrentDateProvider {
5758
public override func systemTime() -> UInt64 {
5859
return internalSystemTime
5960
}
61+
62+
override public func systemUptime() -> TimeInterval {
63+
_systemUptime
64+
}
65+
public func setSystemUptime(_ uptime: TimeInterval) {
66+
_systemUptime = uptime
67+
}
6068
}

Sources/Sentry/SentryScope.m

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,13 @@
4747

4848
@property (atomic) NSUInteger maxBreadcrumbs;
4949
@property (atomic) NSUInteger currentBreadcrumbIndex;
50-
@property (atomic, strong) NSMutableArray<SentryBreadcrumb *> *breadcrumbArray;
5150

5251
@property (atomic, strong) NSMutableArray<SentryAttachment *> *attachmentArray;
5352

5453
@property (nonatomic, retain) NSMutableArray<id<SentryScopeObserver>> *observers;
5554

55+
@property (atomic, strong) NSMutableArray<SentryBreadcrumb *> *breadcrumbArray;
56+
5657
@end
5758

5859
@implementation SentryScope {

Sources/Sentry/SentrySessionReplay.m

+14-6
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@ @implementation SentrySessionReplay {
4343
int _currentSegmentId;
4444
BOOL _processingScreenshot;
4545
BOOL _reachedMaximumDuration;
46+
SentryTouchTracker *_touchTracker;
4647
SentryReplayBreadcrumbConverter *_breadcrumbConverter;
4748
}
4849

4950
- (instancetype)initWithSettings:(SentryReplayOptions *)replayOptions
5051
replayFolderPath:(NSURL *)folderPath
5152
screenshotProvider:(id<SentryViewScreenshotProvider>)screenshotProvider
5253
replayMaker:(id<SentryReplayVideoMaker>)replayMaker
54+
touchTracker:(SentryTouchTracker *)touchTracker
5355
dateProvider:(SentryCurrentDateProvider *)dateProvider
5456
random:(id<SentryRandom>)random
5557
displayLinkWrapper:(SentryDisplayLinkWrapper *)displayLinkWrapper;
@@ -64,6 +66,7 @@ - (instancetype)initWithSettings:(SentryReplayOptions *)replayOptions
6466
_urlToCache = folderPath;
6567
_replayMaker = replayMaker;
6668
_reachedMaximumDuration = NO;
69+
_touchTracker = touchTracker;
6770
_breadcrumbConverter = [[SentryReplayBreadcrumbConverter alloc] init];
6871
}
6972
return self;
@@ -289,13 +292,18 @@ - (void)captureSegment:(NSInteger)segment
289292
replayEvent.segmentId = segment;
290293
replayEvent.timestamp = videoInfo.end;
291294

292-
__block NSArray<SentryRRWebEvent *> *events;
295+
__block NSArray<SentryBreadcrumb *> *breadcrumbs;
296+
[SentrySDK.currentHub
297+
configureScope:^(SentryScope *_Nonnull scope) { breadcrumbs = scope.breadcrumbs; }];
298+
NSMutableArray<SentryRRWebEvent *> *events = [NSMutableArray array];
293299

294-
[SentrySDK.currentHub configureScope:^(SentryScope *_Nonnull scope) {
295-
events = [self->_breadcrumbConverter convertWithBreadcrumbs:scope.breadcrumbs
296-
from:videoInfo.start
297-
until:videoInfo.end];
298-
}];
300+
[events addObjectsFromArray:[self->_breadcrumbConverter convertWithBreadcrumbs:breadcrumbs
301+
from:videoInfo.start
302+
until:videoInfo.end]];
303+
304+
[events addObjectsFromArray:[_touchTracker replayEventsFrom:videoInfo.start
305+
until:videoInfo.end]];
306+
[_touchTracker flushFinishedEvents];
299307

300308
SentryReplayRecording *recording =
301309
[[SentryReplayRecording alloc] initWithSegmentId:replayEvent.segmentId

Sources/Sentry/SentrySessionReplayIntegration.m

+38-1
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,21 @@
1414
# import "SentrySDK+Private.h"
1515
# import "SentrySessionReplay.h"
1616
# import "SentrySwift.h"
17+
# import "SentrySwizzle.h"
1718
# import "SentryUIApplication.h"
1819
# import <UIKit/UIKit.h>
1920

2021
NS_ASSUME_NONNULL_BEGIN
2122

2223
static NSString *SENTRY_REPLAY_FOLDER = @"replay";
2324

25+
/**
26+
* We need to use this from the swizzled block
27+
* and using an instance property would hold reference
28+
* and leak memory.
29+
*/
30+
static SentryTouchTracker *_touchTracker;
31+
2432
API_AVAILABLE(ios(16.0), tvos(16.0))
2533
@interface
2634
SentrySessionReplayIntegration ()
@@ -48,6 +56,13 @@ - (BOOL)installWithOptions:(nonnull SentryOptions *)options
4856
return NO;
4957
}
5058

59+
if (options.enableSwizzling) {
60+
_touchTracker = [[SentryTouchTracker alloc]
61+
initWithDateProvider:SentryDependencyContainer.sharedInstance.dateProvider
62+
scale:options.experimental.sessionReplay.sizeScale];
63+
[self swizzleApplicationTouch];
64+
}
65+
5166
if (SentryDependencyContainer.sharedInstance.application.windows.count > 0) {
5267
// If a window its already available start replay right away
5368
[self startWithOptions:_replayOptions fullSession:_startedAsFullSession];
@@ -100,9 +115,9 @@ - (void)startWithOptions:(SentryReplayOptions *)replayOptions
100115
replayFolderPath:docs
101116
screenshotProvider:SentryViewPhotographer.shared
102117
replayMaker:replayMaker
118+
touchTracker:_touchTracker
103119
dateProvider:SentryDependencyContainer.sharedInstance.dateProvider
104120
random:SentryDependencyContainer.sharedInstance.random
105-
106121
displayLinkWrapper:[[SentryDisplayLinkWrapper alloc] init]];
107122

108123
[self.sessionReplay
@@ -139,6 +154,7 @@ - (SentryIntegrationOption)integrationOptions
139154

140155
- (void)uninstall
141156
{
157+
_touchTracker = nil;
142158
[self stop];
143159
}
144160

@@ -147,6 +163,27 @@ - (BOOL)shouldReplayFullSession:(CGFloat)rate
147163
return [SentryDependencyContainer.sharedInstance.random nextNumber] < rate;
148164
}
149165

166+
- (void)swizzleApplicationTouch
167+
{
168+
# pragma clang diagnostic push
169+
# pragma clang diagnostic ignored "-Wshadow"
170+
SEL selector = NSSelectorFromString(@"sendEvent:");
171+
SentrySwizzleInstanceMethod([UIApplication class], selector, SentrySWReturnType(void),
172+
SentrySWArguments(UIEvent * event), SentrySWReplacement({
173+
[_touchTracker trackTouchFromEvent:event];
174+
SentrySWCallOriginal(event);
175+
}),
176+
SentrySwizzleModeOncePerClass, (void *)selector);
177+
# pragma clang diagnostic pop
178+
}
179+
180+
# if TEST || TESTCI
181+
- (SentryTouchTracker *)getTouchTracker
182+
{
183+
return _touchTracker;
184+
}
185+
# endif
186+
150187
@end
151188
NS_ASSUME_NONNULL_END
152189

Sources/Sentry/include/SentryDisplayLinkWrapper.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ NS_ASSUME_NONNULL_BEGIN
2121

2222
NS_ASSUME_NONNULL_END
2323

24-
#endif //
24+
#endif

Sources/Sentry/include/SentrySessionReplay.h

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
@class SentryDisplayLinkWrapper;
1111
@class SentryVideoInfo;
1212
@class SentryId;
13+
@class SentryTouchTracker;
1314

1415
@protocol SentryRandom;
1516
@protocol SentryRedactOptions;
@@ -26,6 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
2627
replayFolderPath:(NSURL *)folderPath
2728
screenshotProvider:(id<SentryViewScreenshotProvider>)photographer
2829
replayMaker:(id<SentryReplayVideoMaker>)replayMaker
30+
touchTracker:(SentryTouchTracker *)touchTracker
2931
dateProvider:(SentryCurrentDateProvider *)dateProvider
3032
random:(id<SentryRandom>)random
3133
displayLinkWrapper:(SentryDisplayLinkWrapper *)displayLinkWrapper;

Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_CPPException.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
#include <cxxabi.h>
3737
#include <dlfcn.h>
38+
#include <exception>
3839
#include <stdio.h>
3940
#include <stdlib.h>
4041
#include <string.h>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import Foundation
2+
3+
extension FixedWidthInteger {
4+
5+
@inlinable
6+
@discardableResult
7+
postfix static func ++ (lhs: inout Self) -> Self {
8+
defer { lhs += 1 }
9+
return lhs
10+
}
11+
12+
}

0 commit comments

Comments
 (0)