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: SwiftUI time for initial display and time for full display #4596

Draft
wants to merge 35 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a689d58
wip
brustolin Dec 2, 2024
fd905da
more changes
brustolin Dec 4, 2024
e024c6c
Update CHANGELOG.md
brustolin Dec 4, 2024
ec167f7
Merge branch 'main' into feat/swiftui-ttid
brustolin Dec 4, 2024
671956f
Format code
getsentry-bot Dec 4, 2024
5c531b6
Update CHANGELOG.md
brustolin Dec 4, 2024
6bedfa7
Merge branch 'feat/swiftui-ttid' of https://github.com/getsentry/sent…
brustolin Dec 4, 2024
e6c6f18
fix for macOS
brustolin Dec 4, 2024
d6884c5
fix tests
brustolin Dec 4, 2024
ebdbc79
Update SentryTracedView.swift
brustolin Dec 4, 2024
78e6b66
Format code
getsentry-bot Dec 4, 2024
04c6fdd
Update SentryTimeToDisplayTrackerTest.swift
brustolin Dec 4, 2024
818aa34
Format code
getsentry-bot Dec 4, 2024
6bbebc7
Update SentrySDKTests.swift
brustolin Dec 4, 2024
a970eb3
UITests
brustolin Dec 5, 2024
9f92dd8
Merge branch 'main' into feat/swiftui-ttid
brustolin Dec 5, 2024
d51b0ee
Update CHANGELOG.md
brustolin Dec 5, 2024
45623f3
Update SentryRedactModifierTests.swift
brustolin Dec 10, 2024
e572da7
Merge branch 'main' into feat/swiftui-ttid
brustolin Dec 12, 2024
331d1df
use onAppear
brustolin Dec 12, 2024
f1b6632
Format code
getsentry-bot Dec 12, 2024
6dc28e5
Update SentryTracedView.swift
brustolin Dec 12, 2024
588764e
fix test
brustolin Dec 12, 2024
15cfd35
Update Sources/Sentry/SentryUIViewControllerPerformanceTracker.m
brustolin Dec 13, 2024
edba1ba
Format code
getsentry-bot Dec 13, 2024
98e4c6e
refactoring
brustolin Dec 18, 2024
facf4a3
Format code
getsentry-bot Dec 18, 2024
d3bc4ca
move code to viewModel
brustolin Dec 18, 2024
036a741
Update SentryTracedView.swift
brustolin Dec 18, 2024
b4ddf12
Update SentryTracedView.swift
brustolin Dec 18, 2024
4c749b4
More change
brustolin Dec 19, 2024
25d4173
Merge branch 'main' into feat/swiftui-ttid
brustolin Dec 19, 2024
951bab7
Update test.yml
brustolin Dec 20, 2024
9f95dd8
Merge branch 'main' into feat/swiftui-ttid
brustolin Dec 20, 2024
c95d3ec
Update scripts/xcode-test.sh
brustolin Dec 20, 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
35 changes: 26 additions & 9 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
raw-test-output.log

unit-tests:
name: Unit ${{matrix.platform}} - Xcode ${{matrix.xcode}} - OS ${{matrix.test-destination-os}}
name: Unit ${{matrix.platform}} - Xcode ${{matrix.xcode}} - OS ${{matrix.test-destination-os}} ${{matrix.scheme}}
runs-on: ${{matrix.runs-on}}
timeout-minutes: 20
needs: build-test-server
Expand All @@ -84,21 +84,24 @@ jobs:
xcode: "14.3"
test-destination-os: "16.4"
device: "iPhone 14"

scheme: "Sentry"

# iOS 17
- runs-on: macos-14
platform: "iOS"
xcode: "15.4"
test-destination-os: "17.2"
device: "iPhone 15"

scheme: "Sentry"

# iOS 18
- runs-on: macos-15
platform: "iOS"
xcode: "16.1"
test-destination-os: "18.1"
device: "iPhone 16"

scheme: "Sentry"

# We don't run the unit tests on macOS 13 cause we run them on all on GH actions available iOS versions.
# The chance of missing a bug solely on tvOS 16 that doesn't occur on iOS, macOS 12 or macOS 14 is minimal.
# We are running tests on macOS 14 and later, as there were OS-internal changes introduced in succeeding versions.
Expand All @@ -108,25 +111,29 @@ jobs:
platform: "macOS"
xcode: "15.4"
test-destination-os: "latest"

scheme: "Sentry"

# macOS 15
- runs-on: macos-15
platform: "macOS"
xcode: "16.1"
test-destination-os: "latest"

scheme: "Sentry"

# Catalyst. We test the latest version, as the risk something breaking on Catalyst and not
# on an older iOS or macOS version is low.
# In addition we are running tests on macOS 14, as there were OS-internal changes introduced in succeeding versions.
- runs-on: macos-14
platform: "Catalyst"
xcode: "15.4"
test-destination-os: "latest"

scheme: "Sentry"

- runs-on: macos-15
platform: "Catalyst"
xcode: "16.1"
test-destination-os: "latest"
scheme: "Sentry"

# We don't run the unit tests on tvOS 16 cause we run them on all on GH actions available iOS versions.
# The chance of missing a bug solely on tvOS 16 that doesn't occur on iOS, tvOS 15 or tvOS 16 is minimal.
Expand All @@ -137,12 +144,22 @@ jobs:
platform: "tvOS"
xcode: "15.4"
test-destination-os: "17.5"
scheme: "Sentry"

# iOS 17
- runs-on: macos-14
platform: "iOS"
xcode: "15.4"
test-destination-os: "17.2"
device: "iPhone 15"
scheme: "SentrySwiftUI"

# tvOS 18
- runs-on: macos-15
platform: "tvOS"
xcode: "16.1"
test-destination-os: "18.1"
scheme: "Sentry"

steps:
- uses: actions/checkout@v4
Expand All @@ -168,14 +185,14 @@ jobs:
# We split building and running tests in two steps so we know how long running the tests takes.
- name: Build tests
id: build_tests
run: ./scripts/xcode-test.sh ${{matrix.platform}} ${{matrix.test-destination-os}} $GITHUB_REF_NAME build-for-testing "${{matrix.device}}" TestCI
run: ./scripts/xcode-test.sh ${{matrix.platform}} ${{matrix.test-destination-os}} $GITHUB_REF_NAME build-for-testing "${{matrix.device}}" TestCI ${{matrix.scheme}}

- name: Run tests
# We call a script with the platform so the destination
# passed to xcodebuild doesn't end up in the job name,
# because GitHub Actions don't provide an easy way of
# manipulating string in expressions.
run: ./scripts/xcode-test.sh ${{matrix.platform}} ${{matrix.test-destination-os}} $GITHUB_REF_NAME test-without-building "${{matrix.device}}" TestCI
run: ./scripts/xcode-test.sh ${{matrix.platform}} ${{matrix.test-destination-os}} $GITHUB_REF_NAME test-without-building "${{matrix.device}}" TestCI ${{matrix.scheme}}

- name: Slowest Tests
if: ${{ always() }}
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Features

- SwiftUI time for initial display and time for full display (#4596)

### Improvements

- Improve compiler error message for missing Swift declarations due to APPLICATION_EXTENSION_API_ONLY (#4603)
Expand Down
8 changes: 8 additions & 0 deletions Samples/iOS-SwiftUI/iOS-SwiftUI-UITests/LaunchUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,12 @@ class LaunchUITests: XCTestCase {
formScreenNavigationBar/*@START_MENU_TOKEN@*/.buttons["Test"]/*[[".otherElements[\"Test\"].buttons[\"Test\"]",".buttons[\"Test\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
XCTAssertEqual(app.staticTexts["SPAN_ID"].label, "NO SPAN")
}

func testTTID_TTFD() {
let app = XCUIApplication()
app.launch()
app.buttons["Show TTD"].tap()

XCTAssertEqual(app.staticTexts["TTDInfo"].label, "TTID and TTFD found")
}
}
30 changes: 30 additions & 0 deletions Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
D8199DCE29376FD90074249E /* SentrySwiftUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D8BBD38B2901AE400011F850 /* SentrySwiftUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
D832FAF02982A908007A9A5F /* FormScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = D832FAEF2982A908007A9A5F /* FormScreen.swift */; };
D85388D12980222500B63908 /* UIKitScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85388D02980222500B63908 /* UIKitScreen.swift */; };
D8F0F3C02D0068A100826CE3 /* SentrySwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8BBD38B2901AE400011F850 /* SentrySwiftUI.framework */; };
D8F0F3C12D0068A100826CE3 /* SentrySwiftUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D8BBD38B2901AE400011F850 /* SentrySwiftUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -108,6 +110,13 @@
remoteGlobalIDString = 63AA76651EB8CB2F00D153DE;
remoteInfo = SentryTests;
};
D833D61A2D13216300961E7A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = D833D60D2D1320B500961E7A;
remoteInfo = SentrySwiftUITests;
};
D8BBD38A2901AE400011F850 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */;
Expand All @@ -130,6 +139,17 @@
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
D8F0F3C22D0068A100826CE3 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
D8F0F3C12D0068A100826CE3 /* SentrySwiftUI.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -166,6 +186,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D8F0F3C02D0068A100826CE3 /* SentrySwiftUI.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -190,6 +211,7 @@
8425DE232B52241000113FEF /* SentryProfilerTests.xctest */,
8425DE252B52241000113FEF /* libSentryTestUtils.a */,
8425DE272B52241000113FEF /* SentryTestUtilsDynamic.framework */,
D833D61B2D13216300961E7A /* libSentrySwiftUITests.a */,
);
name = Products;
sourceTree = "<group>";
Expand Down Expand Up @@ -306,6 +328,7 @@
7B64385326A6C0A6000D0F65 /* Sources */,
7B64385426A6C0A6000D0F65 /* Frameworks */,
7B64385526A6C0A6000D0F65 /* Resources */,
D8F0F3C22D0068A100826CE3 /* Embed Frameworks */,
);
buildRules = (
);
Expand Down Expand Up @@ -462,6 +485,13 @@
remoteRef = 84D4FEB328ECD52E00EDAAFE /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D833D61B2D13216300961E7A /* libSentrySwiftUITests.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libSentrySwiftUITests.a;
remoteRef = D833D61A2D13216300961E7A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D8BBD38B2901AE400011F850 /* SentrySwiftUI.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
Expand Down
41 changes: 37 additions & 4 deletions Samples/iOS-SwiftUI/iOS-SwiftUI/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class DataBag {

struct ContentView: View {

@State var TTDInfo: String = ""

var addBreadcrumbAction: () -> Void = {
let crumb = Breadcrumb(level: SentryLevel.info, category: "Debug")
crumb.message = "tapped addBreadcrumb"
Expand Down Expand Up @@ -89,12 +91,34 @@ struct ContentView: View {
}
}

func showTTD() {
guard let tracer = getCurrentTracer() else { return }

var log = [String]()

if !hasTTID(tracer: tracer) { log.append("TTID not found") }
if !hasTTFD(tracer: tracer) { log.append("TTFD not found") }

if log.isEmpty {
log.append("TTID and TTFD found")
}
TTDInfo = log.joined(separator: "\n")
}

func getCurrentTracer() -> SentryTracer? {
if DataBag.shared.info["initialTransaction"] == nil {
DataBag.shared.info["initialTransaction"] = SentrySDK.span as? SentryTracer
}
return DataBag.shared.info["initialTransaction"] as? SentryTracer
}

func hasTTID(tracer: SentryTracer?) -> Bool {
tracer?.children.contains { $0.spanDescription?.contains("initial display") == true } == true
}

func hasTTFD(tracer: SentryTracer?) -> Bool {
tracer?.children.contains { $0.spanDescription?.contains("full display") == true } == true
}

func getCurrentSpan() -> Span? {

Expand All @@ -113,21 +137,24 @@ struct ContentView: View {

return DataBag.shared.info["lastSpan"] as? Span
}

var body: some View {
return SentryTracedView("Content View Body") {
NavigationView {
return SentryTracedView("Content View Body", waitForFullDisplay: true) { NavigationView {
VStack(alignment: HorizontalAlignment.center, spacing: 16) {
Group {
Text(getCurrentTracer()?.transactionContext.name ?? "NO SPAN")
.accessibilityIdentifier("TRANSACTION_NAME")

Text(getCurrentTracer()?.transactionContext.spanId.sentrySpanIdString ?? "NO ID")
.accessibilityIdentifier("TRANSACTION_ID")
.sentryReplayMask()

Text(getCurrentTracer()?.transactionContext.origin ?? "NO ORIGIN")
.accessibilityIdentifier("TRACE_ORIGIN")
}.sentryReplayUnmask()
.onAppear {
SentrySDK.reportFullyDisplayed()
}
SentryTracedView("Child Span") {
VStack {
Text(getCurrentSpan()?.spanDescription ?? "NO SPAN")
Expand Down Expand Up @@ -165,6 +192,9 @@ struct ContentView: View {
Button(action: captureTransactionAction) {
Text("Capture Transaction")
}
Button(action: showTTD) {
Text("Show TTD")
}
}
VStack(spacing: 16) {
Button(action: {
Expand Down Expand Up @@ -204,8 +234,11 @@ struct ContentView: View {
.background(Color.white)
}
SecondView()

Text(TTDInfo)
.accessibilityIdentifier("TTDInfo")
}
}
}
}
}
}
Expand Down
Loading
Loading