Skip to content

Commit d73e907

Browse files
Merge pull request #2460 from DataDog/gonzalezreal/RUM-11460/swiftui-shape-capture-performance-fixes
RUM-11460: [Session Replay] SwiftUI shape capture performance fixes Co-authored-by: gonzalezreal <guille.gonzalez@datadoghq.com>
2 parents 234dddd + 163453c commit d73e907

35 files changed

Lines changed: 961 additions & 103 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Release `3.0` introduces breaking changes. Follow the [Migration Guide](MIGRATIO
2020
- [IMPROVEMENT] Remove fatal errors from Logs. See [#2359][]
2121
- [IMPROVEMENT] Introduce new category for network errors. See [#2341][]
2222
- [IMPROVEMENT] Add opt-out API to disable tracking memory warnings as RUM Errors. See [#2355][]
23+
- [IMPROVEMENT] Improve SwiftUI system image and SF symbol capture in Session Replay through shape SVG recording, image maskColor support, and drawing rasterization. See [#2432][] [#2428][] [#2391][]
2324

2425
# 2.30.0 / 28-07-2025
2526

Datadog/Datadog.xcodeproj/project.pbxproj

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -448,10 +448,16 @@
448448
49D8C0BE2AC5F2BC0075E427 /* Logs+Internal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D8C0B92AC5F21F0075E427 /* Logs+Internal.swift */; };
449449
5B0A9B8B2E3BB98E00A8131C /* GraphicsFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0A9B8A2E3BB98500A8131C /* GraphicsFilter.swift */; };
450450
5B0A9B8D2E3BBB4500A8131C /* GraphicsFilter+Reflection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0A9B8C2E3BBB3D00A8131C /* GraphicsFilter+Reflection.swift */; };
451+
5B3AF8AA2E4B3AE9009E5375 /* EnrichedResourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B3AF8A92E4B3AE6009E5375 /* EnrichedResourceTests.swift */; };
452+
5B9B20C52E460A0600C95B6C /* ShapeResourceBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B9B20C42E4609FC00C95B6C /* ShapeResourceBuilderTests.swift */; };
451453
5B9CB9E32E41F6F9005485E6 /* ImageRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B9CB9E22E41F6F6005485E6 /* ImageRepresentable.swift */; };
452454
5B9CB9E52E41FD60005485E6 /* Drawing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B9CB9E42E41FD5C005485E6 /* Drawing.swift */; };
453455
5B9CB9E72E420ACB005485E6 /* ImageRendererTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B9CB9E62E420AC4005485E6 /* ImageRendererTests.swift */; };
454456
5BCBC0CD2DF85B6A0094DCC2 /* SessionReplayPrivacyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BCBC0CC2DF85AFE0094DCC2 /* SessionReplayPrivacyView.swift */; };
457+
5BE0EA2B2E66E8A800216E1C /* ShapeResourceBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE0EA2A2E66E8A200216E1C /* ShapeResourceBuilder.swift */; };
458+
5BE0EA2D2E66EFA300216E1C /* Path+SessionReplay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE0EA2C2E66EF9B00216E1C /* Path+SessionReplay.swift */; };
459+
5BE0EA2F2E66F25200216E1C /* Path+SessionReplayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE0EA2E2E66F23F00216E1C /* Path+SessionReplayTests.swift */; };
460+
5BF7B51F2E44F7D300E0B772 /* ShapeResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BF7B51E2E44F7CE00E0B772 /* ShapeResource.swift */; };
455461
5BFDD7A92E28FDD3009A2CEE /* RUMWebViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BFDD7A82E28FDC9009A2CEE /* RUMWebViewContext.swift */; };
456462
5BFDD7AA2E28FDD3009A2CEE /* RUMWebViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BFDD7A82E28FDC9009A2CEE /* RUMWebViewContext.swift */; };
457463
5BFE7B7B2E3CFCDE00B8FAA8 /* ImageRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BFE7B7A2E3CFCDA00B8FAA8 /* ImageRenderer.swift */; };
@@ -2475,10 +2481,16 @@
24752481
49D8C0B92AC5F21F0075E427 /* Logs+Internal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Logs+Internal.swift"; sourceTree = "<group>"; };
24762482
5B0A9B8A2E3BB98500A8131C /* GraphicsFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphicsFilter.swift; sourceTree = "<group>"; };
24772483
5B0A9B8C2E3BBB3D00A8131C /* GraphicsFilter+Reflection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GraphicsFilter+Reflection.swift"; sourceTree = "<group>"; };
2484+
5B3AF8A92E4B3AE6009E5375 /* EnrichedResourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnrichedResourceTests.swift; sourceTree = "<group>"; };
2485+
5B9B20C42E4609FC00C95B6C /* ShapeResourceBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShapeResourceBuilderTests.swift; sourceTree = "<group>"; };
24782486
5B9CB9E22E41F6F6005485E6 /* ImageRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRepresentable.swift; sourceTree = "<group>"; };
24792487
5B9CB9E42E41FD5C005485E6 /* Drawing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Drawing.swift; sourceTree = "<group>"; };
24802488
5B9CB9E62E420AC4005485E6 /* ImageRendererTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRendererTests.swift; sourceTree = "<group>"; };
24812489
5BCBC0CC2DF85AFE0094DCC2 /* SessionReplayPrivacyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionReplayPrivacyView.swift; sourceTree = "<group>"; };
2490+
5BE0EA2A2E66E8A200216E1C /* ShapeResourceBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShapeResourceBuilder.swift; sourceTree = "<group>"; };
2491+
5BE0EA2C2E66EF9B00216E1C /* Path+SessionReplay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Path+SessionReplay.swift"; sourceTree = "<group>"; };
2492+
5BE0EA2E2E66F23F00216E1C /* Path+SessionReplayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Path+SessionReplayTests.swift"; sourceTree = "<group>"; };
2493+
5BF7B51E2E44F7CE00E0B772 /* ShapeResource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShapeResource.swift; sourceTree = "<group>"; };
24822494
5BFDD7A82E28FDC9009A2CEE /* RUMWebViewContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RUMWebViewContext.swift; sourceTree = "<group>"; };
24832495
5BFE7B7A2E3CFCDA00B8FAA8 /* ImageRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRenderer.swift; sourceTree = "<group>"; };
24842496
61020C292757AD91005EEAEA /* BackgroundLocationMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundLocationMonitor.swift; sourceTree = "<group>"; };
@@ -4055,6 +4067,14 @@
40554067
path = WatchdogTerminations;
40564068
sourceTree = "<group>";
40574069
};
4070+
5B3AF8A82E4B3A7F009E5375 /* Models */ = {
4071+
isa = PBXGroup;
4072+
children = (
4073+
5B3AF8A92E4B3AE6009E5375 /* EnrichedResourceTests.swift */,
4074+
);
4075+
path = Models;
4076+
sourceTree = "<group>";
4077+
};
40584078
61020C272757AD63005EEAEA /* BackgroundEvents */ = {
40594079
isa = PBXGroup;
40604080
children = (
@@ -4088,18 +4108,19 @@
40884108
61054E022A6EE0DB00AAA894 /* DatadogSessionReplayTests */ = {
40894109
isa = PBXGroup;
40904110
children = (
4091-
960B26C12D03611400D7196F /* Resources */,
4092-
96E863712C9C547B0023BF78 /* SessionReplayOverrideTests.swift */,
4093-
61054F482A6EE1B900AAA894 /* SessionReplayTests.swift */,
4094-
61054F3D2A6EE1B900AAA894 /* SessionReplayConfigurationTests.swift */,
4095-
D2A434AD2A8E426C0028E329 /* DDSessionReplayTests.swift */,
4096-
96E863752C9C7E800023BF78 /* DDSessionReplayOverridesTests.swift */,
40974111
61054F882A6EE1BA00AAA894 /* Feature */,
40984112
61054F922A6EE1BA00AAA894 /* Helpers */,
4113+
5B3AF8A82E4B3A7F009E5375 /* Models */,
40994114
61054F4E2A6EE1BA00AAA894 /* Processor */,
41004115
61054F592A6EE1BA00AAA894 /* Recorder */,
4116+
960B26C12D03611400D7196F /* Resources */,
41014117
61054F3E2A6EE1B900AAA894 /* Utilities */,
41024118
61054F492A6EE1BA00AAA894 /* Writer */,
4119+
96E863712C9C547B0023BF78 /* SessionReplayOverrideTests.swift */,
4120+
61054F482A6EE1B900AAA894 /* SessionReplayTests.swift */,
4121+
61054F3D2A6EE1B900AAA894 /* SessionReplayConfigurationTests.swift */,
4122+
D2A434AD2A8E426C0028E329 /* DDSessionReplayTests.swift */,
4123+
96E863752C9C7E800023BF78 /* DDSessionReplayOverridesTests.swift */,
41034124
);
41044125
name = DatadogSessionReplayTests;
41054126
path = ../DatadogSessionReplay/Tests;
@@ -4141,6 +4162,7 @@
41414162
61054E132A6EE10A00AAA894 /* Utilities */ = {
41424163
isa = PBXGroup;
41434164
children = (
4165+
5BE0EA2C2E66EF9B00216E1C /* Path+SessionReplay.swift */,
41444166
61054E142A6EE10A00AAA894 /* UIImage+SessionReplay.swift */,
41454167
962D72BE2CF7538800F86EF0 /* CGImage+SessionReplay.swift */,
41464168
D22442C42CA301DA002E71E4 /* UIColor+SessionReplay.swift */,
@@ -4433,6 +4455,7 @@
44334455
61054F5B2A6EE1BA00AAA894 /* Utilties */ = {
44344456
isa = PBXGroup;
44354457
children = (
4458+
5BE0EA2E2E66F23F00216E1C /* Path+SessionReplayTests.swift */,
44364459
61054F5D2A6EE1BA00AAA894 /* UIView+SessionReplayTests.swift */,
44374460
61054F5F2A6EE1BA00AAA894 /* CGRect+SessionReplayTests.swift */,
44384461
);
@@ -5944,6 +5967,7 @@
59445967
960B26BA2D03541900D7196F /* SwiftUI */ = {
59455968
isa = PBXGroup;
59465969
children = (
5970+
5B9B20C42E4609FC00C95B6C /* ShapeResourceBuilderTests.swift */,
59475971
5B9CB9E62E420AC4005485E6 /* ImageRendererTests.swift */,
59485972
D21331C02D132F0600E4A6A1 /* SwiftUIWireframesBuilderTests.swift */,
59495973
962D72C42CF7806300F86EF0 /* GraphicsImageReflectionTests.swift */,
@@ -6205,22 +6229,16 @@
62056229
E2AA55E62C32C6D9002FEF28 /* ApplicationNotifications.swift */,
62066230
D23039B3298D5235001A1FA3 /* AppState.swift */,
62076231
D23039B5298D5235001A1FA3 /* BatteryStatus.swift */,
6208-
6174D6122BFDF16C00EC7469 /* BundleType.swift */,
62096232
D23039B6298D5235001A1FA3 /* CarrierInfo.swift */,
62106233
D23039BA298D5235001A1FA3 /* DatadogContext.swift */,
6211-
D2F8235229915E12003C7E99 /* DatadogSite.swift */,
62126234
D23039B7298D5235001A1FA3 /* DateProvider.swift */,
62136235
D23039BC298D5235001A1FA3 /* DeviceInfo.swift */,
62146236
D23039BE298D5235001A1FA3 /* LaunchInfo.swift */,
6215-
D2F8235229915E12003C7E99 /* DatadogSite.swift */,
6216-
6174D6122BFDF16C00EC7469 /* BundleType.swift */,
6217-
D23039BE298D5235001A1FA3 /* LaunchTime.swift */,
62186237
D23039B9298D5235001A1FA3 /* NetworkConnectionInfo.swift */,
62196238
11B5439E2DE9C40B006F6C0A /* OperatingSystem+Utils.swift */,
62206239
D23039B8298D5235001A1FA3 /* Sysctl.swift */,
62216240
D23039BB298D5235001A1FA3 /* TrackingConsent.swift */,
62226241
D23039B4298D5235001A1FA3 /* UserInfo.swift */,
6223-
8648D07A2E01ABB0002F226B /* BrightnessStatus.swift */,
62246242
D2F8235229915E12003C7E99 /* DatadogSite.swift */,
62256243
6174D6122BFDF16C00EC7469 /* BundleType.swift */,
62266244
8648D07A2E01ABB0002F226B /* BrightnessLevel.swift */,
@@ -6641,6 +6659,8 @@
66416659
962D72BB2CF6436600F86EF0 /* GraphicsImage+Reflection.swift */,
66426660
5B9CB9E22E41F6F6005485E6 /* ImageRepresentable.swift */,
66436661
5BFE7B7A2E3CFCDA00B8FAA8 /* ImageRenderer.swift */,
6662+
5BF7B51E2E44F7CE00E0B772 /* ShapeResource.swift */,
6663+
5BE0EA2A2E66E8A200216E1C /* ShapeResourceBuilder.swift */,
66446664
D2AD1CBE2CE4AE6600106C74 /* SwiftUIWireframesBuilder.swift */,
66456665
D2AD1CBF2CE4AE6600106C74 /* Text.swift */,
66466666
D2AD1CC02CE4AE6600106C74 /* Text+Reflection.swift */,
@@ -8531,6 +8551,7 @@
85318551
A7B932FB2B1F6A0A00AE6477 /* EnrichedRecord.swift in Sources */,
85328552
61054E8D2A6EE10A00AAA894 /* RUMContextReceiver.swift in Sources */,
85338553
A7B932FD2B1F6A0A00AE6477 /* EnrichedResource.swift in Sources */,
8554+
5BE0EA2D2E66EFA300216E1C /* Path+SessionReplay.swift in Sources */,
85348555
61054E622A6EE10A00AAA894 /* RecordWriter.swift in Sources */,
85358556
61054E692A6EE10A00AAA894 /* UIImage+SessionReplay.swift in Sources */,
85368557
5B0A9B8B2E3BB98E00A8131C /* GraphicsFilter.swift in Sources */,
@@ -8554,6 +8575,7 @@
85548575
61054E8B2A6EE10A00AAA894 /* SessionReplayFeature.swift in Sources */,
85558576
61054E992A6EE10A00AAA894 /* WireframesBuilder.swift in Sources */,
85568577
61054E892A6EE10A00AAA894 /* NodeIDGenerator.swift in Sources */,
8578+
5BE0EA2B2E66E8A800216E1C /* ShapeResourceBuilder.swift in Sources */,
85578579
61054E962A6EE10A00AAA894 /* Diff+SRWireframes.swift in Sources */,
85588580
61054E902A6EE10A00AAA894 /* SegmentJSON.swift in Sources */,
85598581
61054E672A6EE10A00AAA894 /* Recorder.swift in Sources */,
@@ -8577,6 +8599,7 @@
85778599
61054E972A6EE10A00AAA894 /* Diff.swift in Sources */,
85788600
61054E6E2A6EE10A00AAA894 /* RecordingCoordinator.swift in Sources */,
85798601
61054E9F2A6EE10B00AAA894 /* Errors.swift in Sources */,
8602+
5BF7B51F2E44F7D300E0B772 /* ShapeResource.swift in Sources */,
85808603
D29A470D2D2ED49F0092BC79 /* Xoshiro.swift in Sources */,
85818604
61054E642A6EE10A00AAA894 /* SessionReplay.swift in Sources */,
85828605
61054E952A6EE10A00AAA894 /* SnapshotProcessor.swift in Sources */,
@@ -8628,7 +8651,10 @@
86288651
960B26C32D075BD200D7196F /* DisplayListReflectionTests.swift in Sources */,
86298652
61054FD42A6EE1BA00AAA894 /* SegmentRequestBuilderTests.swift in Sources */,
86308653
61054FB52A6EE1BA00AAA894 /* UISliderRecorderTests.swift in Sources */,
8654+
5B9B20C52E460A0600C95B6C /* ShapeResourceBuilderTests.swift in Sources */,
86318655
61054FB22A6EE1BA00AAA894 /* UILabelRecorderTests.swift in Sources */,
8656+
5B3AF8AA2E4B3AE9009E5375 /* EnrichedResourceTests.swift in Sources */,
8657+
5BE0EA2F2E66F25200216E1C /* Path+SessionReplayTests.swift in Sources */,
86328658
D2C5D52D2B84F6D800B63F36 /* WebViewRecordReceiverTests.swift in Sources */,
86338659
61054FBA2A6EE1BA00AAA894 /* UIImageViewRecorderTests.swift in Sources */,
86348660
61054FC02A6EE1BA00AAA894 /* UITextViewRecorderTests.swift in Sources */,
@@ -9998,7 +10024,7 @@
999810024
D2EBEE3829BA161100B15732 /* TracingHTTPHeaders.swift in Sources */,
999910025
D21A94F32B8397CA00AC4256 /* WebViewMessage.swift in Sources */,
1000010026
D2DA2364298D57AA00C6C7E6 /* LaunchInfo.swift in Sources */,
10001-
D2DA2364298D57AA00C6C7E6 /* LaunchTime.swift in Sources */,
10027+
D2DA2364298D57AA00C6C7E6 /* LaunchInfo.swift in Sources */,
1000210028
D2E8A8E72DCBBA5100CF7C63 /* RUMCoreContext.swift in Sources */,
1000310029
6175C3522BCE66DB006FAAB0 /* TraceContext.swift in Sources */,
1000410030
D227A0A52C7622EA00C83324 /* BenchmarkProfiler.swift in Sources */,

DatadogSessionReplay/SRSnapshotTests/SRSnapshotTests.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
5BA0067B2E49F6A3000148DB /* UIImage+SVG.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA0067A2E49F698000148DB /* UIImage+SVG.swift */; };
11+
5BA0067D2E49F8BF000148DB /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA0067C2E49F8B3000148DB /* UIColor+Hex.swift */; };
1012
5BB746152E02ABB900B568F1 /* SwiftUIFixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BB746142E02ABB500B568F1 /* SwiftUIFixture.swift */; };
1113
5BB746182E02B4CD00B568F1 /* SwiftUIViewWithPrivacyOverrides.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BB746172E02B4CD00B568F1 /* SwiftUIViewWithPrivacyOverrides.swift */; };
1214
614396642A5E8C0600197326 /* Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614396632A5E8C0600197326 /* Environment.swift */; };
@@ -40,6 +42,8 @@
4042
/* End PBXContainerItemProxy section */
4143

4244
/* Begin PBXFileReference section */
45+
5BA0067A2E49F698000148DB /* UIImage+SVG.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+SVG.swift"; sourceTree = "<group>"; };
46+
5BA0067C2E49F8B3000148DB /* UIColor+Hex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Hex.swift"; sourceTree = "<group>"; };
4347
5BB746142E02ABB500B568F1 /* SwiftUIFixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIFixture.swift; sourceTree = "<group>"; };
4448
5BB746172E02B4CD00B568F1 /* SwiftUIViewWithPrivacyOverrides.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIViewWithPrivacyOverrides.swift; sourceTree = "<group>"; };
4549
614396632A5E8C0600197326 /* Environment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Environment.swift; path = SRHost/Environment.swift; sourceTree = "<group>"; };
@@ -101,6 +105,8 @@
101105
619C49B529955106006B66A6 /* Utils */ = {
102106
isa = PBXGroup;
103107
children = (
108+
5BA0067C2E49F8B3000148DB /* UIColor+Hex.swift */,
109+
5BA0067A2E49F698000148DB /* UIImage+SVG.swift */,
104110
5BB746142E02ABB500B568F1 /* SwiftUIFixture.swift */,
105111
619C49B329952E12006B66A6 /* SnapshotTestCase.swift */,
106112
96363B2B2CD26AF3006FEC9D /* PrivacyOverrides.swift */,
@@ -304,8 +310,10 @@
304310
files = (
305311
619C49BB299639BC006B66A6 /* ImageRendering.swift in Sources */,
306312
614396652A5E8C0600197326 /* Environment.swift in Sources */,
313+
5BA0067B2E49F6A3000148DB /* UIImage+SVG.swift in Sources */,
307314
61B3BC652993BEAF0032C78A /* SRSnapshotTests.swift in Sources */,
308315
96363B2C2CD26AF3006FEC9D /* PrivacyOverrides.swift in Sources */,
316+
5BA0067D2E49F8BF000148DB /* UIColor+Hex.swift in Sources */,
309317
61BB975F2A5D675400AFFF86 /* ImageComposition.swift in Sources */,
310318
5BB746182E02B4CD00B568F1 /* SwiftUIViewWithPrivacyOverrides.swift in Sources */,
311319
619C49B72995512A006B66A6 /* ImageComparison.swift in Sources */,

DatadogSessionReplay/SRSnapshotTests/SRSnapshotTests/Utils/ImageRendering.swift

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,15 @@ private extension SRWireframe {
5959
case .textWireframe(let text):
6060
return text.toFrame()
6161
case .imageWireframe(value: let image):
62-
return image.toFrame(
63-
imageData: resources
64-
.first { $0.calculateIdentifier() == image.resourceId }?
65-
.calculateData()
66-
)
62+
let resource = resources.first {
63+
$0.calculateIdentifier() == image.resourceId
64+
}
65+
switch resource?.mimeType {
66+
case .some("image/svg+xml"):
67+
return image.toFrame(svgData: resource?.calculateData())
68+
default:
69+
return image.toFrame(imageData: resource?.calculateData())
70+
}
6771
case .placeholderWireframe(value: let placeholder):
6872
return placeholder.toFrame()
6973
case .webviewWireframe(value: let webview):
@@ -115,6 +119,19 @@ private extension SRImageWireframe {
115119
content: .init(imageData: imageData)
116120
)
117121
}
122+
123+
func toFrame(svgData: Data?) -> BlueprintFrame {
124+
BlueprintFrame(
125+
x: x,
126+
y: y,
127+
width: width,
128+
height: height,
129+
border: border,
130+
style: shapeStyle,
131+
clip: clip,
132+
content: .init(svgData: svgData)
133+
)
134+
}
118135
}
119136

120137
private extension SRWebviewWireframe {
@@ -267,23 +284,10 @@ extension BlueprintFrame.Content {
267284
let contentType: BlueprintFrame.Content.ContentType = .image(image: image)
268285
self.init(contentType: contentType)
269286
}
270-
}
271-
272-
private extension UIColor {
273-
convenience init(hexString: String) {
274-
precondition(hexString.count == 9, "Invalid `hexString` - expected 9 characters, got '\(hexString)'")
275-
precondition(hexString.hasPrefix("#"), "Invalid `hexString` - expected # prefix, got '\(hexString)'")
276287

277-
guard let hex8 = UInt64(hexString.dropFirst(), radix: 16) else {
278-
preconditionFailure("Invalid `hexString`` - expected hexadecimal value, got '\(hexString)'")
279-
}
280-
281-
let mask: UInt64 = 0x00000000FF
282-
self.init(
283-
red: CGFloat((hex8 >> 24) & mask) / CGFloat(255),
284-
green: CGFloat((hex8 >> 16) & mask) / CGFloat(255),
285-
blue: CGFloat((hex8 >> 8) & mask) / CGFloat(255),
286-
alpha: CGFloat(hex8 & mask) / CGFloat(255)
287-
)
288+
init(svgData: Data?) {
289+
let image = svgData.flatMap { UIImage(svgData: $0, scale: UIScreen.main.scale) } ?? UIImage()
290+
let contentType: BlueprintFrame.Content.ContentType = .image(image: image)
291+
self.init(contentType: contentType)
288292
}
289293
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2019-Present Datadog, Inc.
5+
*/
6+
7+
import UIKit
8+
9+
extension UIColor {
10+
convenience init(hexString: String) {
11+
precondition(hexString.count == 9, "Invalid `hexString` - expected 9 characters, got '\(hexString)'")
12+
precondition(hexString.hasPrefix("#"), "Invalid `hexString` - expected # prefix, got '\(hexString)'")
13+
14+
guard let hex8 = UInt64(hexString.dropFirst(), radix: 16) else {
15+
preconditionFailure("Invalid `hexString`` - expected hexadecimal value, got '\(hexString)'")
16+
}
17+
18+
let mask: UInt64 = 0x00000000FF
19+
self.init(
20+
red: CGFloat((hex8 >> 24) & mask) / CGFloat(255),
21+
green: CGFloat((hex8 >> 16) & mask) / CGFloat(255),
22+
blue: CGFloat((hex8 >> 8) & mask) / CGFloat(255),
23+
alpha: CGFloat(hex8 & mask) / CGFloat(255)
24+
)
25+
}
26+
}

0 commit comments

Comments
 (0)