Skip to content

Commit 60066bd

Browse files
committed
ref: Convert SentryViewHierarchyProvider to Swift
1 parent d50a587 commit 60066bd

File tree

6 files changed

+441
-218
lines changed

6 files changed

+441
-218
lines changed

Sentry.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,7 @@
11231123
FAE80C242E4695B40010A595 /* SentryEvent+Serialize.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE80C232E4695AE0010A595 /* SentryEvent+Serialize.h */; };
11241124
FAEC270E2DF3526000878871 /* SentryUserFeedback.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAEC270D2DF3526000878871 /* SentryUserFeedback.swift */; };
11251125
FAEC273D2DF3933A00878871 /* NSData+Unzip.m in Sources */ = {isa = PBXBuildFile; fileRef = FAEC273C2DF3933200878871 /* NSData+Unzip.m */; };
1126+
FAEEBFE22E736D4B00E79CA9 /* SentryViewHierarchyProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAEEBFDC2E736D4100E79CA9 /* SentryViewHierarchyProvider.swift */; };
11261127
FAEFA12F2E4FAE1900C431D9 /* SentrySDKSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAEFA1292E4FAE1700C431D9 /* SentrySDKSettings.swift */; };
11271128
FAF120182E70C08F006E1DA3 /* SentryEnvelopeHeaderHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF120122E70C088006E1DA3 /* SentryEnvelopeHeaderHelper.h */; };
11281129
FAF1201A2E70C0EE006E1DA3 /* SentryEnvelopeHeaderHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = FAF120192E70C0EA006E1DA3 /* SentryEnvelopeHeaderHelper.m */; };
@@ -2472,6 +2473,7 @@
24722473
FAEC270D2DF3526000878871 /* SentryUserFeedback.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryUserFeedback.swift; sourceTree = "<group>"; };
24732474
FAEC273C2DF3933200878871 /* NSData+Unzip.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSData+Unzip.m"; sourceTree = "<group>"; };
24742475
FAEC273E2DF393E000878871 /* NSData+Unzip.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSData+Unzip.h"; sourceTree = "<group>"; };
2476+
FAEEBFDC2E736D4100E79CA9 /* SentryViewHierarchyProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryViewHierarchyProvider.swift; sourceTree = "<group>"; };
24752477
FAEFA1292E4FAE1700C431D9 /* SentrySDKSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySDKSettings.swift; sourceTree = "<group>"; };
24762478
FAF120122E70C088006E1DA3 /* SentryEnvelopeHeaderHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryEnvelopeHeaderHelper.h; path = include/SentryEnvelopeHeaderHelper.h; sourceTree = "<group>"; };
24772479
FAF120192E70C0EA006E1DA3 /* SentryEnvelopeHeaderHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryEnvelopeHeaderHelper.m; sourceTree = "<group>"; };
@@ -4491,6 +4493,7 @@
44914493
D856272A2A374A6800FB8062 /* Tools */ = {
44924494
isa = PBXGroup;
44934495
children = (
4496+
FAEEBFDC2E736D4100E79CA9 /* SentryViewHierarchyProvider.swift */,
44944497
FA94E6B12E6D265500576666 /* SentryEnvelope.swift */,
44954498
FA94E68B2E6B92BE00576666 /* SentryClientReport.swift */,
44964499
FA3AEE772E68E2830092283E /* SentryEnvelopeHeader.swift */,
@@ -5703,6 +5706,7 @@
57035706
84E13B842CBF1D91003B52EC /* SentryUserFeedbackWidgetButtonMegaphoneIconView.swift in Sources */,
57045707
63FE715920DA4C1100CDBAE8 /* SentryCrashCPU_x86_32.c in Sources */,
57055708
92235CAE2E15549C00865983 /* SentryLogger.swift in Sources */,
5709+
FAEEBFE22E736D4B00E79CA9 /* SentryViewHierarchyProvider.swift in Sources */,
57065710
D8C66A372A77B1F70015696A /* SentryPropagationContext.m in Sources */,
57075711
7BE912AD272162D900E49E62 /* SentryNoOpSpan.m in Sources */,
57085712
63FE710D20DA4C1000CDBAE8 /* SentryCrashStackCursor_MachineContext.c in Sources */,

Sources/Sentry/SentryViewHierarchyIntegration.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# import "SentryHub+Private.h"
1010
# import "SentryOptions.h"
1111
# import "SentrySDK+Private.h"
12+
# import "SentrySwift.h"
1213
# import "SentryViewHierarchyProvider.h"
1314
# if SENTRY_HAS_METRIC_KIT
1415
# import "SentryMetricKitIntegration.h"
Lines changed: 179 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -1,178 +1,179 @@
1-
#import "SentryViewHierarchyProvider.h"
2-
3-
#if SENTRY_HAS_UIKIT
4-
5-
# import "SentryCrashFileUtils.h"
6-
# import "SentryCrashJSONCodec.h"
7-
# import "SentryLogC.h"
8-
# import "SentrySwift.h"
9-
# import <UIKit/UIKit.h>
10-
11-
static int
12-
writeJSONDataToFile(const char *const data, const int length, void *const userData)
13-
{
14-
const int fd = *((int *)userData);
15-
const bool success = sentrycrashfu_writeBytesToFD(fd, data, length);
16-
return success ? SentryCrashJSON_OK : SentryCrashJSON_ERROR_CANNOT_ADD_DATA;
17-
}
18-
19-
static int
20-
writeJSONDataToMemory(const char *const data, const int length, void *const userData)
21-
{
22-
NSMutableData *memory = ((__bridge NSMutableData *)userData);
23-
[memory appendBytes:data length:length];
24-
return SentryCrashJSON_OK;
25-
}
26-
27-
@interface SentryViewHierarchyProvider ()
28-
29-
@property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueueWrapper;
30-
@property (nonatomic, strong) id<SentryApplication> sentryUIApplication;
31-
32-
@end
33-
34-
@implementation SentryViewHierarchyProvider
35-
36-
- (instancetype)initWithDispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper
37-
sentryUIApplication:(id<SentryApplication>)sentryUIApplication
38-
{
39-
if (self = [super init]) {
40-
self.reportAccessibilityIdentifier = YES;
41-
self.dispatchQueueWrapper = dispatchQueueWrapper;
42-
self.sentryUIApplication = sentryUIApplication;
43-
}
44-
return self;
45-
}
46-
47-
- (BOOL)saveViewHierarchy:(NSString *)filePath
48-
{
49-
NSArray<UIWindow *> *windows = [self.sentryUIApplication getWindows];
50-
51-
const char *path = [filePath UTF8String];
52-
int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0644);
53-
if (fd < 0) {
54-
SENTRY_LOG_DEBUG(@"Could not open file %s for writing: %s", path, strerror(errno));
55-
return NO;
56-
}
57-
58-
BOOL result = [self processViewHierarchy:windows addFunction:writeJSONDataToFile userData:&fd];
59-
60-
close(fd);
61-
return result;
62-
}
63-
64-
- (NSData *)appViewHierarchyFromMainThread
65-
{
66-
__block NSData *result;
67-
68-
void (^fetchViewHierarchy)(void) = ^{ result = [self appViewHierarchy]; };
69-
70-
SENTRY_LOG_INFO(@"Starting to fetch the view hierarchy from the main thread.");
71-
72-
[self.dispatchQueueWrapper dispatchSyncOnMainQueue:fetchViewHierarchy];
73-
74-
SENTRY_LOG_INFO(@"Finished fetching the view hierarchy from the main thread.");
75-
76-
return result;
77-
}
78-
79-
- (NSData *)appViewHierarchy
80-
{
81-
NSMutableData *result = [[NSMutableData alloc] init];
82-
NSArray<UIWindow *> *windows = [self.sentryUIApplication getWindows];
83-
84-
if (![self processViewHierarchy:windows
85-
addFunction:writeJSONDataToMemory
86-
userData:(__bridge void *)(result)]) {
87-
88-
result = nil;
89-
}
90-
91-
return result;
92-
}
93-
94-
# define tryJson(code) \
95-
if ((result = (code)) != SentryCrashJSON_OK) \
96-
return result;
97-
98-
- (BOOL)processViewHierarchy:(NSArray<UIView *> *)windows
99-
addFunction:(SentryCrashJSONAddDataFunc)addJSONDataFunc
100-
userData:(void *const)userData
101-
{
102-
103-
__block SentryCrashJSONEncodeContext JSONContext;
104-
sentrycrashjson_beginEncode(&JSONContext, NO, addJSONDataFunc, userData);
105-
106-
SENTRY_LOG_DEBUG(@"Processing view hierarchy.");
107-
108-
int (^serializeJson)(void) = ^int() {
109-
int result;
110-
tryJson(sentrycrashjson_beginObject(&JSONContext, NULL));
111-
tryJson(sentrycrashjson_addStringElement(
112-
&JSONContext, "rendering_system", "UIKIT", SentryCrashJSON_SIZE_AUTOMATIC));
113-
tryJson(sentrycrashjson_beginArray(&JSONContext, "windows"));
114-
115-
for (UIView *window in windows) {
116-
tryJson([self viewHierarchyFromView:window intoContext:&JSONContext]);
117-
}
118-
119-
tryJson(sentrycrashjson_endContainer(&JSONContext));
120-
121-
result = sentrycrashjson_endEncode(&JSONContext);
122-
return result;
123-
};
124-
125-
int result = serializeJson();
126-
if (result != SentryCrashJSON_OK) {
127-
SENTRY_LOG_DEBUG(
128-
@"Could not create view hierarchy json: %s", sentrycrashjson_stringForError(result));
129-
return NO;
130-
}
131-
return YES;
132-
}
133-
134-
- (int)viewHierarchyFromView:(UIView *)view intoContext:(SentryCrashJSONEncodeContext *)context
135-
{
136-
SENTRY_LOG_DEBUG(@"Processing view hierarchy of view: %@", view);
137-
138-
int result = 0;
139-
tryJson(sentrycrashjson_beginObject(context, NULL));
140-
const char *viewClassName = [[SwiftDescriptor getObjectClassName:view] UTF8String];
141-
tryJson(sentrycrashjson_addStringElement(
142-
context, "type", viewClassName, SentryCrashJSON_SIZE_AUTOMATIC));
143-
144-
if (self.reportAccessibilityIdentifier && view.accessibilityIdentifier
145-
&& view.accessibilityIdentifier.length != 0) {
146-
tryJson(sentrycrashjson_addStringElement(context, "identifier",
147-
view.accessibilityIdentifier.UTF8String, SentryCrashJSON_SIZE_AUTOMATIC));
148-
}
149-
150-
tryJson(sentrycrashjson_addFloatingPointElement(context, "width", view.frame.size.width));
151-
tryJson(sentrycrashjson_addFloatingPointElement(context, "height", view.frame.size.height));
152-
tryJson(sentrycrashjson_addFloatingPointElement(context, "x", view.frame.origin.x));
153-
tryJson(sentrycrashjson_addFloatingPointElement(context, "y", view.frame.origin.y));
154-
tryJson(sentrycrashjson_addFloatingPointElement(context, "alpha", view.alpha));
155-
tryJson(sentrycrashjson_addBooleanElement(context, "visible", !view.hidden));
156-
157-
if ([view.nextResponder isKindOfClass:[UIViewController class]]) {
158-
UIViewController *vc = (UIViewController *)view.nextResponder;
159-
if (vc.view == view) {
160-
const char *viewControllerClassName =
161-
[[SwiftDescriptor getViewControllerClassName:vc] UTF8String];
162-
tryJson(sentrycrashjson_addStringElement(context, "view_controller",
163-
viewControllerClassName, SentryCrashJSON_SIZE_AUTOMATIC));
164-
}
165-
}
166-
167-
tryJson(sentrycrashjson_beginArray(context, "children"));
168-
for (UIView *child in view.subviews) {
169-
tryJson([self viewHierarchyFromView:child intoContext:context]);
170-
}
171-
tryJson(sentrycrashjson_endContainer(context));
172-
tryJson(sentrycrashjson_endContainer(context));
173-
return result;
174-
}
175-
176-
@end
177-
178-
#endif // SENTRY_HAS_UIKIT
1+
// #import "SentryViewHierarchyProvider.h"
2+
//
3+
// #if SENTRY_HAS_UIKIT
4+
//
5+
// # import "SentryCrashFileUtils.h"
6+
// # import "SentryCrashJSONCodec.h"
7+
// # import "SentryLogC.h"
8+
// # import "SentrySwift.h"
9+
// # import <UIKit/UIKit.h>
10+
//
11+
// static int
12+
// writeJSONDataToFile(const char *const data, const int length, void *const userData)
13+
//{
14+
// const int fd = *((int *)userData);
15+
// const bool success = sentrycrashfu_writeBytesToFD(fd, data, length);
16+
// return success ? SentryCrashJSON_OK : SentryCrashJSON_ERROR_CANNOT_ADD_DATA;
17+
// }
18+
//
19+
// static int
20+
// writeJSONDataToMemory(const char *const data, const int length, void *const userData)
21+
//{
22+
// NSMutableData *memory = ((__bridge NSMutableData *)userData);
23+
// [memory appendBytes:data length:length];
24+
// return SentryCrashJSON_OK;
25+
// }
26+
//
27+
//@interface SentryViewHierarchyProvider ()
28+
//
29+
//@property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueueWrapper;
30+
//@property (nonatomic, strong) id<SentryApplication> sentryUIApplication;
31+
//
32+
//@end
33+
//
34+
//@implementation SentryViewHierarchyProvider
35+
//
36+
//- (instancetype)initWithDispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper
37+
// sentryUIApplication:(id<SentryApplication>)sentryUIApplication
38+
//{
39+
// if (self = [super init]) {
40+
// self.reportAccessibilityIdentifier = YES;
41+
// self.dispatchQueueWrapper = dispatchQueueWrapper;
42+
// self.sentryUIApplication = sentryUIApplication;
43+
// }
44+
// return self;
45+
// }
46+
//
47+
//- (BOOL)saveViewHierarchy:(NSString *)filePath
48+
//{
49+
// NSArray<UIWindow *> *windows = [self.sentryUIApplication getWindows];
50+
//
51+
// const char *path = [filePath UTF8String];
52+
// int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0644);
53+
// if (fd < 0) {
54+
// SENTRY_LOG_DEBUG(@"Could not open file %s for writing: %s", path, strerror(errno));
55+
// return NO;
56+
// }
57+
//
58+
// BOOL result = [self processViewHierarchy:windows addFunction:writeJSONDataToFile
59+
// userData:&fd];
60+
//
61+
// close(fd);
62+
// return result;
63+
// }
64+
//
65+
//- (NSData *)appViewHierarchyFromMainThread
66+
//{
67+
// __block NSData *result;
68+
//
69+
// void (^fetchViewHierarchy)(void) = ^{ result = [self appViewHierarchy]; };
70+
//
71+
// SENTRY_LOG_INFO(@"Starting to fetch the view hierarchy from the main thread.");
72+
//
73+
// [self.dispatchQueueWrapper dispatchSyncOnMainQueue:fetchViewHierarchy];
74+
//
75+
// SENTRY_LOG_INFO(@"Finished fetching the view hierarchy from the main thread.");
76+
//
77+
// return result;
78+
// }
79+
//
80+
//- (NSData *)appViewHierarchy
81+
//{
82+
// NSMutableData *result = [[NSMutableData alloc] init];
83+
// NSArray<UIWindow *> *windows = [self.sentryUIApplication getWindows];
84+
//
85+
// if (![self processViewHierarchy:windows
86+
// addFunction:writeJSONDataToMemory
87+
// userData:(__bridge void *)(result)]) {
88+
//
89+
// result = nil;
90+
// }
91+
//
92+
// return result;
93+
// }
94+
//
95+
// # define tryJson(code) \
96+
// if ((result = (code)) != SentryCrashJSON_OK) \
97+
// return result;
98+
//
99+
//- (BOOL)processViewHierarchy:(NSArray<UIView *> *)windows
100+
// addFunction:(SentryCrashJSONAddDataFunc)addJSONDataFunc
101+
// userData:(void *const)userData
102+
//{
103+
//
104+
// __block SentryCrashJSONEncodeContext JSONContext;
105+
// sentrycrashjson_beginEncode(&JSONContext, NO, addJSONDataFunc, userData);
106+
//
107+
// SENTRY_LOG_DEBUG(@"Processing view hierarchy.");
108+
//
109+
// int (^serializeJson)(void) = ^int() {
110+
// int result;
111+
// tryJson(sentrycrashjson_beginObject(&JSONContext, NULL));
112+
// tryJson(sentrycrashjson_addStringElement(
113+
// &JSONContext, "rendering_system", "UIKIT", SentryCrashJSON_SIZE_AUTOMATIC));
114+
// tryJson(sentrycrashjson_beginArray(&JSONContext, "windows"));
115+
//
116+
// for (UIView *window in windows) {
117+
// tryJson([self viewHierarchyFromView:window intoContext:&JSONContext]);
118+
// }
119+
//
120+
// tryJson(sentrycrashjson_endContainer(&JSONContext));
121+
//
122+
// result = sentrycrashjson_endEncode(&JSONContext);
123+
// return result;
124+
// };
125+
//
126+
// int result = serializeJson();
127+
// if (result != SentryCrashJSON_OK) {
128+
// SENTRY_LOG_DEBUG(
129+
// @"Could not create view hierarchy json: %s", sentrycrashjson_stringForError(result));
130+
// return NO;
131+
// }
132+
// return YES;
133+
// }
134+
//
135+
//- (int)viewHierarchyFromView:(UIView *)view intoContext:(SentryCrashJSONEncodeContext *)context
136+
//{
137+
// SENTRY_LOG_DEBUG(@"Processing view hierarchy of view: %@", view);
138+
//
139+
// int result = 0;
140+
// tryJson(sentrycrashjson_beginObject(context, NULL));
141+
// const char *viewClassName = [[SwiftDescriptor getObjectClassName:view] UTF8String];
142+
// tryJson(sentrycrashjson_addStringElement(
143+
// context, "type", viewClassName, SentryCrashJSON_SIZE_AUTOMATIC));
144+
//
145+
// if (self.reportAccessibilityIdentifier && view.accessibilityIdentifier
146+
// && view.accessibilityIdentifier.length != 0) {
147+
// tryJson(sentrycrashjson_addStringElement(context, "identifier",
148+
// view.accessibilityIdentifier.UTF8String, SentryCrashJSON_SIZE_AUTOMATIC));
149+
// }
150+
//
151+
// tryJson(sentrycrashjson_addFloatingPointElement(context, "width", view.frame.size.width));
152+
// tryJson(sentrycrashjson_addFloatingPointElement(context, "height", view.frame.size.height));
153+
// tryJson(sentrycrashjson_addFloatingPointElement(context, "x", view.frame.origin.x));
154+
// tryJson(sentrycrashjson_addFloatingPointElement(context, "y", view.frame.origin.y));
155+
// tryJson(sentrycrashjson_addFloatingPointElement(context, "alpha", view.alpha));
156+
// tryJson(sentrycrashjson_addBooleanElement(context, "visible", !view.hidden));
157+
//
158+
// if ([view.nextResponder isKindOfClass:[UIViewController class]]) {
159+
// UIViewController *vc = (UIViewController *)view.nextResponder;
160+
// if (vc.view == view) {
161+
// const char *viewControllerClassName =
162+
// [[SwiftDescriptor getViewControllerClassName:vc] UTF8String];
163+
// tryJson(sentrycrashjson_addStringElement(context, "view_controller",
164+
// viewControllerClassName, SentryCrashJSON_SIZE_AUTOMATIC));
165+
// }
166+
// }
167+
//
168+
// tryJson(sentrycrashjson_beginArray(context, "children"));
169+
// for (UIView *child in view.subviews) {
170+
// tryJson([self viewHierarchyFromView:child intoContext:context]);
171+
// }
172+
// tryJson(sentrycrashjson_endContainer(context));
173+
// tryJson(sentrycrashjson_endContainer(context));
174+
// return result;
175+
// }
176+
//
177+
//@end
178+
//
179+
// #endif // SENTRY_HAS_UIKIT

0 commit comments

Comments
 (0)