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

fix: Reads UI Windows in the main thread while fetching view hierarchy #2629

Merged
merged 4 commits into from
Jan 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

- Gather profiling timeseries metrics for CPU usage and memory footprint, and thermal and memory pressure events (#2493)

### Fixes

- Always fetch view hierarchy on the main thread (#2629)

## 8.0.0

### Features
Expand Down
5 changes: 3 additions & 2 deletions Sources/Sentry/SentryViewHierarchy.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ - (BOOL)saveViewHierarchy:(NSString *)filePath

- (NSData *)fetchViewHierarchy
{
NSArray<UIWindow *> *windows = [SentryDependencyContainer.sharedInstance.application windows];

__block NSMutableData *result = [[NSMutableData alloc] init];

void (^save)(void) = ^{
NSArray<UIWindow *> *windows =
[SentryDependencyContainer.sharedInstance.application windows];

if (![self processViewHierarchy:windows
addFunction:writeJSONDataToMemory
userData:(__bridge void *)(result)]) {
Expand Down
23 changes: 23 additions & 0 deletions Tests/SentryTests/SentryViewHierarchyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,37 @@ class SentryViewHierarchyTests: XCTestCase {
wait(for: [ex], timeout: 1)
}

func test_fetch_usesMainThread() {
let sut = TestSentryViewHierarchy()
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 10, height: 10))
fixture.uiApplication.windows = [window]

let ex = expectation(description: "Running on background Thread")
let dispatch = DispatchQueue(label: "background")
dispatch.async {
let _ = sut.fetch()
ex.fulfill()
}

wait(for: [ex], timeout: 1)
XCTAssertTrue(fixture.uiApplication.calledOnMainThread, "fetchViewHierarchy is not using the main thread to get UI windows")
}

class TestSentryUIApplication: SentryUIApplication {
private var _windows: [UIWindow]?
private var _calledOnMainThread = true

var calledOnMainThread: Bool {
return _calledOnMainThread
}

override var windows: [UIWindow]? {
get {
_calledOnMainThread = Thread.isMainThread
return _windows
}
set {
_calledOnMainThread = Thread.isMainThread
_windows = newValue
}
}
Expand Down