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

RUMM-3151 feat: reduce number of view updates by filtering events fro… #1359

Closed
Closed
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: 2 additions & 2 deletions BenchmarkTests/BenchmarkMocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ extension PerformancePreset {
struct FeatureRequestBuilderMock: FeatureRequestBuilder {
let dataFormat = DataFormat(prefix: "", suffix: "", separator: "\n")

func request(for events: [Data], with context: DatadogContext) -> URLRequest {
func request(for events: [Event], with context: DatadogContext) -> URLRequest {
let builder = URLRequestBuilder(
url: .mockAny(),
queryItems: [.ddtags(tags: ["foo:bar"])],
headers: []
)

let data = dataFormat.format(events)
let data = dataFormat.format(events.map { $0.data })
return builder.uploadRequest(with: data)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class DataUploaderBenchmarkTests: BenchmarkTests {
measure(metrics: [XCTMemoryMetric()]) {
// in each, 10 requests are done:
try? (0..<10).forEach { _ in
let events = [Data(repeating: 0x41, count: 10 * 1_024 * 1_024)]
let events = [Event(data: Data(repeating: 0x41, count: 10 * 1_024 * 1_024))]
_ = try dataUploader.upload(events: events, context: context)
}
// After all, the baseline asserts `0kB` or less grow in Physical Memory.
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- [IMPROVEMENT] Reduce number of view updates by filtering events from payload. See [#1328][]

# 1.21.0 / 27-07-2023
- [BUGFIX] Fix TracingUUID string format. See [#1311][] (Thanks [@changm4n][])
- [BUGFIX] Rename _Datadog_Private to DatadogPrivate. See [#1331] (Thanks [@alexfanatics][])
Expand Down Expand Up @@ -472,6 +474,7 @@
[#1311]: https://github.com/DataDog/dd-sdk-ios/pull/1311
[#1315]: https://github.com/DataDog/dd-sdk-ios/pull/1315
[#1331]: https://github.com/DataDog/dd-sdk-ios/pull/1331
[#1328]: https://github.com/DataDog/dd-sdk-ios/pull/1328
[@00fa9a]: https://github.com/00FA9A
[@britton-earnin]: https://github.com/Britton-Earnin
[@hengyu]: https://github.com/Hengyu
Expand Down
42 changes: 42 additions & 0 deletions Datadog/Datadog.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@
objects = {

/* Begin PBXBuildFile section */
3C0D5DD72A543B3B00446CF9 /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DD62A543B3B00446CF9 /* Event.swift */; };
3C0D5DD82A543B3B00446CF9 /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DD62A543B3B00446CF9 /* Event.swift */; };
3C0D5DE22A543DC400446CF9 /* EventGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DDF2A543DAE00446CF9 /* EventGeneratorTests.swift */; };
3C0D5DE32A543DC900446CF9 /* EventGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DDF2A543DAE00446CF9 /* EventGeneratorTests.swift */; };
3C0D5DE42A543E3400446CF9 /* EventGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DDC2A543D5D00446CF9 /* EventGenerator.swift */; };
3C0D5DE52A543E3500446CF9 /* EventGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DDC2A543D5D00446CF9 /* EventGenerator.swift */; };
3C0D5DE92A543EA200446CF9 /* RUMViewEventsFilterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DE62A543E9700446CF9 /* RUMViewEventsFilterTests.swift */; };
3C0D5DEA2A543EA300446CF9 /* RUMViewEventsFilterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DE62A543E9700446CF9 /* RUMViewEventsFilterTests.swift */; };
3C0D5DEC2A54405A00446CF9 /* RUMViewEventsFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DEB2A54405A00446CF9 /* RUMViewEventsFilter.swift */; };
3C0D5DED2A54405A00446CF9 /* RUMViewEventsFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DEB2A54405A00446CF9 /* RUMViewEventsFilter.swift */; };
3C0D5DEF2A5442A900446CF9 /* EventMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DEE2A5442A900446CF9 /* EventMocks.swift */; };
3C0D5DF02A5442A900446CF9 /* EventMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DEE2A5442A900446CF9 /* EventMocks.swift */; };
3C0D5DF52A5443B100446CF9 /* DataFormatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DF42A5443B100446CF9 /* DataFormatTests.swift */; };
3C0D5DF62A5443B100446CF9 /* DataFormatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D5DF42A5443B100446CF9 /* DataFormatTests.swift */; };
3C41693C29FBF4D50042B9D2 /* DatadogWebViewTracking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CE119FE29F7BE0100202522 /* DatadogWebViewTracking.framework */; };
3C41694729FBF8CC0042B9D2 /* DatadogInternal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2DA2385298D57AA00C6C7E6 /* DatadogInternal.framework */; };
3C74305C29FBC0480053B80F /* DatadogInternal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2DA2385298D57AA00C6C7E6 /* DatadogInternal.framework */; };
Expand Down Expand Up @@ -1668,6 +1682,13 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
3C0D5DD62A543B3B00446CF9 /* Event.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Event.swift; sourceTree = "<group>"; };
3C0D5DDC2A543D5D00446CF9 /* EventGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventGenerator.swift; sourceTree = "<group>"; };
3C0D5DDF2A543DAE00446CF9 /* EventGeneratorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventGeneratorTests.swift; sourceTree = "<group>"; };
3C0D5DE62A543E9700446CF9 /* RUMViewEventsFilterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RUMViewEventsFilterTests.swift; sourceTree = "<group>"; };
3C0D5DEB2A54405A00446CF9 /* RUMViewEventsFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RUMViewEventsFilter.swift; sourceTree = "<group>"; };
3C0D5DEE2A5442A900446CF9 /* EventMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventMocks.swift; sourceTree = "<group>"; };
3C0D5DF42A5443B100446CF9 /* DataFormatTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataFormatTests.swift; sourceTree = "<group>"; };
3C85D41429F7C59C00AFF894 /* WebViewTracking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewTracking.swift; sourceTree = "<group>"; };
3C85D41529F7C59C00AFF894 /* WebViewTrackingMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewTrackingMessage.swift; sourceTree = "<group>"; };
3C85D41629F7C59C00AFF894 /* WKUserContentController+Datadog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WKUserContentController+Datadog.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2860,6 +2881,7 @@
D29CDD3128211A2200F7DAA5 /* DataBlock.swift */,
D2DC4BF527F484AA00E4FB96 /* DataEncryption.swift */,
61133BA92423979B00786299 /* FilesOrchestrator.swift */,
3C0D5DDC2A543D5D00446CF9 /* EventGenerator.swift */,
D2A7841429A53B92003B03BB /* Files */,
613E79412577C08900DFCC17 /* Writing */,
613E79422577C09B00DFCC17 /* Reading */,
Expand Down Expand Up @@ -3043,6 +3065,7 @@
61133C272423990D00786299 /* Persistence */ = {
isa = PBXGroup;
children = (
3C0D5DDF2A543DAE00446CF9 /* EventGeneratorTests.swift */,
61133C2A2423990D00786299 /* FilesOrchestratorTests.swift */,
D2B3F0432823EE8300C2B5EE /* DataBlockTests.swift */,
619E16D42577C11B00B2516B /* Writing */,
Expand Down Expand Up @@ -4336,6 +4359,7 @@
D23039D4298D5235001A1FA3 /* DataCompression.swift */,
D23039D5298D5235001A1FA3 /* FeatureRequestBuilder.swift */,
D2D3199929E98D970004F169 /* DefaultJSONEncoder.swift */,
3C0D5DD62A543B3B00446CF9 /* Event.swift */,
);
path = Upload;
sourceTree = "<group>";
Expand Down Expand Up @@ -4459,6 +4483,7 @@
D2EBEE4729BA17C400B15732 /* NetworkInstrumentationMocks.swift */,
61C3646F243B5C8300C4D4E6 /* ServerMock.swift */,
D2160CF629C0EE2B00FAA9A5 /* UploadMocks.swift */,
3C0D5DEE2A5442A900446CF9 /* EventMocks.swift */,
);
path = Mocks;
sourceTree = "<group>";
Expand Down Expand Up @@ -4523,6 +4548,7 @@
D25FF2E729CC6B680063802D /* RUMFeature.swift */,
D25FF2ED29CC73240063802D /* RequestBuilder.swift */,
D25FF2F329CC88060063802D /* RUMBaggageKeys.swift */,
3C0D5DEB2A54405A00446CF9 /* RUMViewEventsFilter.swift */,
);
path = Feature;
sourceTree = "<group>";
Expand Down Expand Up @@ -4589,6 +4615,7 @@
D29A9F3F29DD84AB005C54A4 /* DatadogRUMTests */ = {
isa = PBXGroup;
children = (
3C0D5DE62A543E9700446CF9 /* RUMViewEventsFilterTests.swift */,
61C713AC2A3B793E00FA735A /* RUMMonitorProtocolTests.swift */,
61C713B52A3C600400FA735A /* RUMMonitorProtocol+ConvenienceTests.swift */,
61C713B22A3C3A0B00FA735A /* RUMMonitorProtocol+InternalTests.swift */,
Expand Down Expand Up @@ -4831,6 +4858,7 @@
D2F44FBA299AA2310074B0D9 /* Upload */ = {
isa = PBXGroup;
children = (
3C0D5DF42A5443B100446CF9 /* DataFormatTests.swift */,
D213532F270CA722000315AD /* DataCompressionTests.swift */,
);
path = Upload;
Expand Down Expand Up @@ -6397,6 +6425,7 @@
61D3E0D5277B23F1008BE766 /* KronosNTPPacket.swift in Sources */,
61133BCF2423979B00786299 /* FileWriter.swift in Sources */,
6179FFD3254ADB1700556A0B /* ObjcAppLaunchHandler.m in Sources */,
3C0D5DE42A543E3400446CF9 /* EventGenerator.swift in Sources */,
D2303A0A298D5412001A1FA3 /* AsyncWriter.swift in Sources */,
D29CDD3228211A2200F7DAA5 /* DataBlock.swift in Sources */,
D2553829288F0B2400727FAD /* LowPowerModePublisher.swift in Sources */,
Expand Down Expand Up @@ -6477,6 +6506,7 @@
D22743DC29DEB8B4001A7EF9 /* VitalRefreshRateReaderTests.swift in Sources */,
617B954224BF4E7600E6F443 /* RUMMonitorConfigurationTests.swift in Sources */,
61F9CABA2513A7F5000A5E61 /* RUMSessionMatcher.swift in Sources */,
3C0D5DE22A543DC400446CF9 /* EventGeneratorTests.swift in Sources */,
61C3638324361BE200C4D4E6 /* DatadogPrivateMocks.swift in Sources */,
D26C49AF2886DC7B00802B2D /* ApplicationStatePublisherTests.swift in Sources */,
6147989C2A459E2B0095CB02 /* DDTrace+apiTests.m in Sources */,
Expand Down Expand Up @@ -6855,6 +6885,7 @@
D23039FD298D5236001A1FA3 /* DataCompression.swift in Sources */,
D23039F0298D5236001A1FA3 /* AnyEncoder.swift in Sources */,
D2A783D429A5309F003B03BB /* SwiftExtensions.swift in Sources */,
3C0D5DD72A543B3B00446CF9 /* Event.swift in Sources */,
D22F06D929DAFD500026CC3C /* TimeInterval+Convenience.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -6902,6 +6933,7 @@
D23F8E7429DDCD28001CFAE8 /* RUMCommandSubscriber.swift in Sources */,
D23F8E7529DDCD28001CFAE8 /* RUMUserActionScope.swift in Sources */,
61C713A42A3B78F900FA735A /* RUMMonitorProtocol.swift in Sources */,
3C0D5DED2A54405A00446CF9 /* RUMViewEventsFilter.swift in Sources */,
D23F8E7629DDCD28001CFAE8 /* RUMConnectivityInfoProvider.swift in Sources */,
D23F8E7729DDCD28001CFAE8 /* UIKitRUMViewsPredicate.swift in Sources */,
61C713A62A3B78F900FA735A /* RUMMonitorProtocol+Internal.swift in Sources */,
Expand Down Expand Up @@ -6969,6 +7001,7 @@
D23F8EBF29DDCD38001CFAE8 /* URLSessionRUMResourcesHandlerTests.swift in Sources */,
D23F8EC029DDCD38001CFAE8 /* RUMEventSanitizerTests.swift in Sources */,
D23F8EC129DDCD38001CFAE8 /* RUMEventsMapperTests.swift in Sources */,
3C0D5DEA2A543EA300446CF9 /* RUMViewEventsFilterTests.swift in Sources */,
D23F8EC429DDCD38001CFAE8 /* RUMCommandTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -6998,6 +7031,7 @@
D24C9C6929A7CE06002057CF /* DDErrorMocks.swift in Sources */,
D2579558298ABB04008A1BE5 /* Encoding.swift in Sources */,
D2EBEE4829BA17C400B15732 /* NetworkInstrumentationMocks.swift in Sources */,
3C0D5DEF2A5442A900446CF9 /* EventMocks.swift in Sources */,
D24C9C5529A7C5F3002057CF /* RelativeDateProvider.swift in Sources */,
D2579559298ABB04008A1BE5 /* DDAssert.swift in Sources */,
D2579552298ABB04008A1BE5 /* FileWriterMock.swift in Sources */,
Expand Down Expand Up @@ -7031,6 +7065,7 @@
D24C9C6A29A7CE06002057CF /* DDErrorMocks.swift in Sources */,
D257957B298ABB83008A1BE5 /* Encoding.swift in Sources */,
D2EBEE4929BA17C400B15732 /* NetworkInstrumentationMocks.swift in Sources */,
3C0D5DF02A5442A900446CF9 /* EventMocks.swift in Sources */,
D24C9C5629A7C5F3002057CF /* RelativeDateProvider.swift in Sources */,
D257957C298ABB83008A1BE5 /* DDAssert.swift in Sources */,
D257957D298ABB83008A1BE5 /* FileWriterMock.swift in Sources */,
Expand Down Expand Up @@ -7151,6 +7186,7 @@
D29A9F5D29DD85BB005C54A4 /* RUMCommandSubscriber.swift in Sources */,
D29A9F6529DD85BB005C54A4 /* RUMUserActionScope.swift in Sources */,
61C713A32A3B78F900FA735A /* RUMMonitorProtocol.swift in Sources */,
3C0D5DEC2A54405A00446CF9 /* RUMViewEventsFilter.swift in Sources */,
D29A9F5829DD85BB005C54A4 /* RUMConnectivityInfoProvider.swift in Sources */,
D29A9F5E29DD85BB005C54A4 /* UIKitRUMViewsPredicate.swift in Sources */,
61C713A52A3B78F900FA735A /* RUMMonitorProtocol+Internal.swift in Sources */,
Expand Down Expand Up @@ -7218,6 +7254,7 @@
D29A9F9A29DDB483005C54A4 /* URLSessionRUMResourcesHandlerTests.swift in Sources */,
D29A9FA229DDB483005C54A4 /* RUMEventSanitizerTests.swift in Sources */,
D29A9FB929DDB483005C54A4 /* RUMEventsMapperTests.swift in Sources */,
3C0D5DE92A543EA200446CF9 /* RUMViewEventsFilterTests.swift in Sources */,
D29A9FA729DDB483005C54A4 /* RUMCommandTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -7306,6 +7343,7 @@
D2CB6E2927C50EAE00A62B57 /* KronosInternetAddress.swift in Sources */,
D2CB6E2C27C50EAE00A62B57 /* KronosNTPPacket.swift in Sources */,
D2CB6E3127C50EAE00A62B57 /* FileWriter.swift in Sources */,
3C0D5DE52A543E3500446CF9 /* EventGenerator.swift in Sources */,
D2EFA869286DA85700F1FAA6 /* DatadogContextProvider.swift in Sources */,
D2B3F04E282A85FD00C2B5EE /* DatadogCore.swift in Sources */,
D2303A0B298D5412001A1FA3 /* AsyncWriter.swift in Sources */,
Expand Down Expand Up @@ -7378,6 +7416,7 @@
D2EFA876286E011900F1FAA6 /* DatadogContextProviderTests.swift in Sources */,
614B78F2296D7B63009C6B92 /* LowPowerModePublisherTests.swift in Sources */,
D2CB6EEE27C520D400A62B57 /* DDErrorTests.swift in Sources */,
3C0D5DE32A543DC900446CF9 /* EventGeneratorTests.swift in Sources */,
D25CFAA229C8644E00E3A43D /* Casting+Tracing.swift in Sources */,
D2CB6EF227C520D400A62B57 /* KronosTimeStorageTests.swift in Sources */,
D2CB6EF427C520D400A62B57 /* FileWriterTests.swift in Sources */,
Expand Down Expand Up @@ -7622,6 +7661,7 @@
D2DA237D298D57AA00C6C7E6 /* DataCompression.swift in Sources */,
D2DA237E298D57AA00C6C7E6 /* AnyEncoder.swift in Sources */,
D2A783D529A530A0003B03BB /* SwiftExtensions.swift in Sources */,
3C0D5DD82A543B3B00446CF9 /* Event.swift in Sources */,
D22F06DA29DAFD500026CC3C /* TimeInterval+Convenience.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -7636,6 +7676,7 @@
D21AE6BC29E5EDAF0064BF29 /* TelemetryTests.swift in Sources */,
D2DA23A3298D58F400C6C7E6 /* AnyEncodableTests.swift in Sources */,
D263BCB429DB014900FA0E21 /* FixedWidthInteger+ConvenienceTests.swift in Sources */,
3C0D5DF52A5443B100446CF9 /* DataFormatTests.swift in Sources */,
D2EBEE4429BA168200B15732 /* TraceIDTests.swift in Sources */,
D2EBEE4329BA168200B15732 /* TraceIDGeneratorTests.swift in Sources */,
D2DA23A7298D58F400C6C7E6 /* AppStateHistoryTests.swift in Sources */,
Expand Down Expand Up @@ -7672,6 +7713,7 @@
D21AE6BD29E5EDAF0064BF29 /* TelemetryTests.swift in Sources */,
D2DA23B1298D59DC00C6C7E6 /* AnyEncodableTests.swift in Sources */,
D263BCB529DB014900FA0E21 /* FixedWidthInteger+ConvenienceTests.swift in Sources */,
3C0D5DF62A5443B100446CF9 /* DataFormatTests.swift in Sources */,
D2EBEE4629BA168400B15732 /* TraceIDTests.swift in Sources */,
D2EBEE4529BA168400B15732 /* TraceIDGeneratorTests.swift in Sources */,
D2DA23B2298D59DC00C6C7E6 /* AppStateHistoryTests.swift in Sources */,
Expand Down
5 changes: 5 additions & 0 deletions DatadogCore/Sources/Core/Storage/DataBlock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import Foundation
import DatadogInternal

/// Block size binary type
internal typealias BlockSize = UInt32
Expand All @@ -14,7 +15,11 @@ private let MAX_DATA_LENGTH: UInt64 = 10 * 1_024 * 1_024

/// Block type supported in data stream
internal enum BlockType: UInt16 {
/// Represents an event
case event = 0x00
/// Represents an event metadata associated with the previous event.
/// This block is optional and may be omitted.
case eventMetadata = 0x01
}

/// Reported errors while manipulating data blocks.
Expand Down
60 changes: 60 additions & 0 deletions DatadogCore/Sources/Core/Storage/EventGenerator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2019-Present Datadog, Inc.
*/

import Foundation
import DatadogInternal

/// Event generator that generates events from the given data blocks.
internal struct EventGenerator: Sequence, IteratorProtocol {
private let dataBlocks: [DataBlock]
private var index: Int

init(dataBlocks: [DataBlock], index: Int = 0) {
self.dataBlocks = dataBlocks
self.index = index
}

/// Returns the next event.
///
/// Data format
/// ```
/// [EVENT 1 METADATA] [EVENT 1] [EVENT 2 METADATA] [EVENT 2] [EVENT 3]
/// ```
///
/// - Returns: The next event or `nil` if there are no more events.
/// - Note: a `DataBlock` with `.event` type marks the beginning of the event.
/// It is either followed by another `DataBlock` with `.event` type or
/// by a `DataBlock` with `.metadata` type.
mutating func next() -> Event? {
guard index < dataBlocks.count else {
return nil
}

var metadata: DataBlock? = nil
// If the next block is an event metadata, read it.
if dataBlocks[index].type == .eventMetadata {
metadata = dataBlocks[index]
index += 1
}

// If this is the last block, return nil.
// there cannot be a metadata block without an event block.
guard index < dataBlocks.count else {
return nil
}

// If the next block is an event, read it.
guard dataBlocks[index].type == .event else {
// this is safeguard against corrupted data.
// if there was a metadata block, it will be skipped.
return next()
}
let event = dataBlocks[index]
index += 1

return Event(data: event.data, metadata: metadata?.data)
}
}
Loading