diff --git a/ .gitattributes b/ .gitattributes new file mode 100644 index 0000000000..4157440bf2 --- /dev/null +++ b/ .gitattributes @@ -0,0 +1 @@ +CHANGELOG.md merge=union \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 046e8937a3..b7243af3a9 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -10,3 +10,4 @@ A brief description of implementation details of this PR. - [ ] Feature or bugfix MUST have appropriate tests (unit, integration) - [ ] Make sure each commit and the PR mention the Issue number or JIRA reference +- [ ] Add CHANGELOG entry for user facing change. diff --git a/CHANGELOG.md b/CHANGELOG.md index 96adb783dd..48dae2a2f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# Unreleased + +* [FEATURE] Web-view tracking. See [#729][] +* [FEATURE] Integration with CI Visibility Tests. See[#761][] +* [FEATURE] Add tvOS Support. See [#793][] +* [BUGFIX] Strip query parameters from span resource. See [#728][] +* [BUGFIX] Stop reporting pre-warmed application launch time. See [#789][] +* [BUGFIX] Allow log event dropping. See [#795][] +* [IMPROVEMENT] Crash Reporting: Filter out unrecognized trailing `???` stack frame in `error.stack`. See [#794][] + # 1.9.0 / 01-26-2022 ### Changes @@ -317,6 +327,13 @@ [#715]: https://github.com/DataDog/dd-sdk-ios/issues/715 [#724]: https://github.com/DataDog/dd-sdk-ios/issues/724 [#725]: https://github.com/DataDog/dd-sdk-ios/issues/725 +[#728]: https://github.com/DataDog/dd-sdk-ios/issues/728 +[#729]: https://github.com/DataDog/dd-sdk-ios/issues/729 +[#761]: https://github.com/DataDog/dd-sdk-ios/issues/761 +[#789]: https://github.com/DataDog/dd-sdk-ios/issues/789 +[#793]: https://github.com/DataDog/dd-sdk-ios/issues/793 +[#794]: https://github.com/DataDog/dd-sdk-ios/issues/794 +[#795]: https://github.com/DataDog/dd-sdk-ios/issues/795 [@00FA9A]: https://github.com/00FA9A [@Britton-Earnin]: https://github.com/Britton-Earnin [@Hengyu]: https://github.com/Hengyu @@ -341,4 +358,4 @@ [@provTheodoreNewell]: https://github.com/provTheodoreNewell [@safa-ads]: https://github.com/safa-ads [@sdejesusF]: https://github.com/sdejesusF -[@AvdLee]: https://github.com/AvdLee \ No newline at end of file +[@AvdLee]: https://github.com/AvdLee diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index 717a2aeac1..86cba2396f 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -170,16 +170,14 @@ 61410167251A661D00E3C2D9 /* UIApplicationSwizzlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61410166251A661D00E3C2D9 /* UIApplicationSwizzlerTests.swift */; }; 61411B1024EC15AC0012EAB2 /* Casting+RUM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61411B0F24EC15AC0012EAB2 /* Casting+RUM.swift */; }; 61441C0524616DE9003D8BB8 /* ExampleAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61441C0424616DE9003D8BB8 /* ExampleAppDelegate.swift */; }; - 61441C0C24616DE9003D8BB8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61441C0A24616DE9003D8BB8 /* Main.storyboard */; }; + 61441C0C24616DE9003D8BB8 /* Main iOS.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61441C0A24616DE9003D8BB8 /* Main iOS.storyboard */; }; 61441C0E24616DEC003D8BB8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 61441C0D24616DEC003D8BB8 /* Assets.xcassets */; }; - 61441C1124616DEC003D8BB8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61441C0F24616DEC003D8BB8 /* LaunchScreen.storyboard */; }; 61441C4024617013003D8BB8 /* IntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61441C3B24617013003D8BB8 /* IntegrationTests.swift */; }; 61441C4124617013003D8BB8 /* LoggingScenarioTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61441C3C24617013003D8BB8 /* LoggingScenarioTests.swift */; }; 61441C44246174CE003D8BB8 /* HTTPServerMock in Frameworks */ = {isa = PBXBuildFile; productRef = 61441C43246174CE003D8BB8 /* HTTPServerMock */; }; 61441C4924618052003D8BB8 /* JSONDataMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E45BE624519A3700F2C652 /* JSONDataMatcher.swift */; }; 61441C4A24618052003D8BB8 /* LogMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C432423990D00786299 /* LogMatcher.swift */; }; 61441C4B24618052003D8BB8 /* SpanMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E45ED02451A8730061DAC7 /* SpanMatcher.swift */; }; - 61441C4E24619498003D8BB8 /* Datadog.framework in ⚙️ Embed Framework Dependencies */ = {isa = PBXBuildFile; fileRef = 61133B82242393DE00786299 /* Datadog.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 61441C6D24619FE4003D8BB8 /* Datadog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61133B82242393DE00786299 /* Datadog.framework */; platformFilter = ios; }; 61441C7A2461A204003D8BB8 /* LoggingBenchmarkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61441C782461A204003D8BB8 /* LoggingBenchmarkTests.swift */; }; 61441C7B2461A204003D8BB8 /* LoggingStorageBenchmarkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61441C792461A204003D8BB8 /* LoggingStorageBenchmarkTests.swift */; }; @@ -212,9 +210,6 @@ 614D812C24E3EA15004C9C5D /* Feature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614D812B24E3EA15004C9C5D /* Feature.swift */; }; 614E9EB3244719FA007EE3E1 /* BundleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614E9EB2244719FA007EE3E1 /* BundleType.swift */; }; 614ED36C260352DC00C8C519 /* CrashReporter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 614ED36B260352DC00C8C519 /* CrashReporter.xcframework */; }; - 614ED37C2603533D00C8C519 /* CrashReporter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 614ED36B260352DC00C8C519 /* CrashReporter.xcframework */; }; - 614ED39A260357FA00C8C519 /* DatadogCrashReporting.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61B7885425C180CB002675B5 /* DatadogCrashReporting.framework */; }; - 614ED39B260357FA00C8C519 /* DatadogCrashReporting.framework in ⚙️ Embed Framework Dependencies */ = {isa = PBXBuildFile; fileRef = 61B7885425C180CB002675B5 /* DatadogCrashReporting.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 6152C83E24BE1C91006A1679 /* HTTPServerMock in Frameworks */ = {isa = PBXBuildFile; productRef = 6152C83D24BE1C91006A1679 /* HTTPServerMock */; }; 6152C84024BE1CC8006A1679 /* DataUploaderBenchmarkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6152C83F24BE1CC8006A1679 /* DataUploaderBenchmarkTests.swift */; }; 6156CB8E24DDA1B5008CB2B2 /* RUMContextProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6156CB8D24DDA1B5008CB2B2 /* RUMContextProvider.swift */; }; @@ -223,7 +218,6 @@ 6156CB9824DEFD44008CB2B2 /* LoggingWithRUMIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6156CB9724DEFD44008CB2B2 /* LoggingWithRUMIntegration.swift */; }; 6156CB9D24E18600008CB2B2 /* TracingWithRUMIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6156CB9B24E18224008CB2B2 /* TracingWithRUMIntegration.swift */; }; 61570005246AADFA00E96950 /* DatadogObjc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61133BF0242397DA00786299 /* DatadogObjc.framework */; }; - 61570006246AAE5E00E96950 /* DatadogObjc.framework in ⚙️ Embed Framework Dependencies */ = {isa = PBXBuildFile; fileRef = 61133BF0242397DA00786299 /* DatadogObjc.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 61570007246AAED100E96950 /* DatadogObjc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61133BF0242397DA00786299 /* DatadogObjc.framework */; }; 6157FA5E252767CB009A8A3B /* URLSessionRUMResourcesHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6157FA5D252767CB009A8A3B /* URLSessionRUMResourcesHandler.swift */; }; 615A4A8324A3431600233986 /* Tracer+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615A4A8224A3431600233986 /* Tracer+objc.swift */; }; @@ -334,7 +328,6 @@ 61B03898252724DE00518F3C /* TracingHTTPHeaders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618E13B02524B8F80098C6B0 /* TracingHTTPHeaders.swift */; }; 61B038BA2527257B00518F3C /* URLSessionAutoInstrumentationMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B038B92527257B00518F3C /* URLSessionAutoInstrumentationMocks.swift */; }; 61B038C62527259300518F3C /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B038C52527259300518F3C /* XCTestCase.swift */; }; - 61B03ECE274FF01F00EB1AE1 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61B03ECC274FF00E00EB1AE1 /* SwiftUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 61B22E5A24F3E6B700DC26D2 /* RUMDebugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B22E5924F3E6B700DC26D2 /* RUMDebugging.swift */; }; 61B3BD52266128D300A9BEF0 /* LoggerE2ETests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B3BD51266128D300A9BEF0 /* LoggerE2ETests.swift */; }; 61B558CF2469561C001460D3 /* LoggerBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B558CE2469561C001460D3 /* LoggerBuilderTests.swift */; }; @@ -544,14 +537,450 @@ B3FC3C3C2653A97700DEED9E /* VitalInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3FC3C3B2653A97700DEED9E /* VitalInfoTests.swift */; }; D2135330270CA722000315AD /* DataCompressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213532F270CA722000315AD /* DataCompressionTests.swift */; }; D22C1F5C271484B400922024 /* LogEventMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22C1F5B271484B400922024 /* LogEventMapper.swift */; }; + D240680827CE6C9E00C04F44 /* ConsoleOutputInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61441C902461A648003D8BB8 /* ConsoleOutputInterceptor.swift */; }; + D240680E27CE6C9E00C04F44 /* UIViewController+KeyboardControlling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61441C922461A648003D8BB8 /* UIViewController+KeyboardControlling.swift */; }; + D240681627CE6C9E00C04F44 /* AppConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61441C9C2461A796003D8BB8 /* AppConfiguration.swift */; }; + D240681E27CE6C9E00C04F44 /* ExampleAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61441C0424616DE9003D8BB8 /* ExampleAppDelegate.swift */; }; + D240682527CE6C9E00C04F44 /* PersistenceHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6111544725C9A88B007C84C9 /* PersistenceHelper.swift */; }; + D240682B27CE6C9E00C04F44 /* UIButton+Disabling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61441C912461A648003D8BB8 /* UIButton+Disabling.swift */; }; + D240682D27CE6C9E00C04F44 /* Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614CADD62510BAC000B93D2D /* Environment.swift */; }; + D240683D27CE6C9E00C04F44 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 61441C0D24616DEC003D8BB8 /* Assets.xcassets */; }; + D240684F27CF5CA500C04F44 /* TestScenarios.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614CADCD250FCA0200B93D2D /* TestScenarios.swift */; }; + D240685527CF5D0100C04F44 /* Datadog.framework in ⚙️ Embed Framework Dependencies */ = {isa = PBXBuildFile; fileRef = D2CB6ED127C50EAE00A62B57 /* Datadog.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D240685927CF5D0100C04F44 /* DatadogCrashReporting.framework in ⚙️ Embed Framework Dependencies */ = {isa = PBXBuildFile; fileRef = D2CB6FD127C5348200A62B57 /* DatadogCrashReporting.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D240686027CF5D0100C04F44 /* DatadogObjc.framework in ⚙️ Embed Framework Dependencies */ = {isa = PBXBuildFile; fileRef = D2CB6FB027C5217A00A62B57 /* DatadogObjc.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D240686827CF642900C04F44 /* SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61776D4D273E6D9F00F93802 /* SwiftUI.swift */; }; + D240687027CF971C00C04F44 /* CrashReporter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 614ED36B260352DC00C8C519 /* CrashReporter.xcframework */; }; + D240687127CF971C00C04F44 /* Datadog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6ED127C50EAE00A62B57 /* Datadog.framework */; }; + D240687227CF971C00C04F44 /* DatadogCrashReporting.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6FD127C5348200A62B57 /* DatadogCrashReporting.framework */; }; + D240687327CF971C00C04F44 /* DatadogObjc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6FB027C5217A00A62B57 /* DatadogObjc.framework */; }; + D240687827CF982B00C04F44 /* CrashReporter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 614ED36B260352DC00C8C519 /* CrashReporter.xcframework */; }; + D240687B27CF982C00C04F44 /* Datadog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61133B82242393DE00786299 /* Datadog.framework */; }; + D240687C27CF982C00C04F44 /* Datadog.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 61133B82242393DE00786299 /* Datadog.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D240687D27CF982D00C04F44 /* DatadogCrashReporting.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61B7885425C180CB002675B5 /* DatadogCrashReporting.framework */; }; + D240687E27CF982D00C04F44 /* DatadogCrashReporting.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 61B7885425C180CB002675B5 /* DatadogCrashReporting.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D240687F27CF982F00C04F44 /* DatadogObjc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61133BF0242397DA00786299 /* DatadogObjc.framework */; }; + D240688027CF982F00C04F44 /* DatadogObjc.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 61133BF0242397DA00786299 /* DatadogObjc.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D240688627CFA64A00C04F44 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D240688427CFA64A00C04F44 /* LaunchScreen.storyboard */; }; D243BBC0276C9D640019C857 /* PLCrashReporterIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243BBBF276C9D640019C857 /* PLCrashReporterIntegrationTests.swift */; }; D244B3A3271EDACD003E1B29 /* SwiftUIExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D244B3A2271EDACD003E1B29 /* SwiftUIExtensionsTests.swift */; }; D24985A22728048B00B4F72D /* SwiftUIViewHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D24985A12728048B00B4F72D /* SwiftUIViewHandler.swift */; }; D24985A327280FD100B4F72D /* SwiftUIViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D249859F2728042200B4F72D /* SwiftUIViewModifier.swift */; }; D24C27EA270C8BEE005DE596 /* DataCompression.swift in Sources */ = {isa = PBXBuildFile; fileRef = D24C27E9270C8BEE005DE596 /* DataCompression.swift */; }; D2791EF927170A760046E07A /* RUMSwiftUIScenarioTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2791EF827170A760046E07A /* RUMSwiftUIScenarioTests.swift */; }; + D28D5D5527C54B30008E72D0 /* DatadogCrashReporting.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6FD127C5348200A62B57 /* DatadogCrashReporting.framework */; }; D29889C9273413ED00A4D1A9 /* RUMViewsHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29889C72734136200A4D1A9 /* RUMViewsHandlerTests.swift */; }; D29D5A4D273BF8B400A687C1 /* SwiftUIActionModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29D5A4C273BF8B400A687C1 /* SwiftUIActionModifier.swift */; }; + D2CB6E0C27C50EAE00A62B57 /* Datadog.h in Headers */ = {isa = PBXBuildFile; fileRef = 61133B85242393DE00786299 /* Datadog.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D2CB6E0D27C50EAE00A62B57 /* ObjcAppLaunchHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6179FFD1254ADB1100556A0B /* ObjcAppLaunchHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D2CB6E0E27C50EAE00A62B57 /* ObjcExceptionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E68FB54244707FD0013A8AA /* ObjcExceptionHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D2CB6E1027C50EAE00A62B57 /* CrashReportingWithRUMIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6112B10A25C849C000B37771 /* CrashReportingWithRUMIntegration.swift */; }; + D2CB6E1127C50EAE00A62B57 /* TracerConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E917D02465423600E6C631 /* TracerConfiguration.swift */; }; + D2CB6E1227C50EAE00A62B57 /* SwiftUIViewHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D24985A12728048B00B4F72D /* SwiftUIViewHandler.swift */; }; + D2CB6E1327C50EAE00A62B57 /* SwiftUIViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D249859F2728042200B4F72D /* SwiftUIViewModifier.swift */; }; + D2CB6E1427C50EAE00A62B57 /* SwiftUIExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FCA238271D896E0020286F /* SwiftUIExtensions.swift */; }; + D2CB6E1527C50EAE00A62B57 /* DateCorrector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C576C5256E65BD00295F7C /* DateCorrector.swift */; }; + D2CB6E1627C50EAE00A62B57 /* RUMWithCrashContextIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FC5F4425CC23C9006BB4DE /* RUMWithCrashContextIntegration.swift */; }; + D2CB6E1727C50EAE00A62B57 /* OTSpan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E909E624A24DD3005EA2DE /* OTSpan.swift */; }; + D2CB6E1827C50EAE00A62B57 /* RUMViewIdentity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FF9A4425AC5DEA001058CC /* RUMViewIdentity.swift */; }; + D2CB6E1927C50EAE00A62B57 /* CrashContextProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 616124A625CAC268009901BE /* CrashContextProvider.swift */; }; + D2CB6E1A27C50EAE00A62B57 /* OTSpanContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E909EC24A24DD3005EA2DE /* OTSpanContext.swift */; }; + D2CB6E1B27C50EAE00A62B57 /* OTTracer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E909E924A24DD3005EA2DE /* OTTracer.swift */; }; + D2CB6E1C27C50EAE00A62B57 /* OTReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E909EA24A24DD3005EA2DE /* OTReference.swift */; }; + D2CB6E1D27C50EAE00A62B57 /* ArbitraryDataWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6116563A25D2A6C90070EC03 /* ArbitraryDataWriter.swift */; }; + D2CB6E1E27C50EAE00A62B57 /* LoggingForTracingAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61216275247D1CD700AC5D67 /* LoggingForTracingAdapter.swift */; }; + D2CB6E1F27C50EAE00A62B57 /* WebRUMEventConsumer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB4B865274FAB4C0041CD03 /* WebRUMEventConsumer.swift */; }; + D2CB6E2027C50EAE00A62B57 /* Global.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E909E824A24DD3005EA2DE /* Global.swift */; }; + D2CB6E2127C50EAE00A62B57 /* RUMViewsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EFF3D22731822A00D09F33 /* RUMViewsHandler.swift */; }; + D2CB6E2227C50EAE00A62B57 /* InternalLoggers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BB82423979B00786299 /* InternalLoggers.swift */; }; + D2CB6E2327C50EAE00A62B57 /* LoggingWithActiveSpanIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6105D19F2508F1600040DD22 /* LoggingWithActiveSpanIntegration.swift */; }; + D2CB6E2427C50EAE00A62B57 /* WebLogEventConsumer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB4B863274FAB410041CD03 /* WebLogEventConsumer.swift */; }; + D2CB6E2527C50EAE00A62B57 /* MoveDataMigrator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61EF78B0257E2E7A00EDCCB3 /* MoveDataMigrator.swift */; }; + D2CB6E2627C50EAE00A62B57 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BB62423979B00786299 /* Logger.swift */; }; + D2CB6E2727C50EAE00A62B57 /* TrackingConsent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6114FE1525766B310084E372 /* TrackingConsent.swift */; }; + D2CB6E2827C50EAE00A62B57 /* DateProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BA82423979B00786299 /* DateProvider.swift */; }; + D2CB6E2927C50EAE00A62B57 /* KronosInternetAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D3E0C8277B23F0008BE766 /* KronosInternetAddress.swift */; }; + D2CB6E2A27C50EAE00A62B57 /* RUMContextProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6156CB8D24DDA1B5008CB2B2 /* RUMContextProvider.swift */; }; + D2CB6E2B27C50EAE00A62B57 /* RUMViewScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C2C21124C5951400C0321C /* RUMViewScope.swift */; }; + D2CB6E2C27C50EAE00A62B57 /* KronosNTPPacket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D3E0CB277B23F0008BE766 /* KronosNTPPacket.swift */; }; + D2CB6E2D27C50EAE00A62B57 /* CrashReportingFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61DE332525C826E4008E3EC2 /* CrashReportingFeature.swift */; }; + D2CB6E2E27C50EAE00A62B57 /* LaunchTimeProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E36A10254B2280001AD6F2 /* LaunchTimeProvider.swift */; }; + D2CB6E2F27C50EAE00A62B57 /* SpanTagsReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614872762485067300E3EBDB /* SpanTagsReducer.swift */; }; + D2CB6E3027C50EAE00A62B57 /* RUMApplicationScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3E63D24BF1B91008053F2 /* RUMApplicationScope.swift */; }; + D2CB6E3127C50EAE00A62B57 /* FileWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BA72423979B00786299 /* FileWriter.swift */; }; + D2CB6E3227C50EAE00A62B57 /* SwiftUIActionModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29D5A4C273BF8B400A687C1 /* SwiftUIActionModifier.swift */; }; + D2CB6E3327C50EAE00A62B57 /* OTConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E909EB24A24DD3005EA2DE /* OTConstants.swift */; }; + D2CB6E3427C50EAE00A62B57 /* MobileDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BA32423979B00786299 /* MobileDevice.swift */; }; + D2CB6E3527C50EAE00A62B57 /* SpanEventBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A8A524509FAA00DA608C /* SpanEventBuilder.swift */; }; + D2CB6E3627C50EAE00A62B57 /* ObjcAppLaunchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6179FFD2254ADB1100556A0B /* ObjcAppLaunchHandler.m */; }; + D2CB6E3727C50EAE00A62B57 /* UIKitRUMUserActionsPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F637AED12697404200516F32 /* UIKitRUMUserActionsPredicate.swift */; }; + D2CB6E3827C50EAE00A62B57 /* DataFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61AD4E3724531500006E34EA /* DataFormat.swift */; }; + D2CB6E3927C50EAE00A62B57 /* JSONEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E58E8E024615C75008E5063 /* JSONEncoder.swift */; }; + D2CB6E3A27C50EAE00A62B57 /* InternalMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F1878C25FA33A90022CE9A /* InternalMonitor.swift */; }; + D2CB6E3B27C50EAE00A62B57 /* CodableValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BA02423979B00786299 /* CodableValue.swift */; }; + D2CB6E3C27C50EAE00A62B57 /* Retrying.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6139CD702589FAFD007E8BB7 /* Retrying.swift */; }; + D2CB6E3D27C50EAE00A62B57 /* FeaturesConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61BBD19424ED4E9E0023E65F /* FeaturesConfiguration.swift */; }; + D2CB6E3E27C50EAE00A62B57 /* SpanEventMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618D9DE6263AD78900A3FAD2 /* SpanEventMapper.swift */; }; + D2CB6E3F27C50EAE00A62B57 /* ConsentProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6114FE2E257687300084E372 /* ConsentProvider.swift */; }; + D2CB6E4027C50EAE00A62B57 /* UIViewControllerSwizzler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F3CDA42511190E00C816E5 /* UIViewControllerSwizzler.swift */; }; + D2CB6E4127C50EAE00A62B57 /* RUMCurrentContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6156CB8F24DDA8BE008CB2B2 /* RUMCurrentContext.swift */; }; + D2CB6E4227C50EAE00A62B57 /* RUMConnectivityInfoProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614B0A4E24EBDC6B00A2A780 /* RUMConnectivityInfoProvider.swift */; }; + D2CB6E4327C50EAE00A62B57 /* ObjcExceptionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E68FB53244707FD0013A8AA /* ObjcExceptionHandler.m */; }; + D2CB6E4427C50EAE00A62B57 /* UIApplicationSwizzler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6141014E251A57AF00E3C2D9 /* UIApplicationSwizzler.swift */; }; + D2CB6E4527C50EAE00A62B57 /* RUMResourceScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61494CB024C839460082C633 /* RUMResourceScope.swift */; }; + D2CB6E4627C50EAE00A62B57 /* RUMSessionScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C2C20624C098FC00C0321C /* RUMSessionScope.swift */; }; + D2CB6E4727C50EAE00A62B57 /* TracingUUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 617CEB382456BC3A00AD4669 /* TracingUUID.swift */; }; + D2CB6E4827C50EAE00A62B57 /* ServerDateProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61BCB81E256EB77F0039887B /* ServerDateProvider.swift */; }; + D2CB6E4927C50EAE00A62B57 /* AttributesSanitizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61122ED925B1BA9700F9C7F5 /* AttributesSanitizer.swift */; }; + D2CB6E4A27C50EAE00A62B57 /* RUMEventOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FF282524B8A248000B3D9B /* RUMEventOutput.swift */; }; + D2CB6E4B27C50EAE00A62B57 /* InternalMonitoringFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F1878325FA121F0022CE9A /* InternalMonitoringFeature.swift */; }; + D2CB6E4C27C50EAE00A62B57 /* RUMDataModelsMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618715F824DC13A100FC0F69 /* RUMDataModelsMapping.swift */; }; + D2CB6E4D27C50EAE00A62B57 /* Globals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3638424361E9200C4D4E6 /* Globals.swift */; }; + D2CB6E4E27C50EAE00A62B57 /* ActiveSpansPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D202E924C065CF00D1AF3A /* ActiveSpansPool.swift */; }; + D2CB6E4F27C50EAE00A62B57 /* AppStateListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ED6A6B325F2901800CB2E29 /* AppStateListener.swift */; }; + D2CB6E5027C50EAE00A62B57 /* UIViewControllerHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F3CDA2251118FB00C816E5 /* UIViewControllerHandler.swift */; }; + D2CB6E5127C50EAE00A62B57 /* Warnings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A87D24509A0C00DA608C /* Warnings.swift */; }; + D2CB6E5227C50EAE00A62B57 /* DataMigrator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 619E16E82578E73E00B2516B /* DataMigrator.swift */; }; + D2CB6E5327C50EAE00A62B57 /* RUMUUIDGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618DCFD824C7269500589570 /* RUMUUIDGenerator.swift */; }; + D2CB6E5427C50EAE00A62B57 /* FirstPartyURLsFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EFD112B24B32D29003A1A2B /* FirstPartyURLsFilter.swift */; }; + D2CB6E5527C50EAE00A62B57 /* KronosNSTimer+ClosureKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D3E0D1277B23F1008BE766 /* KronosNSTimer+ClosureKit.swift */; }; + D2CB6E5627C50EAE00A62B57 /* TaskInterception.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61417DC52525CDDE00E2D55C /* TaskInterception.swift */; }; + D2CB6E5727C50EAE00A62B57 /* HTTPHeadersReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618E13A92524B8700098C6B0 /* HTTPHeadersReader.swift */; }; + D2CB6E5827C50EAE00A62B57 /* SpanSanitizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61122ECD25B1B74500F9C7F5 /* SpanSanitizer.swift */; }; + D2CB6E5927C50EAE00A62B57 /* Writer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613E79272577B0EE00DFCC17 /* Writer.swift */; }; + D2CB6E5A27C50EAE00A62B57 /* URLSessionAutoInstrumentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618E136C252384D90098C6B0 /* URLSessionAutoInstrumentation.swift */; }; + D2CB6E5B27C50EAE00A62B57 /* DDSpanContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A87E24509A0C00DA608C /* DDSpanContext.swift */; }; + D2CB6E5C27C50EAE00A62B57 /* UIKitRUMUserActionsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6141015A251A601D00E3C2D9 /* UIKitRUMUserActionsHandler.swift */; }; + D2CB6E5D27C50EAE00A62B57 /* RUMInstrumentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 616CCE15250A467E009FED46 /* RUMInstrumentation.swift */; }; + D2CB6E5E27C50EAE00A62B57 /* URLSessionRUMResourcesHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6157FA5D252767CB009A8A3B /* URLSessionRUMResourcesHandler.swift */; }; + D2CB6E5F27C50EAE00A62B57 /* RUMCommandSubscriber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 616CCE12250A1868009FED46 /* RUMCommandSubscriber.swift */; }; + D2CB6E6027C50EAE00A62B57 /* CrashReportingIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6112B11325C84E7900B37771 /* CrashReportingIntegration.swift */; }; + D2CB6E6127C50EAE00A62B57 /* CrashReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6161247825CA9CA6009901BE /* CrashReporter.swift */; }; + D2CB6E6227C50EAE00A62B57 /* LogEventSanitizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BC42423979B00786299 /* LogEventSanitizer.swift */; }; + D2CB6E6327C50EAE00A62B57 /* UIKitExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615F197B25B5A64B00BE14B5 /* UIKitExtensions.swift */; }; + D2CB6E6427C50EAE00A62B57 /* VitalCPUReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC8B5D92668197B000F7529 /* VitalCPUReader.swift */; }; + D2CB6E6527C50EAE00A62B57 /* Feature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614D812B24E3EA15004C9C5D /* Feature.swift */; }; + D2CB6E6627C50EAE00A62B57 /* Reader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613E792E2577B0F900DFCC17 /* Reader.swift */; }; + D2CB6E6727C50EAE00A62B57 /* DDURLSessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618E1365252383D80098C6B0 /* DDURLSessionDelegate.swift */; }; + D2CB6E6827C50EAE00A62B57 /* SwiftExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BBA2423979B00786299 /* SwiftExtensions.swift */; }; + D2CB6E6927C50EAE00A62B57 /* KronosDNSResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D3E0C9277B23F0008BE766 /* KronosDNSResolver.swift */; }; + D2CB6E6A27C50EAE00A62B57 /* InternalURLsFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6149FB392529D17F00EE387A /* InternalURLsFilter.swift */; }; + D2CB6E6B27C50EAE00A62B57 /* ValuePublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 611529A425E3DD51004F740E /* ValuePublisher.swift */; }; + D2CB6E6C27C50EAE00A62B57 /* KronosMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FFFB88278457D300401A28 /* KronosMonitor.swift */; }; + D2CB6E6D27C50EAE00A62B57 /* RUMUUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618DCFD624C7265300589570 /* RUMUUID.swift */; }; + D2CB6E6E27C50EAE00A62B57 /* URLSessionInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618E1337252340810098C6B0 /* URLSessionInterceptor.swift */; }; + D2CB6E6F27C50EAE00A62B57 /* TracingHTTPHeaders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618E13B02524B8F80098C6B0 /* TracingHTTPHeaders.swift */; }; + D2CB6E7027C50EAE00A62B57 /* MethodSwizzler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E544A4E24753C6E00E83072 /* MethodSwizzler.swift */; }; + D2CB6E7127C50EAE00A62B57 /* LogConsoleOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BC92423979B00786299 /* LogConsoleOutput.swift */; }; + D2CB6E7227C50EAE00A62B57 /* SpanEventEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A8A424509FAA00DA608C /* SpanEventEncoder.swift */; }; + D2CB6E7327C50EAE00A62B57 /* Tracer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A88D24509A1F00DA608C /* Tracer.swift */; }; + D2CB6E7427C50EAE00A62B57 /* OTFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E909E724A24DD3005EA2DE /* OTFormat.swift */; }; + D2CB6E7527C50EAE00A62B57 /* RUMDataModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E26E6B824C87693000B3270 /* RUMDataModels.swift */; }; + D2CB6E7627C50EAE00A62B57 /* KronosClock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D3E0CC277B23F0008BE766 /* KronosClock.swift */; }; + D2CB6E7727C50EAE00A62B57 /* DataReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613E793A2577B6EE00DFCC17 /* DataReader.swift */; }; + D2CB6E7827C50EAE00A62B57 /* DDRUMMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614B0A5224EBFE5500A2A780 /* DDRUMMonitor.swift */; }; + D2CB6E7927C50EAE00A62B57 /* UserInfoProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BC02423979B00786299 /* UserInfoProvider.swift */; }; + D2CB6E7A27C50EAE00A62B57 /* WebEventBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB4B867275103E40041CD03 /* WebEventBridge.swift */; }; + D2CB6E7B27C50EAE00A62B57 /* Datadog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BBB2423979B00786299 /* Datadog.swift */; }; + D2CB6E7C27C50EAE00A62B57 /* CarrierInfoProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BA22423979B00786299 /* CarrierInfoProvider.swift */; }; + D2CB6E7D27C50EAE00A62B57 /* TracingFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A88F24509AA700DA608C /* TracingFeature.swift */; }; + D2CB6E7E27C50EAE00A62B57 /* RUMMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E5333524B84B43003D6C4E /* RUMMonitor.swift */; }; + D2CB6E7F27C50EAE00A62B57 /* LoggingWithRUMIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6156CB9724DEFD44008CB2B2 /* LoggingWithRUMIntegration.swift */; }; + D2CB6E8027C50EAE00A62B57 /* WKUserContentController+Datadog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB4B861274E79D50041CD03 /* WKUserContentController+Datadog.swift */; }; + D2CB6E8127C50EAE00A62B57 /* DataUploader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BB02423979B00786299 /* DataUploader.swift */; }; + D2CB6E8227C50EAE00A62B57 /* DeleteAllDataMigrator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 619E16F02578E89700B2516B /* DeleteAllDataMigrator.swift */; }; + D2CB6E8327C50EAE00A62B57 /* RUMUserActionScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61494CB924CB126F0082C633 /* RUMUserActionScope.swift */; }; + D2CB6E8427C50EAE00A62B57 /* DDNoopRUMMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F1B81026D795F3009F3293 /* DDNoopRUMMonitor.swift */; }; + D2CB6E8527C50EAE00A62B57 /* Casting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A87C24509A0C00DA608C /* Casting.swift */; }; + D2CB6E8627C50EAE00A62B57 /* RUMScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3E63624BF191F008053F2 /* RUMScope.swift */; }; + D2CB6E8727C50EAE00A62B57 /* LogEventBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BC32423979B00786299 /* LogEventBuilder.swift */; }; + D2CB6E8827C50EAE00A62B57 /* FileReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BAD2423979B00786299 /* FileReader.swift */; }; + D2CB6E8927C50EAE00A62B57 /* LongTaskObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E359F4D26CD518D001E25E9 /* LongTaskObserver.swift */; }; + D2CB6E8A27C50EAE00A62B57 /* SpanFileOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A88024509A0C00DA608C /* SpanFileOutput.swift */; }; + D2CB6E8B27C50EAE00A62B57 /* Attributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3E63424BF1794008053F2 /* Attributes.swift */; }; + D2CB6E8C27C50EAE00A62B57 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BAC2423979B00786299 /* File.swift */; }; + D2CB6E8D27C50EAE00A62B57 /* KronosNTPProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D3E0CF277B23F0008BE766 /* KronosNTPProtocol.swift */; }; + D2CB6E8E27C50EAE00A62B57 /* DDCrashReportingPluginType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61DE333525C8278A008E3EC2 /* DDCrashReportingPluginType.swift */; }; + D2CB6E8F27C50EAE00A62B57 /* CrashReportingWithLoggingIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6112B10125C83D4E00B37771 /* CrashReportingWithLoggingIntegration.swift */; }; + D2CB6E9027C50EAE00A62B57 /* CrashContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6161249D25CAB340009901BE /* CrashContext.swift */; }; + D2CB6E9127C50EAE00A62B57 /* KronosTimeFreeze.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D3E0D0277B23F1008BE766 /* KronosTimeFreeze.swift */; }; + D2CB6E9227C50EAE00A62B57 /* DateFormatting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D447E124917F8F00649287 /* DateFormatting.swift */; }; + D2CB6E9327C50EAE00A62B57 /* LogUtilityOutputs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BC62423979B00786299 /* LogUtilityOutputs.swift */; }; + D2CB6E9427C50EAE00A62B57 /* RequestBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BB42423979B00786299 /* RequestBuilder.swift */; }; + D2CB6E9527C50EAE00A62B57 /* RUMContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3E63824BF19B4008053F2 /* RUMContext.swift */; }; + D2CB6E9627C50EAE00A62B57 /* RUMOffViewEventsHandlingRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A614E7276B2BD000A06CE7 /* RUMOffViewEventsHandlingRule.swift */; }; + D2CB6E9727C50EAE00A62B57 /* DataUploadStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61ED39D326C2A36B002C0F26 /* DataUploadStatus.swift */; }; + D2CB6E9827C50EAE00A62B57 /* LogFileOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BC72423979B00786299 /* LogFileOutput.swift */; }; + D2CB6E9927C50EAE00A62B57 /* DataUploadWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BB12423979B00786299 /* DataUploadWorker.swift */; }; + D2CB6E9A27C50EAE00A62B57 /* KronosTimeStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D3E0CA277B23F0008BE766 /* KronosTimeStorage.swift */; }; + D2CB6E9B27C50EAE00A62B57 /* FilesOrchestrator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BA92423979B00786299 /* FilesOrchestrator.swift */; }; + D2CB6E9C27C50EAE00A62B57 /* NetworkConnectionInfoProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BA42423979B00786299 /* NetworkConnectionInfoProvider.swift */; }; + D2CB6E9D27C50EAE00A62B57 /* RUMEventFileOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FF282324B8A1C3000B3D9B /* RUMEventFileOutput.swift */; }; + D2CB6E9E27C50EAE00A62B57 /* RUMDebugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B22E5924F3E6B700DC26D2 /* RUMDebugging.swift */; }; + D2CB6E9F27C50EAE00A62B57 /* DataCompression.swift in Sources */ = {isa = PBXBuildFile; fileRef = D24C27E9270C8BEE005DE596 /* DataCompression.swift */; }; + D2CB6EA027C50EAE00A62B57 /* SpanOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A88124509A0C00DA608C /* SpanOutput.swift */; }; + D2CB6EA127C50EAE00A62B57 /* LogEventEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BC22423979B00786299 /* LogEventEncoder.swift */; }; + D2CB6EA227C50EAE00A62B57 /* VitalInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3FC3C0626526EFF00DEED9E /* VitalInfo.swift */; }; + D2CB6EA327C50EAE00A62B57 /* RUMEventsMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613E81EF25A740140084B751 /* RUMEventsMapper.swift */; }; + D2CB6EA427C50EAE00A62B57 /* RUMIntegrations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D980B924E28D0100E03345 /* RUMIntegrations.swift */; }; + D2CB6EA527C50EAE00A62B57 /* DDSpan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A87824509A0C00DA608C /* DDSpan.swift */; }; + D2CB6EA627C50EAE00A62B57 /* RUMEventBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FF281D24B8968D000B3D9B /* RUMEventBuilder.swift */; }; + D2CB6EA727C50EAE00A62B57 /* Versioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D5AEA624B4D45A007F194B /* Versioning.swift */; }; + D2CB6EA827C50EAE00A62B57 /* HTTPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BB22423979B00786299 /* HTTPClient.swift */; }; + D2CB6EA927C50EAE00A62B57 /* LogEventMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22C1F5B271484B400922024 /* LogEventMapper.swift */; }; + D2CB6EAA27C50EAE00A62B57 /* URLSessionSwizzler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618E132B25233EC90098C6B0 /* URLSessionSwizzler.swift */; }; + D2CB6EAB27C50EAE00A62B57 /* VitalMemoryReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3BBBCB0265E71C600943419 /* VitalMemoryReader.swift */; }; + D2CB6EAC27C50EAE00A62B57 /* DatadogConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BB52423979B00786299 /* DatadogConfiguration.swift */; }; + D2CB6EAD27C50EAE00A62B57 /* DataProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 619E16D72577C1CB00B2516B /* DataProcessor.swift */; }; + D2CB6EAE27C50EAE00A62B57 /* DataOrchestrator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6137C571271DAD4B00EFC4A1 /* DataOrchestrator.swift */; }; + D2CB6EAF27C50EAE00A62B57 /* BundleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614E9EB2244719FA007EE3E1 /* BundleType.swift */; }; + D2CB6EB027C50EAE00A62B57 /* UIKitRUMViewsPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F3CDA62512144600C816E5 /* UIKitRUMViewsPredicate.swift */; }; + D2CB6EB127C50EAE00A62B57 /* BatteryStatusProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BA52423979B00786299 /* BatteryStatusProvider.swift */; }; + D2CB6EB227C50EAE00A62B57 /* Sampler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613C6B8F2768FDDE00870CBF /* Sampler.swift */; }; + D2CB6EB327C50EAE00A62B57 /* KronosNTPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D3E0CE277B23F0008BE766 /* KronosNTPClient.swift */; }; + D2CB6EB427C50EAE00A62B57 /* VitalInfoSampler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9973F0268DF69500D8059B /* VitalInfoSampler.swift */; }; + D2CB6EB527C50EAE00A62B57 /* VitalRefreshRateReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA3CA6826775A3500B16871 /* VitalRefreshRateReader.swift */; }; + D2CB6EB627C50EAE00A62B57 /* (null) in Sources */ = {isa = PBXBuildFile; }; + D2CB6EB727C50EAE00A62B57 /* URLSessionTracingHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B03810252656F500518F3C /* URLSessionTracingHandler.swift */; }; + D2CB6EB827C50EAE00A62B57 /* RUMEventSanitizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61122ED325B1B84D00F9C7F5 /* RUMEventSanitizer.swift */; }; + D2CB6EB927C50EAE00A62B57 /* DDError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61363D9C24D999F70084CD6F /* DDError.swift */; }; + D2CB6EBA27C50EAE00A62B57 /* DataUploadConditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BAF2423979B00786299 /* DataUploadConditions.swift */; }; + D2CB6EBB27C50EAE00A62B57 /* LoggingFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 612983CC2449E62E00D4424B /* LoggingFeature.swift */; }; + D2CB6EBC27C50EAE00A62B57 /* RUMCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3E63A24BF1A4B008053F2 /* RUMCommand.swift */; }; + D2CB6EBD27C50EAE00A62B57 /* LogOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BC82423979B00786299 /* LogOutput.swift */; }; + D2CB6EBE27C50EAE00A62B57 /* DDNoOps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A87924509A0C00DA608C /* DDNoOps.swift */; }; + D2CB6EBF27C50EAE00A62B57 /* KronosData+Bytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D3E0CD277B23F0008BE766 /* KronosData+Bytes.swift */; }; + D2CB6EC027C50EAE00A62B57 /* RUMFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E5332B24B75C51003D6C4E /* RUMFeature.swift */; }; + D2CB6EC127C50EAE00A62B57 /* TracingWithRUMIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6156CB9B24E18224008CB2B2 /* TracingWithRUMIntegration.swift */; }; + D2CB6EC227C50EAE00A62B57 /* ConsentAwareDataWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6114FE0E257667D40084E372 /* ConsentAwareDataWriter.swift */; }; + D2CB6EC327C50EAE00A62B57 /* TracingUUIDGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A87B24509A0C00DA608C /* TracingUUIDGenerator.swift */; }; + D2CB6EC427C50EAE00A62B57 /* DataUploadDelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BB32423979B00786299 /* DataUploadDelay.swift */; }; + D2CB6EC527C50EAE00A62B57 /* HostsSanitizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAF0CF7275A2FDC0044E8CA /* HostsSanitizer.swift */; }; + D2CB6EC627C50EAE00A62B57 /* HTTPHeadersWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A88324509A0C00DA608C /* HTTPHeadersWriter.swift */; }; + D2CB6EC727C50EAE00A62B57 /* PerformancePreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61BB2B1A244A185D009F3F56 /* PerformancePreset.swift */; }; + D2CB6EC827C50EAE00A62B57 /* RUMUserInfoProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614B0A4A24EBC43D00A2A780 /* RUMUserInfoProvider.swift */; }; + D2CB6EC927C50EAE00A62B57 /* Directory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BAB2423979B00786299 /* Directory.swift */; }; + D2CB6ED727C520D400A62B57 /* URLSessionSwizzlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B03878252724AB00518F3C /* URLSessionSwizzlerTests.swift */; }; + D2CB6ED827C520D400A62B57 /* RUMUserActionScopeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 617CD0DC24CEDDD300B0B557 /* RUMUserActionScopeTests.swift */; }; + D2CB6ED927C520D400A62B57 /* RUMViewsHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29889C72734136200A4D1A9 /* RUMViewsHandlerTests.swift */; }; + D2CB6EDA27C520D400A62B57 /* Casting+Tracing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A89C24509C1100DA608C /* Casting+Tracing.swift */; }; + D2CB6EDB27C520D400A62B57 /* LogSanitizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C3C2423990D00786299 /* LogSanitizerTests.swift */; }; + D2CB6EDC27C520D400A62B57 /* ConsentAwareDataWriterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6114FE22257671F00084E372 /* ConsentAwareDataWriterTests.swift */; }; + D2CB6EDD27C520D400A62B57 /* UIApplicationSwizzlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61410166251A661D00E3C2D9 /* UIApplicationSwizzlerTests.swift */; }; + D2CB6EDE27C520D400A62B57 /* RUMEventMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FF282724B8A31E000B3D9B /* RUMEventMatcher.swift */; }; + D2CB6EDF27C520D400A62B57 /* RUMSessionScopeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C2C20824C0C75500C0321C /* RUMSessionScopeTests.swift */; }; + D2CB6EE027C520D400A62B57 /* SpanMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E45ED02451A8730061DAC7 /* SpanMatcher.swift */; }; + D2CB6EE127C520D400A62B57 /* RUMWithCrashContextIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FC5F4D25CC2920006BB4DE /* RUMWithCrashContextIntegrationTests.swift */; }; + D2CB6EE227C520D400A62B57 /* ServerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3646F243B5C8300C4D4E6 /* ServerMock.swift */; }; + D2CB6EE327C520D400A62B57 /* RUMViewScopeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6198D27024C6E3B700493501 /* RUMViewScopeTests.swift */; }; + D2CB6EE427C520D400A62B57 /* FeatureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61EF78C0257F842000EDCCB3 /* FeatureTests.swift */; }; + D2CB6EE527C520D400A62B57 /* DataUploadConditionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C302423990D00786299 /* DataUploadConditionsTests.swift */; }; + D2CB6EE627C520D400A62B57 /* DateFormattingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618C365E248E85B400520CDE /* DateFormattingTests.swift */; }; + D2CB6EE727C520D400A62B57 /* FileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C2C2423990D00786299 /* FileTests.swift */; }; + D2CB6EE827C520D400A62B57 /* TracingFeatureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61AD4E3924534075006E34EA /* TracingFeatureTests.swift */; }; + D2CB6EE927C520D400A62B57 /* SamplerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613C6B912768FF3100870CBF /* SamplerTests.swift */; }; + D2CB6EEA27C520D400A62B57 /* LogMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C432423990D00786299 /* LogMatcher.swift */; }; + D2CB6EEB27C520D400A62B57 /* DataCompressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213532F270CA722000315AD /* DataCompressionTests.swift */; }; + D2CB6EEC27C520D400A62B57 /* CustomObjcViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 61DB33B125DEDFC200F7EA71 /* CustomObjcViewController.m */; }; + D2CB6EED27C520D400A62B57 /* RUMIntegrationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D980BB24E293F600E03345 /* RUMIntegrationsTests.swift */; }; + D2CB6EEE27C520D400A62B57 /* DDErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61363D9E24D99BAA0084CD6F /* DDErrorTests.swift */; }; + D2CB6EEF27C520D400A62B57 /* Casting+RUM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61411B0F24EC15AC0012EAB2 /* Casting+RUM.swift */; }; + D2CB6EF027C520D400A62B57 /* InternalLoggersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C362423990D00786299 /* InternalLoggersTests.swift */; }; + D2CB6EF127C520D400A62B57 /* RUMEventFileOutputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FF282F24BC5E2D000B3D9B /* RUMEventFileOutputTests.swift */; }; + D2CB6EF227C520D400A62B57 /* KronosTimeStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D3E0E2277B3D92008BE766 /* KronosTimeStorageTests.swift */; }; + D2CB6EF327C520D400A62B57 /* VitalRefreshRateReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E986C2F2677B91400D62490 /* VitalRefreshRateReaderTests.swift */; }; + D2CB6EF427C520D400A62B57 /* FileWriterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C292423990D00786299 /* FileWriterTests.swift */; }; + D2CB6EF527C520D400A62B57 /* TracerConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E917D2246546BF00E6C631 /* TracerConfigurationTests.swift */; }; + D2CB6EF627C520D400A62B57 /* DDSpanTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A89824509C1100DA608C /* DDSpanTests.swift */; }; + D2CB6EF727C520D400A62B57 /* URLSessionAutoInstrumentationMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B038B92527257B00518F3C /* URLSessionAutoInstrumentationMocks.swift */; }; + D2CB6EF827C520D400A62B57 /* LogConsoleOutputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C3E2423990D00786299 /* LogConsoleOutputTests.swift */; }; + D2CB6EF927C520D400A62B57 /* WebRUMEventConsumerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E53889B2773C4B300A7DC42 /* WebRUMEventConsumerTests.swift */; }; + D2CB6EFA27C520D400A62B57 /* FeatureDirectoriesMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6114FDEB257659E90084E372 /* FeatureDirectoriesMock.swift */; }; + D2CB6EFB27C520D400A62B57 /* SpanSanitizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61122EE725B1C92500F9C7F5 /* SpanSanitizerTests.swift */; }; + D2CB6EFC27C520D400A62B57 /* DDGlobal+apiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 61B5E42426DFAFBC000B0A5F /* DDGlobal+apiTests.m */; }; + D2CB6EFD27C520D400A62B57 /* LoggingFeatureMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FB222C244A21ED00902D19 /* LoggingFeatureMocks.swift */; }; + D2CB6EFE27C520D400A62B57 /* RUMMonitorConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 617B954124BF4E7600E6F443 /* RUMMonitorConfigurationTests.swift */; }; + D2CB6EFF27C520D400A62B57 /* AttributesMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614BF37D2670AE9D002379C8 /* AttributesMocks.swift */; }; + D2CB6F0027C520D400A62B57 /* RUMSessionMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F9CA982513977A000A5E61 /* RUMSessionMatcher.swift */; }; + D2CB6F0127C520D400A62B57 /* DatadogPrivateMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3638224361BE200C4D4E6 /* DatadogPrivateMocks.swift */; }; + D2CB6F0227C520D400A62B57 /* TracingFeatureMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61AD4E172451C7FF006E34EA /* TracingFeatureMocks.swift */; }; + D2CB6F0327C520D400A62B57 /* WKUserContentController+DatadogTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAF0CF5275A21100044E8CA /* WKUserContentController+DatadogTests.swift */; }; + D2CB6F0427C520D400A62B57 /* DDTracerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615A4A8824A34FD700233986 /* DDTracerTests.swift */; }; + D2CB6F0527C520D400A62B57 /* DDTracerConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615A4A8624A3452800233986 /* DDTracerConfigurationTests.swift */; }; + D2CB6F0627C520D400A62B57 /* RUMEventsMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613E81F625A743600084B751 /* RUMEventsMapperTests.swift */; }; + D2CB6F0727C520D400A62B57 /* MoveDataMigratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61EF78B6257E37D500EDCCB3 /* MoveDataMigratorTests.swift */; }; + D2CB6F0827C520D400A62B57 /* DDSpanContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F1A620249A45E400075390 /* DDSpanContextTests.swift */; }; + D2CB6F0927C520D400A62B57 /* RUMDataModels+objcTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D03BDF273404E700367DE0 /* RUMDataModels+objcTests.swift */; }; + D2CB6F0A27C520D400A62B57 /* UIKitRUMUserActionsHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615C3195251DD5080018781C /* UIKitRUMUserActionsHandlerTests.swift */; }; + D2CB6F0B27C520D400A62B57 /* CodableValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E917CE2464270500E6C631 /* CodableValueTests.swift */; }; + D2CB6F0C27C520D400A62B57 /* KronosNTPPacketTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D3E0DF277B3D92008BE766 /* KronosNTPPacketTests.swift */; }; + D2CB6F0D27C520D400A62B57 /* NetworkConnectionInfoProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C242423990D00786299 /* NetworkConnectionInfoProviderTests.swift */; }; + D2CB6F0E27C520D400A62B57 /* DDRUMMonitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 616B668D259CC28E00968EE8 /* DDRUMMonitorTests.swift */; }; + D2CB6F0F27C520D400A62B57 /* VitalMemoryReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3BBBCBB265E71D100943419 /* VitalMemoryReaderTests.swift */; }; + D2CB6F1027C520D400A62B57 /* DDNSURLSessionDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EE5AD8126205B82001E699E /* DDNSURLSessionDelegateTests.swift */; }; + D2CB6F1127C520D400A62B57 /* CrashReportingWithRUMIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6182374225D3DFD5006A375B /* CrashReportingWithRUMIntegrationTests.swift */; }; + D2CB6F1227C520D400A62B57 /* LoggerBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B558CE2469561C001460D3 /* LoggerBuilderTests.swift */; }; + D2CB6F1327C520D400A62B57 /* DDConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C162423990D00786299 /* DDConfigurationTests.swift */; }; + D2CB6F1427C520D400A62B57 /* UUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A89B24509C1100DA608C /* UUID.swift */; }; + D2CB6F1527C520D400A62B57 /* URLSessionRUMResourcesHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613F23F0252B129E006CD2D7 /* URLSessionRUMResourcesHandlerTests.swift */; }; + D2CB6F1627C520D400A62B57 /* URLSessionInterceptorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B03874252724AB00518F3C /* URLSessionInterceptorTests.swift */; }; + D2CB6F1727C520D400A62B57 /* ObjcExceptionHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3637F2436164B00C4D4E6 /* ObjcExceptionHandlerTests.swift */; }; + D2CB6F1827C520D400A62B57 /* DatadogTestsObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6184751426EFCF1300C7C9C5 /* DatadogTestsObserver.swift */; }; + D2CB6F1927C520D400A62B57 /* RequestBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C332423990D00786299 /* RequestBuilderTests.swift */; }; + D2CB6F1A27C520D400A62B57 /* FileReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C282423990D00786299 /* FileReaderTests.swift */; }; + D2CB6F1B27C520D400A62B57 /* RUMOffViewEventsHandlingRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A614E9276B9D4C00A06CE7 /* RUMOffViewEventsHandlingRuleTests.swift */; }; + D2CB6F1C27C520D400A62B57 /* DDNoopRUMMonitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F1B81226D8DA68009F3293 /* DDNoopRUMMonitorTests.swift */; }; + D2CB6F1D27C520D400A62B57 /* DataUploaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C322423990D00786299 /* DataUploaderTests.swift */; }; + D2CB6F1E27C520D400A62B57 /* DataUploadWorkerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61D6FF7824E42A2900D0E375 /* DataUploadWorkerMock.swift */; }; + D2CB6F1F27C520D400A62B57 /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B038C52527259300518F3C /* XCTestCase.swift */; }; + D2CB6F2027C520D400A62B57 /* FeaturesConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61BBD19624ED50040023E65F /* FeaturesConfigurationTests.swift */; }; + D2CB6F2127C520D400A62B57 /* HTTPClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C342423990D00786299 /* HTTPClientTests.swift */; }; + D2CB6F2227C520D400A62B57 /* DatadogTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C412423990D00786299 /* DatadogTests.swift */; }; + D2CB6F2327C520D400A62B57 /* WebEventBridgeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB4B86B27510AF90041CD03 /* WebEventBridgeTests.swift */; }; + D2CB6F2427C520D400A62B57 /* DDURLSessionDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B03877252724AB00518F3C /* DDURLSessionDelegateTests.swift */; }; + D2CB6F2527C520D400A62B57 /* EquatableInTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61AADBDC263C7ECF008ABC6F /* EquatableInTests.swift */; }; + D2CB6F2627C520D400A62B57 /* DataUploadDelayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C312423990D00786299 /* DataUploadDelayTests.swift */; }; + D2CB6F2727C520D400A62B57 /* FirstPartyURLsFilterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B03875252724AB00518F3C /* FirstPartyURLsFilterTests.swift */; }; + D2CB6F2827C520D400A62B57 /* DataUploadWorkerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C2F2423990D00786299 /* DataUploadWorkerTests.swift */; }; + D2CB6F2927C520D400A62B57 /* DDGlobalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 616B6683259CAE3300968EE8 /* DDGlobalTests.swift */; }; + D2CB6F2A27C520D400A62B57 /* GlobalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E909F524A32D1C005EA2DE /* GlobalTests.swift */; }; + D2CB6F2B27C520D400A62B57 /* CrashContextProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FC5F3425CC1898006BB4DE /* CrashContextProviderTests.swift */; }; + D2CB6F2C27C520D400A62B57 /* JSONEncoderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E58E8E224615EDA008E5063 /* JSONEncoderTests.swift */; }; + D2CB6F2D27C520D400A62B57 /* LogFileOutputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C402423990D00786299 /* LogFileOutputTests.swift */; }; + D2CB6F2E27C520D400A62B57 /* RUMCommandTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618715F624DC0CDE00FC0F69 /* RUMCommandTests.swift */; }; + D2CB6F2F27C520D400A62B57 /* LogUtilityOutputsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C3F2423990D00786299 /* LogUtilityOutputsTests.swift */; }; + D2CB6F3027C520D400A62B57 /* DatadogExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C472423990D00786299 /* DatadogExtensions.swift */; }; + D2CB6F3127C520D400A62B57 /* InternalMonitoringFeatureMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F1879C25FA774C0022CE9A /* InternalMonitoringFeatureMocks.swift */; }; + D2CB6F3227C520D400A62B57 /* JSONDataMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E45BE624519A3700F2C652 /* JSONDataMatcher.swift */; }; + D2CB6F3327C520D400A62B57 /* FilesOrchestratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C2A2423990D00786299 /* FilesOrchestratorTests.swift */; }; + D2CB6F3427C520D400A62B57 /* TracingUUIDGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B558D32469CDD8001460D3 /* TracingUUIDGeneratorTests.swift */; }; + D2CB6F3527C520D400A62B57 /* MethodSwizzlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E544A5024753DDE00E83072 /* MethodSwizzlerTests.swift */; }; + D2CB6F3627C520D400A62B57 /* TaskInterceptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613F23E3252B062F006CD2D7 /* TaskInterceptionTests.swift */; }; + D2CB6F3727C520D400A62B57 /* LoggingFeatureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FB222F244E1BE900902D19 /* LoggingFeatureTests.swift */; }; + D2CB6F3827C520D400A62B57 /* RUMFeatureMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E5333024B75DFC003D6C4E /* RUMFeatureMocks.swift */; }; + D2CB6F3927C520D400A62B57 /* TestsDirectory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C462423990D00786299 /* TestsDirectory.swift */; }; + D2CB6F3A27C520D400A62B57 /* SwiftExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C452423990D00786299 /* SwiftExtensions.swift */; }; + D2CB6F3B27C520D400A62B57 /* NSURLSessionBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 61A763DB252DB2B3005A23F2 /* NSURLSessionBridge.m */; }; + D2CB6F3C27C520D400A62B57 /* VitalInfoSamplerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2EF44E2694FA14008A7DAE /* VitalInfoSamplerTests.swift */; }; + D2CB6F3D27C520D400A62B57 /* RUMViewIdentityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C1510C25AC8C1B00362D4B /* RUMViewIdentityTests.swift */; }; + D2CB6F3E27C520D400A62B57 /* DataOrchestratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6137C573271DBF4800EFC4A1 /* DataOrchestratorTests.swift */; }; + D2CB6F3F27C520D400A62B57 /* RUMDataModelMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613E820425A879AF0084B751 /* RUMDataModelMocks.swift */; }; + D2CB6F4027C520D400A62B57 /* DDLoggerBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C152423990D00786299 /* DDLoggerBuilderTests.swift */; }; + D2CB6F4127C520D400A62B57 /* VitalInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3FC3C3B2653A97700DEED9E /* VitalInfoTests.swift */; }; + D2CB6F4227C520D400A62B57 /* DDNoopTracerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F1B81426D8E5FF009F3293 /* DDNoopTracerTests.swift */; }; + D2CB6F4327C520D400A62B57 /* DDLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C172423990D00786299 /* DDLoggerTests.swift */; }; + D2CB6F4427C520D400A62B57 /* RUMDataModelsMappingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618715FB24DC5F0800FC0F69 /* RUMDataModelsMappingTests.swift */; }; + D2CB6F4527C520D400A62B57 /* TracerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A89524509BF600DA608C /* TracerTests.swift */; }; + D2CB6F4627C520D400A62B57 /* CoreMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F1A6192498A51700075390 /* CoreMocks.swift */; }; + D2CB6F4727C520D400A62B57 /* SpanEventBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E45BD12450F65B00F2C652 /* SpanEventBuilderTests.swift */; }; + D2CB6F4827C520D400A62B57 /* CrashReportingFeatureMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F2723E25C86DA400D54BF8 /* CrashReportingFeatureMocks.swift */; }; + D2CB6F4927C520D400A62B57 /* CrashReportingWithLoggingIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FF416125EE5FF400CE35EC /* CrashReportingWithLoggingIntegrationTests.swift */; }; + D2CB6F4A27C520D400A62B57 /* DateCorrectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61A9238D256FCAA2009B9667 /* DateCorrectionTests.swift */; }; + D2CB6F4B27C520D400A62B57 /* DeleteAllDataMigratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61EF788F257E289A00EDCCB3 /* DeleteAllDataMigratorTests.swift */; }; + D2CB6F4C27C520D400A62B57 /* TracingUUIDTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E45BCE2450A6EC00F2C652 /* TracingUUIDTests.swift */; }; + D2CB6F4D27C520D400A62B57 /* DataUploadStatusTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61DA20EF26C40121004AFE6D /* DataUploadStatusTests.swift */; }; + D2CB6F4E27C520D400A62B57 /* LaunchTimeProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614AD085254C3027004999A3 /* LaunchTimeProviderTests.swift */; }; + D2CB6F4F27C520D400A62B57 /* RetryingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6139CD762589FEE3007E8BB7 /* RetryingTests.swift */; }; + D2CB6F5027C520D400A62B57 /* DDDatadogTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C142423990D00786299 /* DDDatadogTests.swift */; }; + D2CB6F5127C520D400A62B57 /* URLSessionAutoInstrumentationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613F23FC252B3755006CD2D7 /* URLSessionAutoInstrumentationTests.swift */; }; + D2CB6F5227C520D400A62B57 /* FoundationMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C202423990D00786299 /* FoundationMocks.swift */; }; + D2CB6F5327C520D400A62B57 /* DirectoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C2D2423990D00786299 /* DirectoryTests.swift */; }; + D2CB6F5427C520D400A62B57 /* RUMFeatureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E5332E24B75DE2003D6C4E /* RUMFeatureTests.swift */; }; + D2CB6F5527C520D400A62B57 /* ActiveSpansPoolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D203FB24C1884500D1AF3A /* ActiveSpansPoolTests.swift */; }; + D2CB6F5627C520D400A62B57 /* InternalURLsFilterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6149FB402529DEBD00EE387A /* InternalURLsFilterTests.swift */; }; + D2CB6F5727C520D400A62B57 /* CarrierInfoProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C262423990D00786299 /* CarrierInfoProviderTests.swift */; }; + D2CB6F5827C520D400A62B57 /* RUMScopeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618DCFDE24C75FD300589570 /* RUMScopeTests.swift */; }; + D2CB6F5927C520D400A62B57 /* WarningsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C5A89A24509C1100DA608C /* WarningsTests.swift */; }; + D2CB6F5A27C520D400A62B57 /* SwiftExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E36D92124373EA700BFBDB7 /* SwiftExtensionsTests.swift */; }; + D2CB6F5B27C520D400A62B57 /* RUMEventSanitizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61122EED25B1D75B00F9C7F5 /* RUMEventSanitizerTests.swift */; }; + D2CB6F5C27C520D400A62B57 /* RUMConnectivityInfoProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614B0A5024EBDC8000A2A780 /* RUMConnectivityInfoProviderTests.swift */; }; + D2CB6F5D27C520D400A62B57 /* UIKitRUMViewsPredicateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 611F82022563C66100CB9BDB /* UIKitRUMViewsPredicateTests.swift */; }; + D2CB6F5E27C520D400A62B57 /* LogBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C3B2423990D00786299 /* LogBuilderTests.swift */; }; + D2CB6F5F27C520D400A62B57 /* DDNSURLSessionDelegate+apiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 61B5E42A26DFC433000B0A5F /* DDNSURLSessionDelegate+apiTests.m */; }; + D2CB6F6027C520D400A62B57 /* DatadogConfigurationBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F8CC082469295500FE2908 /* DatadogConfigurationBuilderTests.swift */; }; + D2CB6F6127C520D400A62B57 /* Encoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F1A622249B811200075390 /* Encoding.swift */; }; + D2CB6F6227C520D400A62B57 /* WebLogEventConsumerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA8A7F72768A72B007D6FDB /* WebLogEventConsumerTests.swift */; }; + D2CB6F6327C520D400A62B57 /* ConsentProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6114FE3A25768AA90084E372 /* ConsentProviderTests.swift */; }; + D2CB6F6427C520D400A62B57 /* LoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C382423990D00786299 /* LoggerTests.swift */; }; + D2CB6F6527C520D400A62B57 /* KronosMonitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61815C05278867D1004A666C /* KronosMonitorTests.swift */; }; + D2CB6F6627C520D400A62B57 /* RUMMonitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 617B953C24BF4D8F00E6F443 /* RUMMonitorTests.swift */; }; + D2CB6F6727C520D400A62B57 /* HostsSanitizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA8A7F0275E1518007D6FDB /* HostsSanitizerTests.swift */; }; + D2CB6F6827C520D400A62B57 /* SwiftUIExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D244B3A2271EDACD003E1B29 /* SwiftUIExtensionsTests.swift */; }; + D2CB6F6927C520D400A62B57 /* InternalMonitoringFeatureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F187FB25FA7DD60022CE9A /* InternalMonitoringFeatureTests.swift */; }; + D2CB6F6A27C520D400A62B57 /* DDRUMMonitor+apiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 61B5E42026DF85C7000B0A5F /* DDRUMMonitor+apiTests.m */; }; + D2CB6F6B27C520D400A62B57 /* RUMDebuggingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61786F7624FCDE04009E6BAB /* RUMDebuggingTests.swift */; }; + D2CB6F6C27C520D400A62B57 /* RUMInstrumentationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F9CA702512450B000A5E61 /* RUMInstrumentationTests.swift */; }; + D2CB6F6D27C520D400A62B57 /* RUMCurrentContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6156CB9224DDAA34008CB2B2 /* RUMCurrentContextTests.swift */; }; + D2CB6F6E27C520D400A62B57 /* SpanFileOutputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E45BE4245196EA00F2C652 /* SpanFileOutputTests.swift */; }; + D2CB6F6F27C520D400A62B57 /* RUMResourceScopeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61494CB424C864680082C633 /* RUMResourceScopeTests.swift */; }; + D2CB6F7027C520D400A62B57 /* UIKitMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C1C2423990D00786299 /* UIKitMocks.swift */; }; + D2CB6F7127C520D400A62B57 /* URLSessionTracingHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B03876252724AB00518F3C /* URLSessionTracingHandlerTests.swift */; }; + D2CB6F7227C520D400A62B57 /* ValuePublisherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 611529AD25E3E429004F740E /* ValuePublisherTests.swift */; }; + D2CB6F7327C520D400A62B57 /* CoreTelephonyMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C1B2423990D00786299 /* CoreTelephonyMocks.swift */; }; + D2CB6F7427C520D400A62B57 /* VitalCPUReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EC8B5ED2668E4DB000F7529 /* VitalCPUReaderTests.swift */; }; + D2CB6F7527C520D400A62B57 /* UIKitExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6115299625E3BEF9004F740E /* UIKitExtensionsTests.swift */; }; + D2CB6F7627C520D400A62B57 /* RUMUserInfoProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614B0A4C24EBD71500A2A780 /* RUMUserInfoProviderTests.swift */; }; + D2CB6F7727C520D400A62B57 /* DDURLSessionDelegateAsSuperclassTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF963E72537556300235F98 /* DDURLSessionDelegateAsSuperclassTests.swift */; }; + D2CB6F7827C520D400A62B57 /* BatteryStatusProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C252423990D00786299 /* BatteryStatusProviderTests.swift */; }; + D2CB6F7927C520D400A62B57 /* UIViewControllerSwizzlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F3CDAA25121FB500C816E5 /* UIViewControllerSwizzlerTests.swift */; }; + D2CB6F7A27C520D400A62B57 /* AppStateListenerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E989A4125F640D100235FC3 /* AppStateListenerTests.swift */; }; + D2CB6F7B27C520D400A62B57 /* RUMApplicationScopeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 617B953F24BF4DB300E6F443 /* RUMApplicationScopeTests.swift */; }; + D2CB6F7C27C520D400A62B57 /* CrashReporterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F2724825C943C500D54BF8 /* CrashReporterTests.swift */; }; + D2CB6F7D27C520D400A62B57 /* CrashContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6172472625D673D7007085B3 /* CrashContextTests.swift */; }; + D2CB6F7E27C520D400A62B57 /* OTSpanTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61BAD46926415FCE001886CA /* OTSpanTests.swift */; }; + D2CB6F7F27C520D400A62B57 /* DDDatadog+apiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 61B5E42626DFB145000B0A5F /* DDDatadog+apiTests.m */; }; + D2CB6F8027C520D400A62B57 /* LoggingForTracingAdapterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61216279247D21FE00AC5D67 /* LoggingForTracingAdapterTests.swift */; }; + D2CB6F8127C520D400A62B57 /* MobileDeviceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C232423990D00786299 /* MobileDeviceTests.swift */; }; + D2CB6F8227C520D400A62B57 /* RUMEventBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FF282024B8981D000B3D9B /* RUMEventBuilderTests.swift */; }; + D2CB6F8327C520D400A62B57 /* DDConfiguration+apiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 61B5E42826DFB60A000B0A5F /* DDConfiguration+apiTests.m */; }; + D2CB6F8427C520D400A62B57 /* DatadogTestsObserverLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 6184751726EFD03400C7C9C5 /* DatadogTestsObserverLoader.m */; }; + D2CB6F8527C520D400A62B57 /* PerformancePresetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61345612244756E300E7DA6B /* PerformancePresetTests.swift */; }; + D2CB6F9627C5217A00A62B57 /* DatadogObjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 61133BF2242397DA00786299 /* DatadogObjc.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D2CB6F9827C5217A00A62B57 /* AnyEncodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C0B2423983800786299 /* AnyEncodable.swift */; }; + D2CB6F9927C5217A00A62B57 /* Casting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6132BF5024A49F7400D7BD17 /* Casting.swift */; }; + D2CB6F9A27C5217A00A62B57 /* RUMDataModels+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6111C58125C0081F00F5C4A2 /* RUMDataModels+objc.swift */; }; + D2CB6F9B27C5217A00A62B57 /* DDSpanContext+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6132BF4824A49B6800D7BD17 /* DDSpanContext+objc.swift */; }; + D2CB6F9C27C5217A00A62B57 /* OTTracer+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6132BF4124A38D2400D7BD17 /* OTTracer+objc.swift */; }; + D2CB6F9D27C5217A00A62B57 /* TracerConfiguration+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615A4A8424A3445700233986 /* TracerConfiguration+objc.swift */; }; + D2CB6F9E27C5217A00A62B57 /* Datadog+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C092423983800786299 /* Datadog+objc.swift */; }; + D2CB6F9F27C5217A00A62B57 /* Logger+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C0C2423983800786299 /* Logger+objc.swift */; }; + D2CB6FA027C5217A00A62B57 /* Tracer+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615A4A8224A3431600233986 /* Tracer+objc.swift */; }; + D2CB6FA127C5217A00A62B57 /* HTTPHeadersWriter+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6132BF4B24A49C8F00D7BD17 /* HTTPHeadersWriter+objc.swift */; }; + D2CB6FA227C5217A00A62B57 /* DDSpan+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6132BF4624A498D800D7BD17 /* DDSpan+objc.swift */; }; + D2CB6FA327C5217A00A62B57 /* OTSpan+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615A4A8A24A3568900233986 /* OTSpan+objc.swift */; }; + D2CB6FA427C5217A00A62B57 /* DDURLSessionDelegate+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 611720D42524D9FB00634D9E /* DDURLSessionDelegate+objc.swift */; }; + D2CB6FA527C5217A00A62B57 /* RUMMonitor+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E55407B25812D1C00F6E3AD /* RUMMonitor+objc.swift */; }; + D2CB6FA627C5217A00A62B57 /* OTSpanContext+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615A4A8C24A356A000233986 /* OTSpanContext+objc.swift */; }; + D2CB6FA727C5217A00A62B57 /* Global+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EEA4870258B76A100EBDA9D /* Global+objc.swift */; }; + D2CB6FA827C5217A00A62B57 /* DatadogConfiguration+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C0D2423983800786299 /* DatadogConfiguration+objc.swift */; }; + D2CB6FB327C5234300A62B57 /* Datadog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6ED127C50EAE00A62B57 /* Datadog.framework */; }; + D2CB6FB827C523DA00A62B57 /* Datadog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6ED127C50EAE00A62B57 /* Datadog.framework */; }; + D2CB6FB927C523DA00A62B57 /* DatadogObjc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6FB027C5217A00A62B57 /* DatadogObjc.framework */; }; + D2CB6FBE27C5348200A62B57 /* DatadogCrashReporting.h in Headers */ = {isa = PBXBuildFile; fileRef = 61B7885625C180CB002675B5 /* DatadogCrashReporting.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D2CB6FC027C5348200A62B57 /* DDCrashReportBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 617247B725DAB0E2007085B3 /* DDCrashReportBuilder.swift */; }; + D2CB6FC127C5348200A62B57 /* DDCrashReportExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 612556BA268DD9BF002BCE74 /* DDCrashReportExporter.swift */; }; + D2CB6FC227C5348200A62B57 /* CrashReportMinifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FDBA1226971953001D9D43 /* CrashReportMinifier.swift */; }; + D2CB6FC327C5348200A62B57 /* PLCrashReporterIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F2728A25C9561A00D54BF8 /* PLCrashReporterIntegration.swift */; }; + D2CB6FC427C5348200A62B57 /* CrashReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 612556AF268C8D31002BCE74 /* CrashReport.swift */; }; + D2CB6FC527C5348200A62B57 /* SwiftExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615CC40B2694A56D0005F08C /* SwiftExtensions.swift */; }; + D2CB6FC627C5348200A62B57 /* DDCrashReportingPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6170DC1B25C18729003AED5C /* DDCrashReportingPlugin.swift */; }; + D2CB6FC727C5348200A62B57 /* ThirdPartyCrashReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F2727325C9509D00D54BF8 /* ThirdPartyCrashReporter.swift */; }; + D2CB6FCB27C5348200A62B57 /* CrashReporter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 614ED36B260352DC00C8C519 /* CrashReporter.xcframework */; }; + D2CB6FD927C5352300A62B57 /* DDCrashReportBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FDBA1626974CA9001D9D43 /* DDCrashReportBuilderTests.swift */; }; + D2CB6FDA27C5352300A62B57 /* FoundationMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C202423990D00786299 /* FoundationMocks.swift */; }; + D2CB6FDB27C5352300A62B57 /* SwiftExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615CC40F2694A64D0005F08C /* SwiftExtensionTests.swift */; }; + D2CB6FDC27C5352300A62B57 /* PLCrashReporterIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243BBBF276C9D640019C857 /* PLCrashReporterIntegrationTests.swift */; }; + D2CB6FDD27C5352300A62B57 /* CrashReportMinifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FDBA14269722B4001D9D43 /* CrashReportMinifierTests.swift */; }; + D2CB6FDE27C5352300A62B57 /* DDCrashReportExporterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E95D872695C00200EA3115 /* DDCrashReportExporterTests.swift */; }; + D2CB6FDF27C5352300A62B57 /* EquatableInTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61AADBDC263C7ECF008ABC6F /* EquatableInTests.swift */; }; + D2CB6FE027C5352300A62B57 /* DDCrashReportingPluginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B7886125C180CB002675B5 /* DDCrashReportingPluginTests.swift */; }; + D2CB6FE127C5352300A62B57 /* CrashReportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615CC4122695957C0005F08C /* CrashReportTests.swift */; }; + D2CB6FE227C5352300A62B57 /* Mocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61F2729A25C95EB200D54BF8 /* Mocks.swift */; }; + D2CB6FE527C5352300A62B57 /* CrashReporter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 614ED36B260352DC00C8C519 /* CrashReporter.xcframework */; }; + D2CB6FEE27C5365A00A62B57 /* Datadog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6ED127C50EAE00A62B57 /* Datadog.framework */; }; + D2CB6FF327C5369600A62B57 /* DatadogCrashReporting.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6FD127C5348200A62B57 /* DatadogCrashReporting.framework */; }; + D2DC4BBC27F234D600E4FB96 /* CITestIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E11625D727B681D200E428C6 /* CITestIntegration.swift */; }; + D2DC4BBD27F234E000E4FB96 /* CITestIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E143CCAE27D236F600F4018A /* CITestIntegrationTests.swift */; }; D2EFF3D32731822A00D09F33 /* RUMViewsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EFF3D22731822A00D09F33 /* RUMViewsHandler.swift */; }; D2F1B81126D795F3009F3293 /* DDNoopRUMMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F1B81026D795F3009F3293 /* DDNoopRUMMonitor.swift */; }; D2F1B81326D8DA68009F3293 /* DDNoopRUMMonitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F1B81226D8DA68009F3293 /* DDNoopRUMMonitorTests.swift */; }; @@ -559,9 +988,10 @@ D2F5BB36271831C200BDE2A4 /* RUMSwiftUIInstrumentationScenario.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D2F5BB35271831C200BDE2A4 /* RUMSwiftUIInstrumentationScenario.storyboard */; }; D2F5BB382718331800BDE2A4 /* SwiftUIRootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F5BB372718331800BDE2A4 /* SwiftUIRootViewController.swift */; }; D2FCA239271D896E0020286F /* SwiftUIExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FCA238271D896E0020286F /* SwiftUIExtensions.swift */; }; + E11625D827B681D200E428C6 /* CITestIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E11625D727B681D200E428C6 /* CITestIntegration.swift */; }; E132727B24B333C700952F8B /* TracingBenchmarkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E132727A24B333C700952F8B /* TracingBenchmarkTests.swift */; }; E132727D24B35B5F00952F8B /* TracingStorageBenchmarkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E132727C24B35B5F00952F8B /* TracingStorageBenchmarkTests.swift */; }; - E13A880C257922EC004FB174 /* EnvironmentSpanIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13A880B257922EC004FB174 /* EnvironmentSpanIntegration.swift */; }; + E143CCAF27D236F600F4018A /* CITestIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E143CCAE27D236F600F4018A /* CITestIntegrationTests.swift */; }; E1D202EA24C065CF00D1AF3A /* ActiveSpansPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D202E924C065CF00D1AF3A /* ActiveSpansPool.swift */; }; E1D203FD24C1885C00D1AF3A /* ActiveSpansPoolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D203FB24C1884500D1AF3A /* ActiveSpansPoolTests.swift */; }; E1D5AEA724B4D45B007F194B /* Versioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D5AEA624B4D45A007F194B /* Versioning.swift */; }; @@ -583,13 +1013,6 @@ remoteGlobalIDString = 61441C0124616DE9003D8BB8; remoteInfo = Example; }; - 61441C4F24619499003D8BB8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 61133B79242393DE00786299 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 61133B81242393DE00786299; - remoteInfo = Datadog; - }; 61441C5924619A08003D8BB8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 61133B79242393DE00786299 /* Project object */; @@ -604,20 +1027,6 @@ remoteGlobalIDString = 61441C0124616DE9003D8BB8; remoteInfo = Example; }; - 614ED39C260357FA00C8C519 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 61133B79242393DE00786299 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 61B7885325C180CB002675B5; - remoteInfo = DatadogCrashReporting; - }; - 6170DC5225C18E57003AED5C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 61133B79242393DE00786299 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 61B7885325C180CB002675B5; - remoteInfo = DatadogCrashReporting; - }; 618F9845265BC486009959F8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 61133B79242393DE00786299 /* Project object */; @@ -667,34 +1076,103 @@ remoteGlobalIDString = 61133B81242393DE00786299; remoteInfo = Datadog; }; + D240685627CF5D0100C04F44 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61133B79242393DE00786299 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2CB6E0A27C50EAE00A62B57; + remoteInfo = "Datadog tvOS"; + }; + D240685A27CF5D0100C04F44 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61133B79242393DE00786299 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2CB6FBA27C5348200A62B57; + remoteInfo = "DatadogCrashReporting tvOS"; + }; + D240686127CF5D0100C04F44 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61133B79242393DE00786299 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2CB6F9227C5217A00A62B57; + remoteInfo = "DatadogObjc tvOS"; + }; + D240686A27CF686F00C04F44 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61133B79242393DE00786299 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D24067F827CE6C9E00C04F44; + remoteInfo = "Example tvOS"; + }; + D240686C27CF687200C04F44 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61133B79242393DE00786299 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D24067F827CE6C9E00C04F44; + remoteInfo = "Example tvOS"; + }; + D28D5D5327C53A60008E72D0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61133B79242393DE00786299 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2CB6FBA27C5348200A62B57; + remoteInfo = "DatadogCrashReporting tvOS"; + }; + D2CB6FB527C5234300A62B57 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61133B79242393DE00786299 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2CB6E0A27C50EAE00A62B57; + remoteInfo = "Datadog tvOS"; + }; + D2CB6FF027C5365A00A62B57 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61133B79242393DE00786299 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2CB6E0A27C50EAE00A62B57; + remoteInfo = "Datadog tvOS"; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 61441C5124619499003D8BB8 /* ⚙️ Embed Framework Dependencies */ = { + 61993660265BB6A6009D7EA8 /* ⚙️ Embed Framework Dependencies */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - 61441C4E24619498003D8BB8 /* Datadog.framework in ⚙️ Embed Framework Dependencies */, - 614ED39B260357FA00C8C519 /* DatadogCrashReporting.framework in ⚙️ Embed Framework Dependencies */, - 61570006246AAE5E00E96950 /* DatadogObjc.framework in ⚙️ Embed Framework Dependencies */, + 61993657265BB6A6009D7EA8 /* Datadog.framework in ⚙️ Embed Framework Dependencies */, + 6199365B265BB6A6009D7EA8 /* DatadogCrashReporting.framework in ⚙️ Embed Framework Dependencies */, ); name = "⚙️ Embed Framework Dependencies"; runOnlyForDeploymentPostprocessing = 0; }; - 61993660265BB6A6009D7EA8 /* ⚙️ Embed Framework Dependencies */ = { + D240684527CE6C9E00C04F44 /* ⚙️ Embed Framework Dependencies */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - 61993657265BB6A6009D7EA8 /* Datadog.framework in ⚙️ Embed Framework Dependencies */, - 6199365B265BB6A6009D7EA8 /* DatadogCrashReporting.framework in ⚙️ Embed Framework Dependencies */, + D240685927CF5D0100C04F44 /* DatadogCrashReporting.framework in ⚙️ Embed Framework Dependencies */, + D240685527CF5D0100C04F44 /* Datadog.framework in ⚙️ Embed Framework Dependencies */, + D240686027CF5D0100C04F44 /* DatadogObjc.framework in ⚙️ Embed Framework Dependencies */, ); name = "⚙️ Embed Framework Dependencies"; runOnlyForDeploymentPostprocessing = 0; }; + D240687A27CF982B00C04F44 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + D240687E27CF982D00C04F44 /* DatadogCrashReporting.framework in Embed Frameworks */, + D240687C27CF982C00C04F44 /* Datadog.framework in Embed Frameworks */, + D240688027CF982F00C04F44 /* DatadogObjc.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -863,11 +1341,10 @@ 61410166251A661D00E3C2D9 /* UIApplicationSwizzlerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIApplicationSwizzlerTests.swift; sourceTree = ""; }; 61411B0F24EC15AC0012EAB2 /* Casting+RUM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Casting+RUM.swift"; sourceTree = ""; }; 61417DC52525CDDE00E2D55C /* TaskInterception.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskInterception.swift; sourceTree = ""; }; - 61441C0224616DE9003D8BB8 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 61441C0224616DE9003D8BB8 /* Example iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 61441C0424616DE9003D8BB8 /* ExampleAppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleAppDelegate.swift; sourceTree = ""; }; - 61441C0B24616DE9003D8BB8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 61441C0B24616DE9003D8BB8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = "Base.lproj/Main iOS.storyboard"; sourceTree = ""; }; 61441C0D24616DEC003D8BB8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 61441C1024616DEC003D8BB8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 61441C1224616DEC003D8BB8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61441C2A24616F1D003D8BB8 /* DatadogIntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DatadogIntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 61441C3B24617013003D8BB8 /* IntegrationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntegrationTests.swift; sourceTree = ""; }; @@ -1244,6 +1721,8 @@ B3FC3C3B2653A97700DEED9E /* VitalInfoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VitalInfoTests.swift; sourceTree = ""; }; D213532F270CA722000315AD /* DataCompressionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataCompressionTests.swift; sourceTree = ""; }; D22C1F5B271484B400922024 /* LogEventMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogEventMapper.swift; sourceTree = ""; }; + D240684D27CE6C9E00C04F44 /* Example tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + D240688527CFA64A00C04F44 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; D243BBBF276C9D640019C857 /* PLCrashReporterIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PLCrashReporterIntegrationTests.swift; sourceTree = ""; }; D244B3A2271EDACD003E1B29 /* SwiftUIExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIExtensionsTests.swift; sourceTree = ""; }; D249859F2728042200B4F72D /* SwiftUIViewModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftUIViewModifier.swift; sourceTree = ""; }; @@ -1252,6 +1731,11 @@ D2791EF827170A760046E07A /* RUMSwiftUIScenarioTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RUMSwiftUIScenarioTests.swift; sourceTree = ""; }; D29889C72734136200A4D1A9 /* RUMViewsHandlerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RUMViewsHandlerTests.swift; sourceTree = ""; }; D29D5A4C273BF8B400A687C1 /* SwiftUIActionModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIActionModifier.swift; sourceTree = ""; }; + D2CB6ED127C50EAE00A62B57 /* Datadog.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Datadog.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D2CB6F8F27C520D400A62B57 /* DatadogTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DatadogTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + D2CB6FB027C5217A00A62B57 /* DatadogObjc.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DatadogObjc.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D2CB6FD127C5348200A62B57 /* DatadogCrashReporting.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DatadogCrashReporting.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D2CB6FEC27C5352300A62B57 /* DatadogCrashReportingTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DatadogCrashReportingTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; D2EFF3D22731822A00D09F33 /* RUMViewsHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RUMViewsHandler.swift; sourceTree = ""; }; D2F1B81026D795F3009F3293 /* DDNoopRUMMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DDNoopRUMMonitor.swift; sourceTree = ""; }; D2F1B81226D8DA68009F3293 /* DDNoopRUMMonitorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DDNoopRUMMonitorTests.swift; sourceTree = ""; }; @@ -1259,9 +1743,10 @@ D2F5BB35271831C200BDE2A4 /* RUMSwiftUIInstrumentationScenario.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = RUMSwiftUIInstrumentationScenario.storyboard; sourceTree = ""; }; D2F5BB372718331800BDE2A4 /* SwiftUIRootViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIRootViewController.swift; sourceTree = ""; }; D2FCA238271D896E0020286F /* SwiftUIExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIExtensions.swift; sourceTree = ""; }; + E11625D727B681D200E428C6 /* CITestIntegration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CITestIntegration.swift; sourceTree = ""; }; E132727A24B333C700952F8B /* TracingBenchmarkTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TracingBenchmarkTests.swift; sourceTree = ""; }; E132727C24B35B5F00952F8B /* TracingStorageBenchmarkTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TracingStorageBenchmarkTests.swift; sourceTree = ""; }; - E13A880B257922EC004FB174 /* EnvironmentSpanIntegration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentSpanIntegration.swift; sourceTree = ""; }; + E143CCAE27D236F600F4018A /* CITestIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CITestIntegrationTests.swift; sourceTree = ""; }; E1B082CB25641DF9002DB9D2 /* Example.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Example.xcconfig; sourceTree = ""; }; E1D202E924C065CF00D1AF3A /* ActiveSpansPool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSpansPool.swift; sourceTree = ""; }; E1D203FB24C1884500D1AF3A /* ActiveSpansPoolTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSpansPoolTests.swift; sourceTree = ""; }; @@ -1291,9 +1776,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 61B03ECE274FF01F00EB1AE1 /* SwiftUI.framework in Frameworks */, - 614ED39A260357FA00C8C519 /* DatadogCrashReporting.framework in Frameworks */, - 614ED37C2603533D00C8C519 /* CrashReporter.xcframework in Frameworks */, + D240687827CF982B00C04F44 /* CrashReporter.xcframework in Frameworks */, + D240687B27CF982C00C04F44 /* Datadog.framework in Frameworks */, + D240687D27CF982D00C04F44 /* DatadogCrashReporting.framework in Frameworks */, + D240687F27CF982F00C04F44 /* DatadogObjc.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1364,6 +1850,60 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D240682F27CE6C9E00C04F44 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D240687027CF971C00C04F44 /* CrashReporter.xcframework in Frameworks */, + D240687127CF971C00C04F44 /* Datadog.framework in Frameworks */, + D240687227CF971C00C04F44 /* DatadogCrashReporting.framework in Frameworks */, + D240687327CF971C00C04F44 /* DatadogObjc.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6ECC27C50EAE00A62B57 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6F8627C520D400A62B57 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D28D5D5527C54B30008E72D0 /* DatadogCrashReporting.framework in Frameworks */, + D2CB6FB827C523DA00A62B57 /* Datadog.framework in Frameworks */, + D2CB6FB927C523DA00A62B57 /* DatadogObjc.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6FA927C5217A00A62B57 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D2CB6FB327C5234300A62B57 /* Datadog.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6FCA27C5348200A62B57 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D2CB6FCB27C5348200A62B57 /* CrashReporter.xcframework in Frameworks */, + D2CB6FEE27C5365A00A62B57 /* Datadog.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6FE327C5352300A62B57 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D2CB6FF327C5369600A62B57 /* DatadogCrashReporting.framework in Frameworks */, + D2CB6FE527C5352300A62B57 /* CrashReporter.xcframework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -1441,7 +1981,7 @@ 61133B82242393DE00786299 /* Datadog.framework */, 61133B8B242393DE00786299 /* DatadogTests.xctest */, 61133BF0242397DA00786299 /* DatadogObjc.framework */, - 61441C0224616DE9003D8BB8 /* Example.app */, + 61441C0224616DE9003D8BB8 /* Example iOS.app */, 61441C2A24616F1D003D8BB8 /* DatadogIntegrationTests.xctest */, 61441C6824619FE4003D8BB8 /* DatadogBenchmarkTests.xctest */, 61B7885425C180CB002675B5 /* DatadogCrashReporting.framework */, @@ -1449,6 +1989,12 @@ 6199362B265BA958009D7EA8 /* E2E.app */, 61993665265BBEDC009D7EA8 /* E2ETests.xctest */, 618F9840265BC486009959F8 /* E2EInstrumentationTests.xctest */, + D2CB6ED127C50EAE00A62B57 /* Datadog.framework */, + D2CB6F8F27C520D400A62B57 /* DatadogTests.xctest */, + D2CB6FB027C5217A00A62B57 /* DatadogObjc.framework */, + D2CB6FD127C5348200A62B57 /* DatadogCrashReporting.framework */, + D2CB6FEC27C5352300A62B57 /* DatadogCrashReportingTests.xctest */, + D240684D27CE6C9E00C04F44 /* Example tvOS.app */, ); name = Products; sourceTree = ""; @@ -1977,7 +2523,7 @@ 6105D19F2508F1600040DD22 /* LoggingWithActiveSpanIntegration.swift */, 6156CB9B24E18224008CB2B2 /* TracingWithRUMIntegration.swift */, 61FC5F4425CC23C9006BB4DE /* RUMWithCrashContextIntegration.swift */, - E13A880B257922EC004FB174 /* EnvironmentSpanIntegration.swift */, + E11625D727B681D200E428C6 /* CITestIntegration.swift */, 9EB4B860274E79620041CD03 /* WebView */, 6112B11C25C84E7F00B37771 /* CrashReporting */, ); @@ -1988,6 +2534,7 @@ isa = PBXGroup; children = ( 61D980BB24E293F600E03345 /* RUMIntegrationsTests.swift */, + E143CCAE27D236F600F4018A /* CITestIntegrationTests.swift */, 61216279247D21FE00AC5D67 /* LoggingForTracingAdapterTests.swift */, 61FC5F4D25CC2920006BB4DE /* RUMWithCrashContextIntegrationTests.swift */, 6182374125D3DFB8006A375B /* CrashReporting */, @@ -2234,7 +2781,6 @@ isa = PBXGroup; children = ( D29D5A48273BF7E100A687C1 /* UIKit */, - D29D5A49273BF7F300A687C1 /* SwiftUI */, ); path = Actions; sourceTree = ""; @@ -2275,9 +2821,9 @@ 61441C9A2461A64F003D8BB8 /* Debugging */, 6133702F250F829000236D58 /* Scenarios */, 61441C8F2461A648003D8BB8 /* Utils */, - 61441C0A24616DE9003D8BB8 /* Main.storyboard */, + 61441C0A24616DE9003D8BB8 /* Main iOS.storyboard */, 61441C0D24616DEC003D8BB8 /* Assets.xcassets */, - 61441C0F24616DEC003D8BB8 /* LaunchScreen.storyboard */, + D240688427CFA64A00C04F44 /* LaunchScreen.storyboard */, ); path = Example; sourceTree = ""; @@ -3534,13 +4080,6 @@ path = UIKit; sourceTree = ""; }; - D29D5A49273BF7F300A687C1 /* SwiftUI */ = { - isa = PBXGroup; - children = ( - ); - path = SwiftUI; - sourceTree = ""; - }; D29D5A4A273BF81500A687C1 /* UIKit */ = { isa = PBXGroup; children = ( @@ -3588,12 +4127,38 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D2CB6E0B27C50EAE00A62B57 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D2CB6E0C27C50EAE00A62B57 /* Datadog.h in Headers */, + D2CB6E0D27C50EAE00A62B57 /* ObjcAppLaunchHandler.h in Headers */, + D2CB6E0E27C50EAE00A62B57 /* ObjcExceptionHandler.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6F9527C5217A00A62B57 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D2CB6F9627C5217A00A62B57 /* DatadogObjc.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6FBD27C5348200A62B57 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D2CB6FBE27C5348200A62B57 /* DatadogCrashReporting.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 61133B81242393DE00786299 /* Datadog */ = { + 61133B81242393DE00786299 /* Datadog iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 61133B96242393DE00786299 /* Build configuration list for PBXNativeTarget "Datadog" */; + buildConfigurationList = 61133B96242393DE00786299 /* Build configuration list for PBXNativeTarget "Datadog iOS" */; buildPhases = ( 61133B7D242393DE00786299 /* Headers */, 61133B7E242393DE00786299 /* Sources */, @@ -3605,14 +4170,14 @@ ); dependencies = ( ); - name = Datadog; + name = "Datadog iOS"; productName = Datadog; productReference = 61133B82242393DE00786299 /* Datadog.framework */; productType = "com.apple.product-type.framework"; }; - 61133B8A242393DE00786299 /* DatadogTests */ = { + 61133B8A242393DE00786299 /* DatadogTests iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 61133B99242393DE00786299 /* Build configuration list for PBXNativeTarget "DatadogTests" */; + buildConfigurationList = 61133B99242393DE00786299 /* Build configuration list for PBXNativeTarget "DatadogTests iOS" */; buildPhases = ( 61133B87242393DE00786299 /* Sources */, 61133B88242393DE00786299 /* Frameworks */, @@ -3624,14 +4189,14 @@ dependencies = ( 61441C5A24619A08003D8BB8 /* PBXTargetDependency */, ); - name = DatadogTests; + name = "DatadogTests iOS"; productName = DatadogTests; productReference = 61133B8B242393DE00786299 /* DatadogTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 61133BEF242397DA00786299 /* DatadogObjc */ = { + 61133BEF242397DA00786299 /* DatadogObjc iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 61133C01242397DA00786299 /* Build configuration list for PBXNativeTarget "DatadogObjc" */; + buildConfigurationList = 61133C01242397DA00786299 /* Build configuration list for PBXNativeTarget "DatadogObjc iOS" */; buildPhases = ( 61133BEB242397DA00786299 /* Headers */, 61133BEC242397DA00786299 /* Sources */, @@ -3643,32 +4208,29 @@ dependencies = ( 61133C732423993200786299 /* PBXTargetDependency */, ); - name = DatadogObjc; + name = "DatadogObjc iOS"; productName = DatadogObjc; productReference = 61133BF0242397DA00786299 /* DatadogObjc.framework */; productType = "com.apple.product-type.framework"; }; - 61441C0124616DE9003D8BB8 /* Example */ = { + 61441C0124616DE9003D8BB8 /* Example iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 61441C1324616DEC003D8BB8 /* Build configuration list for PBXNativeTarget "Example" */; + buildConfigurationList = 61441C1324616DEC003D8BB8 /* Build configuration list for PBXNativeTarget "Example iOS" */; buildPhases = ( 61441BFE24616DE9003D8BB8 /* Sources */, 61441BFF24616DE9003D8BB8 /* Frameworks */, 61441C0024616DE9003D8BB8 /* Resources */, - 61441C5124619499003D8BB8 /* ⚙️ Embed Framework Dependencies */, + D240687A27CF982B00C04F44 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( - 61441C5024619499003D8BB8 /* PBXTargetDependency */, - 6170DC5325C18E57003AED5C /* PBXTargetDependency */, - 614ED39D260357FA00C8C519 /* PBXTargetDependency */, ); - name = Example; + name = "Example iOS"; packageProductDependencies = ( ); productName = Example; - productReference = 61441C0224616DE9003D8BB8 /* Example.app */; + productReference = 61441C0224616DE9003D8BB8 /* Example iOS.app */; productType = "com.apple.product-type.application"; }; 61441C2924616F1D003D8BB8 /* DatadogIntegrationTests */ = { @@ -3771,9 +4333,9 @@ productReference = 61993665265BBEDC009D7EA8 /* E2ETests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 61B7885325C180CB002675B5 /* DatadogCrashReporting */ = { + 61B7885325C180CB002675B5 /* DatadogCrashReporting iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 61B7886B25C180CB002675B5 /* Build configuration list for PBXNativeTarget "DatadogCrashReporting" */; + buildConfigurationList = 61B7886B25C180CB002675B5 /* Build configuration list for PBXNativeTarget "DatadogCrashReporting iOS" */; buildPhases = ( 61B7884F25C180CB002675B5 /* Headers */, 61B7885025C180CB002675B5 /* Sources */, @@ -3786,14 +4348,14 @@ dependencies = ( 61DE335825C82941008E3EC2 /* PBXTargetDependency */, ); - name = DatadogCrashReporting; + name = "DatadogCrashReporting iOS"; productName = DatadogCrashReporting; productReference = 61B7885425C180CB002675B5 /* DatadogCrashReporting.framework */; productType = "com.apple.product-type.framework"; }; - 61B7885B25C180CB002675B5 /* DatadogCrashReportingTests */ = { + 61B7885B25C180CB002675B5 /* DatadogCrashReportingTests iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 61B7886C25C180CB002675B5 /* Build configuration list for PBXNativeTarget "DatadogCrashReportingTests" */; + buildConfigurationList = 61B7886C25C180CB002675B5 /* Build configuration list for PBXNativeTarget "DatadogCrashReportingTests iOS" */; buildPhases = ( 61B7885825C180CB002675B5 /* Sources */, 61B7885925C180CB002675B5 /* Frameworks */, @@ -3806,11 +4368,131 @@ 61B7885F25C180CB002675B5 /* PBXTargetDependency */, 61B7888025C18147002675B5 /* PBXTargetDependency */, ); - name = DatadogCrashReportingTests; + name = "DatadogCrashReportingTests iOS"; productName = DatadogCrashReportingTests; productReference = 61B7885C25C180CB002675B5 /* DatadogCrashReportingTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + D24067F827CE6C9E00C04F44 /* Example tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D240684927CE6C9E00C04F44 /* Build configuration list for PBXNativeTarget "Example tvOS" */; + buildPhases = ( + D24067FD27CE6C9E00C04F44 /* Sources */, + D240682F27CE6C9E00C04F44 /* Frameworks */, + D240683327CE6C9E00C04F44 /* Resources */, + D240684527CE6C9E00C04F44 /* ⚙️ Embed Framework Dependencies */, + ); + buildRules = ( + ); + dependencies = ( + D240685727CF5D0100C04F44 /* PBXTargetDependency */, + D240686227CF5D0100C04F44 /* PBXTargetDependency */, + D240685B27CF5D0100C04F44 /* PBXTargetDependency */, + ); + name = "Example tvOS"; + packageProductDependencies = ( + ); + productName = Example; + productReference = D240684D27CE6C9E00C04F44 /* Example tvOS.app */; + productType = "com.apple.product-type.application"; + }; + D2CB6E0A27C50EAE00A62B57 /* Datadog tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D2CB6ECD27C50EAE00A62B57 /* Build configuration list for PBXNativeTarget "Datadog tvOS" */; + buildPhases = ( + D2CB6E0B27C50EAE00A62B57 /* Headers */, + D2CB6E0F27C50EAE00A62B57 /* Sources */, + D2CB6ECA27C50EAE00A62B57 /* Resources */, + D2CB6ECB27C50EAE00A62B57 /* ⚙️ Run linter */, + D2CB6ECC27C50EAE00A62B57 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Datadog tvOS"; + productName = Datadog; + productReference = D2CB6ED127C50EAE00A62B57 /* Datadog.framework */; + productType = "com.apple.product-type.framework"; + }; + D2CB6ED327C520D400A62B57 /* DatadogTests tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D2CB6F8B27C520D400A62B57 /* Build configuration list for PBXNativeTarget "DatadogTests tvOS" */; + buildPhases = ( + D2CB6ED627C520D400A62B57 /* Sources */, + D2CB6F8627C520D400A62B57 /* Frameworks */, + D2CB6F8927C520D400A62B57 /* Resources */, + D2CB6F8A27C520D400A62B57 /* ⚙️ Run linter */, + ); + buildRules = ( + ); + dependencies = ( + D240686D27CF687200C04F44 /* PBXTargetDependency */, + ); + name = "DatadogTests tvOS"; + productName = DatadogTests; + productReference = D2CB6F8F27C520D400A62B57 /* DatadogTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + D2CB6F9227C5217A00A62B57 /* DatadogObjc tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D2CB6FAC27C5217A00A62B57 /* Build configuration list for PBXNativeTarget "DatadogObjc tvOS" */; + buildPhases = ( + D2CB6F9527C5217A00A62B57 /* Headers */, + D2CB6F9727C5217A00A62B57 /* Sources */, + D2CB6FA927C5217A00A62B57 /* Frameworks */, + D2CB6FAB27C5217A00A62B57 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D2CB6FB627C5234300A62B57 /* PBXTargetDependency */, + ); + name = "DatadogObjc tvOS"; + productName = DatadogObjc; + productReference = D2CB6FB027C5217A00A62B57 /* DatadogObjc.framework */; + productType = "com.apple.product-type.framework"; + }; + D2CB6FBA27C5348200A62B57 /* DatadogCrashReporting tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D2CB6FCD27C5348200A62B57 /* Build configuration list for PBXNativeTarget "DatadogCrashReporting tvOS" */; + buildPhases = ( + D2CB6FBD27C5348200A62B57 /* Headers */, + D2CB6FBF27C5348200A62B57 /* Sources */, + D2CB6FC827C5348200A62B57 /* Resources */, + D2CB6FC927C5348200A62B57 /* ⚙️ Run linter */, + D2CB6FCA27C5348200A62B57 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + D2CB6FF127C5365A00A62B57 /* PBXTargetDependency */, + ); + name = "DatadogCrashReporting tvOS"; + productName = DatadogCrashReporting; + productReference = D2CB6FD127C5348200A62B57 /* DatadogCrashReporting.framework */; + productType = "com.apple.product-type.framework"; + }; + D2CB6FD327C5352300A62B57 /* DatadogCrashReportingTests tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D2CB6FE827C5352300A62B57 /* Build configuration list for PBXNativeTarget "DatadogCrashReportingTests tvOS" */; + buildPhases = ( + D2CB6FD827C5352300A62B57 /* Sources */, + D2CB6FE327C5352300A62B57 /* Frameworks */, + D2CB6FE627C5352300A62B57 /* Resources */, + D2CB6FE727C5352300A62B57 /* ⚙️ Run linter */, + ); + buildRules = ( + ); + dependencies = ( + D28D5D5427C53A60008E72D0 /* PBXTargetDependency */, + D240686B27CF686F00C04F44 /* PBXTargetDependency */, + ); + name = "DatadogCrashReportingTests tvOS"; + productName = DatadogCrashReportingTests; + productReference = D2CB6FEC27C5352300A62B57 /* DatadogCrashReportingTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -3863,6 +4545,12 @@ CreatedOnToolsVersion = 12.3; TestTargetID = 61441C0124616DE9003D8BB8; }; + D2CB6ED327C520D400A62B57 = { + TestTargetID = D24067F827CE6C9E00C04F44; + }; + D2CB6FD327C5352300A62B57 = { + TestTargetID = D24067F827CE6C9E00C04F44; + }; }; }; buildConfigurationList = 61133B7C242393DE00786299 /* Build configuration list for PBXProject "Datadog" */; @@ -3878,14 +4566,20 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 61133B81242393DE00786299 /* Datadog */, - 61133BEF242397DA00786299 /* DatadogObjc */, - 61B7885325C180CB002675B5 /* DatadogCrashReporting */, - 61133B8A242393DE00786299 /* DatadogTests */, - 61B7885B25C180CB002675B5 /* DatadogCrashReportingTests */, + 61133B81242393DE00786299 /* Datadog iOS */, + 61133BEF242397DA00786299 /* DatadogObjc iOS */, + 61B7885325C180CB002675B5 /* DatadogCrashReporting iOS */, + 61133B8A242393DE00786299 /* DatadogTests iOS */, + 61B7885B25C180CB002675B5 /* DatadogCrashReportingTests iOS */, + D2CB6E0A27C50EAE00A62B57 /* Datadog tvOS */, + D2CB6F9227C5217A00A62B57 /* DatadogObjc tvOS */, + D2CB6FBA27C5348200A62B57 /* DatadogCrashReporting tvOS */, + D2CB6ED327C520D400A62B57 /* DatadogTests tvOS */, + D2CB6FD327C5352300A62B57 /* DatadogCrashReportingTests tvOS */, 61441C6724619FE4003D8BB8 /* DatadogBenchmarkTests */, 61441C2924616F1D003D8BB8 /* DatadogIntegrationTests */, - 61441C0124616DE9003D8BB8 /* Example */, + 61441C0124616DE9003D8BB8 /* Example iOS */, + D24067F827CE6C9E00C04F44 /* Example tvOS */, 6199362A265BA958009D7EA8 /* E2E */, 61993664265BBEDC009D7EA8 /* E2ETests */, 618F983F265BC486009959F8 /* E2EInstrumentationTests */, @@ -3923,15 +4617,15 @@ 612D8F6925AEE68F000E2E09 /* RUMScrubbingScenario.storyboard in Resources */, D2F5BB36271831C200BDE2A4 /* RUMSwiftUIInstrumentationScenario.storyboard in Resources */, 611EA13C2580F77400BC0E56 /* TrackingConsentScenario.storyboard in Resources */, - 61441C1124616DEC003D8BB8 /* LaunchScreen.storyboard in Resources */, 9EA95C1D2791C9BE00F6C1F3 /* WebViewTrackingScenario.storyboard in Resources */, 61337039250F852E00236D58 /* RUMManualInstrumentationScenario.storyboard in Resources */, 6193DCA4251B5691009B8011 /* RUMTapActionScenario.storyboard in Resources */, 6167ACC7251A0BCE0012B4D0 /* NSURLSessionScenario.storyboard in Resources */, 6111543625C993C2007C84C9 /* CrashReportingScenario.storyboard in Resources */, + D240688627CFA64A00C04F44 /* LaunchScreen.storyboard in Resources */, 61441C0E24616DEC003D8BB8 /* Assets.xcassets in Resources */, 6137E649252DD88D00720485 /* RUMModalViewsAutoInstrumentationScenario.storyboard in Resources */, - 61441C0C24616DE9003D8BB8 /* Main.storyboard in Resources */, + 61441C0C24616DE9003D8BB8 /* Main iOS.storyboard in Resources */, 615AAC36251E353700C89EE9 /* RUMTabBarAutoInstrumentationScenario.storyboard in Resources */, 9EC2835E26CFF57A00FACF1C /* RUMMobileVitalsScenario.storyboard in Resources */, 6167AD19251A27B80012B4D0 /* URLSessionScenario.storyboard in Resources */, @@ -3991,6 +4685,49 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D240683327CE6C9E00C04F44 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D240683D27CE6C9E00C04F44 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6ECA27C50EAE00A62B57 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6F8927C520D400A62B57 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6FAB27C5217A00A62B57 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6FC827C5348200A62B57 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6FE627C5352300A62B57 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -4108,34 +4845,111 @@ shellScript = "if which swiftlint >/dev/null; then\n cd ${SOURCE_ROOT}/..\n ./tools/lint/run-linter.sh\nfi\n"; showEnvVarsInLog = 0; }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 61133B7E242393DE00786299 /* Sources */ = { - isa = PBXSourcesBuildPhase; + D2CB6ECB27C50EAE00A62B57 /* ⚙️ Run linter */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( - 6112B10B25C849C000B37771 /* CrashReportingWithRUMIntegration.swift in Sources */, - 61E917D12465423600E6C631 /* TracerConfiguration.swift in Sources */, - D24985A22728048B00B4F72D /* SwiftUIViewHandler.swift in Sources */, - D24985A327280FD100B4F72D /* SwiftUIViewModifier.swift in Sources */, - D2FCA239271D896E0020286F /* SwiftUIExtensions.swift in Sources */, - 61C576C6256E65BD00295F7C /* DateCorrector.swift in Sources */, - 61FC5F4525CC23C9006BB4DE /* RUMWithCrashContextIntegration.swift in Sources */, - 61E909ED24A24DD3005EA2DE /* OTSpan.swift in Sources */, - 61FF9A4525AC5DEA001058CC /* RUMViewIdentity.swift in Sources */, - 616124A725CAC268009901BE /* CrashContextProvider.swift in Sources */, - 61E909F324A24DD3005EA2DE /* OTSpanContext.swift in Sources */, - 61E909F024A24DD3005EA2DE /* OTTracer.swift in Sources */, - 61E909F124A24DD3005EA2DE /* OTReference.swift in Sources */, - 6116563B25D2A6C90070EC03 /* ArbitraryDataWriter.swift in Sources */, - 61216276247D1CD700AC5D67 /* LoggingForTracingAdapter.swift in Sources */, - 9EB4B866274FAB4C0041CD03 /* WebRUMEventConsumer.swift in Sources */, - 61E909EF24A24DD3005EA2DE /* Global.swift in Sources */, - D2EFF3D32731822A00D09F33 /* RUMViewsHandler.swift in Sources */, - 61133BDD2423979B00786299 /* InternalLoggers.swift in Sources */, - 6105D1A02508F1600040DD22 /* LoggingWithActiveSpanIntegration.swift in Sources */, - 9EB4B864274FAB410041CD03 /* WebLogEventConsumer.swift in Sources */, + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "⚙️ Run linter"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [ \"$CARTHAGE\" == \"YES\" ]; then\n echo \"Skipping linting for carthage build...\"\nelif which swiftlint >/dev/null; then\n cd ${SOURCE_ROOT}/..\n ./tools/lint/run-linter.sh\nfi\n"; + showEnvVarsInLog = 0; + }; + D2CB6F8A27C520D400A62B57 /* ⚙️ Run linter */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "⚙️ Run linter"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\n cd ${SOURCE_ROOT}/..\n ./tools/lint/run-linter.sh\nfi\n"; + showEnvVarsInLog = 0; + }; + D2CB6FC927C5348200A62B57 /* ⚙️ Run linter */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "⚙️ Run linter"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [ \"$CARTHAGE\" == \"YES\" ]; then\n echo \"Skipping linting for carthage build...\"\nelif which swiftlint >/dev/null; then\n cd ${SOURCE_ROOT}/..\n ./tools/lint/run-linter.sh\nfi\n"; + showEnvVarsInLog = 0; + }; + D2CB6FE727C5352300A62B57 /* ⚙️ Run linter */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "⚙️ Run linter"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\n cd ${SOURCE_ROOT}/..\n ./tools/lint/run-linter.sh\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 61133B7E242393DE00786299 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6112B10B25C849C000B37771 /* CrashReportingWithRUMIntegration.swift in Sources */, + 61E917D12465423600E6C631 /* TracerConfiguration.swift in Sources */, + D24985A22728048B00B4F72D /* SwiftUIViewHandler.swift in Sources */, + D24985A327280FD100B4F72D /* SwiftUIViewModifier.swift in Sources */, + D2FCA239271D896E0020286F /* SwiftUIExtensions.swift in Sources */, + 61C576C6256E65BD00295F7C /* DateCorrector.swift in Sources */, + 61FC5F4525CC23C9006BB4DE /* RUMWithCrashContextIntegration.swift in Sources */, + 61E909ED24A24DD3005EA2DE /* OTSpan.swift in Sources */, + 61FF9A4525AC5DEA001058CC /* RUMViewIdentity.swift in Sources */, + 616124A725CAC268009901BE /* CrashContextProvider.swift in Sources */, + 61E909F324A24DD3005EA2DE /* OTSpanContext.swift in Sources */, + 61E909F024A24DD3005EA2DE /* OTTracer.swift in Sources */, + 61E909F124A24DD3005EA2DE /* OTReference.swift in Sources */, + 6116563B25D2A6C90070EC03 /* ArbitraryDataWriter.swift in Sources */, + 61216276247D1CD700AC5D67 /* LoggingForTracingAdapter.swift in Sources */, + 9EB4B866274FAB4C0041CD03 /* WebRUMEventConsumer.swift in Sources */, + E11625D827B681D200E428C6 /* CITestIntegration.swift in Sources */, + 61E909EF24A24DD3005EA2DE /* Global.swift in Sources */, + D2EFF3D32731822A00D09F33 /* RUMViewsHandler.swift in Sources */, + 61133BDD2423979B00786299 /* InternalLoggers.swift in Sources */, + 6105D1A02508F1600040DD22 /* LoggingWithActiveSpanIntegration.swift in Sources */, + 9EB4B864274FAB410041CD03 /* WebLogEventConsumer.swift in Sources */, 61EF78B1257E2E7A00EDCCB3 /* MoveDataMigrator.swift in Sources */, 61133BDC2423979B00786299 /* Logger.swift in Sources */, 6114FE1625766B310084E372 /* TrackingConsent.swift in Sources */, @@ -4281,7 +5095,6 @@ 61D3E0D8277B23F1008BE766 /* KronosNTPClient.swift in Sources */, 9E9973F1268DF69500D8059B /* VitalInfoSampler.swift in Sources */, 9EA3CA6926775A3500B16871 /* VitalRefreshRateReader.swift in Sources */, - E13A880C257922EC004FB174 /* EnvironmentSpanIntegration.swift in Sources */, 61B038602527247200518F3C /* URLSessionTracingHandler.swift in Sources */, 61122ED425B1B84D00F9C7F5 /* RUMEventSanitizer.swift in Sources */, 61363D9D24D999F70084CD6F /* DDError.swift in Sources */, @@ -4359,6 +5172,7 @@ 61EF78B7257E37D500EDCCB3 /* MoveDataMigratorTests.swift in Sources */, 61F1A621249A45E400075390 /* DDSpanContextTests.swift in Sources */, 61D03BE0273404E700367DE0 /* RUMDataModels+objcTests.swift in Sources */, + E143CCAF27D236F600F4018A /* CITestIntegrationTests.swift in Sources */, 615C3196251DD5080018781C /* UIKitRUMUserActionsHandlerTests.swift in Sources */, 61E917CF2464270500E6C631 /* CodableValueTests.swift in Sources */, 61D3E0E4277B3D92008BE766 /* KronosNTPPacketTests.swift in Sources */, @@ -4700,44 +5514,478 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D24067FD27CE6C9E00C04F44 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D240680827CE6C9E00C04F44 /* ConsoleOutputInterceptor.swift in Sources */, + D240680E27CE6C9E00C04F44 /* UIViewController+KeyboardControlling.swift in Sources */, + D240681627CE6C9E00C04F44 /* AppConfiguration.swift in Sources */, + D240681E27CE6C9E00C04F44 /* ExampleAppDelegate.swift in Sources */, + D240682527CE6C9E00C04F44 /* PersistenceHelper.swift in Sources */, + D240682B27CE6C9E00C04F44 /* UIButton+Disabling.swift in Sources */, + D240682D27CE6C9E00C04F44 /* Environment.swift in Sources */, + D240684F27CF5CA500C04F44 /* TestScenarios.swift in Sources */, + D240686827CF642900C04F44 /* SwiftUI.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6E0F27C50EAE00A62B57 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D2CB6E1027C50EAE00A62B57 /* CrashReportingWithRUMIntegration.swift in Sources */, + D2DC4BBC27F234D600E4FB96 /* CITestIntegration.swift in Sources */, + D2CB6E1127C50EAE00A62B57 /* TracerConfiguration.swift in Sources */, + D2CB6E1227C50EAE00A62B57 /* SwiftUIViewHandler.swift in Sources */, + D2CB6E1327C50EAE00A62B57 /* SwiftUIViewModifier.swift in Sources */, + D2CB6E1427C50EAE00A62B57 /* SwiftUIExtensions.swift in Sources */, + D2CB6E1527C50EAE00A62B57 /* DateCorrector.swift in Sources */, + D2CB6E1627C50EAE00A62B57 /* RUMWithCrashContextIntegration.swift in Sources */, + D2CB6E1727C50EAE00A62B57 /* OTSpan.swift in Sources */, + D2CB6E1827C50EAE00A62B57 /* RUMViewIdentity.swift in Sources */, + D2CB6E1927C50EAE00A62B57 /* CrashContextProvider.swift in Sources */, + D2CB6E1A27C50EAE00A62B57 /* OTSpanContext.swift in Sources */, + D2CB6E1B27C50EAE00A62B57 /* OTTracer.swift in Sources */, + D2CB6E1C27C50EAE00A62B57 /* OTReference.swift in Sources */, + D2CB6E1D27C50EAE00A62B57 /* ArbitraryDataWriter.swift in Sources */, + D2CB6E1E27C50EAE00A62B57 /* LoggingForTracingAdapter.swift in Sources */, + D2CB6E1F27C50EAE00A62B57 /* WebRUMEventConsumer.swift in Sources */, + D2CB6E2027C50EAE00A62B57 /* Global.swift in Sources */, + D2CB6E2127C50EAE00A62B57 /* RUMViewsHandler.swift in Sources */, + D2CB6E2227C50EAE00A62B57 /* InternalLoggers.swift in Sources */, + D2CB6E2327C50EAE00A62B57 /* LoggingWithActiveSpanIntegration.swift in Sources */, + D2CB6E2427C50EAE00A62B57 /* WebLogEventConsumer.swift in Sources */, + D2CB6E2527C50EAE00A62B57 /* MoveDataMigrator.swift in Sources */, + D2CB6E2627C50EAE00A62B57 /* Logger.swift in Sources */, + D2CB6E2727C50EAE00A62B57 /* TrackingConsent.swift in Sources */, + D2CB6E2827C50EAE00A62B57 /* DateProvider.swift in Sources */, + D2CB6E2927C50EAE00A62B57 /* KronosInternetAddress.swift in Sources */, + D2CB6E2A27C50EAE00A62B57 /* RUMContextProvider.swift in Sources */, + D2CB6E2B27C50EAE00A62B57 /* RUMViewScope.swift in Sources */, + D2CB6E2C27C50EAE00A62B57 /* KronosNTPPacket.swift in Sources */, + D2CB6E2D27C50EAE00A62B57 /* CrashReportingFeature.swift in Sources */, + D2CB6E2E27C50EAE00A62B57 /* LaunchTimeProvider.swift in Sources */, + D2CB6E2F27C50EAE00A62B57 /* SpanTagsReducer.swift in Sources */, + D2CB6E3027C50EAE00A62B57 /* RUMApplicationScope.swift in Sources */, + D2CB6E3127C50EAE00A62B57 /* FileWriter.swift in Sources */, + D2CB6E3227C50EAE00A62B57 /* SwiftUIActionModifier.swift in Sources */, + D2CB6E3327C50EAE00A62B57 /* OTConstants.swift in Sources */, + D2CB6E3427C50EAE00A62B57 /* MobileDevice.swift in Sources */, + D2CB6E3527C50EAE00A62B57 /* SpanEventBuilder.swift in Sources */, + D2CB6E3627C50EAE00A62B57 /* ObjcAppLaunchHandler.m in Sources */, + D2CB6E3727C50EAE00A62B57 /* UIKitRUMUserActionsPredicate.swift in Sources */, + D2CB6E3827C50EAE00A62B57 /* DataFormat.swift in Sources */, + D2CB6E3927C50EAE00A62B57 /* JSONEncoder.swift in Sources */, + D2CB6E3A27C50EAE00A62B57 /* InternalMonitor.swift in Sources */, + D2CB6E3B27C50EAE00A62B57 /* CodableValue.swift in Sources */, + D2CB6E3C27C50EAE00A62B57 /* Retrying.swift in Sources */, + D2CB6E3D27C50EAE00A62B57 /* FeaturesConfiguration.swift in Sources */, + D2CB6E3E27C50EAE00A62B57 /* SpanEventMapper.swift in Sources */, + D2CB6E3F27C50EAE00A62B57 /* ConsentProvider.swift in Sources */, + D2CB6E4027C50EAE00A62B57 /* UIViewControllerSwizzler.swift in Sources */, + D2CB6E4127C50EAE00A62B57 /* RUMCurrentContext.swift in Sources */, + D2CB6E4227C50EAE00A62B57 /* RUMConnectivityInfoProvider.swift in Sources */, + D2CB6E4327C50EAE00A62B57 /* ObjcExceptionHandler.m in Sources */, + D2CB6E4427C50EAE00A62B57 /* UIApplicationSwizzler.swift in Sources */, + D2CB6E4527C50EAE00A62B57 /* RUMResourceScope.swift in Sources */, + D2CB6E4627C50EAE00A62B57 /* RUMSessionScope.swift in Sources */, + D2CB6E4727C50EAE00A62B57 /* TracingUUID.swift in Sources */, + D2CB6E4827C50EAE00A62B57 /* ServerDateProvider.swift in Sources */, + D2CB6E4927C50EAE00A62B57 /* AttributesSanitizer.swift in Sources */, + D2CB6E4A27C50EAE00A62B57 /* RUMEventOutput.swift in Sources */, + D2CB6E4B27C50EAE00A62B57 /* InternalMonitoringFeature.swift in Sources */, + D2CB6E4C27C50EAE00A62B57 /* RUMDataModelsMapping.swift in Sources */, + D2CB6E4D27C50EAE00A62B57 /* Globals.swift in Sources */, + D2CB6E4E27C50EAE00A62B57 /* ActiveSpansPool.swift in Sources */, + D2CB6E4F27C50EAE00A62B57 /* AppStateListener.swift in Sources */, + D2CB6E5027C50EAE00A62B57 /* UIViewControllerHandler.swift in Sources */, + D2CB6E5127C50EAE00A62B57 /* Warnings.swift in Sources */, + D2CB6E5227C50EAE00A62B57 /* DataMigrator.swift in Sources */, + D2CB6E5327C50EAE00A62B57 /* RUMUUIDGenerator.swift in Sources */, + D2CB6E5427C50EAE00A62B57 /* FirstPartyURLsFilter.swift in Sources */, + D2CB6E5527C50EAE00A62B57 /* KronosNSTimer+ClosureKit.swift in Sources */, + D2CB6E5627C50EAE00A62B57 /* TaskInterception.swift in Sources */, + D2CB6E5727C50EAE00A62B57 /* HTTPHeadersReader.swift in Sources */, + D2CB6E5827C50EAE00A62B57 /* SpanSanitizer.swift in Sources */, + D2CB6E5927C50EAE00A62B57 /* Writer.swift in Sources */, + D2CB6E5A27C50EAE00A62B57 /* URLSessionAutoInstrumentation.swift in Sources */, + D2CB6E5B27C50EAE00A62B57 /* DDSpanContext.swift in Sources */, + D2CB6E5C27C50EAE00A62B57 /* UIKitRUMUserActionsHandler.swift in Sources */, + D2CB6E5D27C50EAE00A62B57 /* RUMInstrumentation.swift in Sources */, + D2CB6E5E27C50EAE00A62B57 /* URLSessionRUMResourcesHandler.swift in Sources */, + D2CB6E5F27C50EAE00A62B57 /* RUMCommandSubscriber.swift in Sources */, + D2CB6E6027C50EAE00A62B57 /* CrashReportingIntegration.swift in Sources */, + D2CB6E6127C50EAE00A62B57 /* CrashReporter.swift in Sources */, + D2CB6E6227C50EAE00A62B57 /* LogEventSanitizer.swift in Sources */, + D2CB6E6327C50EAE00A62B57 /* UIKitExtensions.swift in Sources */, + D2CB6E6427C50EAE00A62B57 /* VitalCPUReader.swift in Sources */, + D2CB6E6527C50EAE00A62B57 /* Feature.swift in Sources */, + D2CB6E6627C50EAE00A62B57 /* Reader.swift in Sources */, + D2CB6E6727C50EAE00A62B57 /* DDURLSessionDelegate.swift in Sources */, + D2CB6E6827C50EAE00A62B57 /* SwiftExtensions.swift in Sources */, + D2CB6E6927C50EAE00A62B57 /* KronosDNSResolver.swift in Sources */, + D2CB6E6A27C50EAE00A62B57 /* InternalURLsFilter.swift in Sources */, + D2CB6E6B27C50EAE00A62B57 /* ValuePublisher.swift in Sources */, + D2CB6E6C27C50EAE00A62B57 /* KronosMonitor.swift in Sources */, + D2CB6E6D27C50EAE00A62B57 /* RUMUUID.swift in Sources */, + D2CB6E6E27C50EAE00A62B57 /* URLSessionInterceptor.swift in Sources */, + D2CB6E6F27C50EAE00A62B57 /* TracingHTTPHeaders.swift in Sources */, + D2CB6E7027C50EAE00A62B57 /* MethodSwizzler.swift in Sources */, + D2CB6E7127C50EAE00A62B57 /* LogConsoleOutput.swift in Sources */, + D2CB6E7227C50EAE00A62B57 /* SpanEventEncoder.swift in Sources */, + D2CB6E7327C50EAE00A62B57 /* Tracer.swift in Sources */, + D2CB6E7427C50EAE00A62B57 /* OTFormat.swift in Sources */, + D2CB6E7527C50EAE00A62B57 /* RUMDataModels.swift in Sources */, + D2CB6E7627C50EAE00A62B57 /* KronosClock.swift in Sources */, + D2CB6E7727C50EAE00A62B57 /* DataReader.swift in Sources */, + D2CB6E7827C50EAE00A62B57 /* DDRUMMonitor.swift in Sources */, + D2CB6E7927C50EAE00A62B57 /* UserInfoProvider.swift in Sources */, + D2CB6E7A27C50EAE00A62B57 /* WebEventBridge.swift in Sources */, + D2CB6E7B27C50EAE00A62B57 /* Datadog.swift in Sources */, + D2CB6E7C27C50EAE00A62B57 /* CarrierInfoProvider.swift in Sources */, + D2CB6E7D27C50EAE00A62B57 /* TracingFeature.swift in Sources */, + D2CB6E7E27C50EAE00A62B57 /* RUMMonitor.swift in Sources */, + D2CB6E7F27C50EAE00A62B57 /* LoggingWithRUMIntegration.swift in Sources */, + D2CB6E8027C50EAE00A62B57 /* WKUserContentController+Datadog.swift in Sources */, + D2CB6E8127C50EAE00A62B57 /* DataUploader.swift in Sources */, + D2CB6E8227C50EAE00A62B57 /* DeleteAllDataMigrator.swift in Sources */, + D2CB6E8327C50EAE00A62B57 /* RUMUserActionScope.swift in Sources */, + D2CB6E8427C50EAE00A62B57 /* DDNoopRUMMonitor.swift in Sources */, + D2CB6E8527C50EAE00A62B57 /* Casting.swift in Sources */, + D2CB6E8627C50EAE00A62B57 /* RUMScope.swift in Sources */, + D2CB6E8727C50EAE00A62B57 /* LogEventBuilder.swift in Sources */, + D2CB6E8827C50EAE00A62B57 /* FileReader.swift in Sources */, + D2CB6E8927C50EAE00A62B57 /* LongTaskObserver.swift in Sources */, + D2CB6E8A27C50EAE00A62B57 /* SpanFileOutput.swift in Sources */, + D2CB6E8B27C50EAE00A62B57 /* Attributes.swift in Sources */, + D2CB6E8C27C50EAE00A62B57 /* File.swift in Sources */, + D2CB6E8D27C50EAE00A62B57 /* KronosNTPProtocol.swift in Sources */, + D2CB6E8E27C50EAE00A62B57 /* DDCrashReportingPluginType.swift in Sources */, + D2CB6E8F27C50EAE00A62B57 /* CrashReportingWithLoggingIntegration.swift in Sources */, + D2CB6E9027C50EAE00A62B57 /* CrashContext.swift in Sources */, + D2CB6E9127C50EAE00A62B57 /* KronosTimeFreeze.swift in Sources */, + D2CB6E9227C50EAE00A62B57 /* DateFormatting.swift in Sources */, + D2CB6E9327C50EAE00A62B57 /* LogUtilityOutputs.swift in Sources */, + D2CB6E9427C50EAE00A62B57 /* RequestBuilder.swift in Sources */, + D2CB6E9527C50EAE00A62B57 /* RUMContext.swift in Sources */, + D2CB6E9627C50EAE00A62B57 /* RUMOffViewEventsHandlingRule.swift in Sources */, + D2CB6E9727C50EAE00A62B57 /* DataUploadStatus.swift in Sources */, + D2CB6E9827C50EAE00A62B57 /* LogFileOutput.swift in Sources */, + D2CB6E9927C50EAE00A62B57 /* DataUploadWorker.swift in Sources */, + D2CB6E9A27C50EAE00A62B57 /* KronosTimeStorage.swift in Sources */, + D2CB6E9B27C50EAE00A62B57 /* FilesOrchestrator.swift in Sources */, + D2CB6E9C27C50EAE00A62B57 /* NetworkConnectionInfoProvider.swift in Sources */, + D2CB6E9D27C50EAE00A62B57 /* RUMEventFileOutput.swift in Sources */, + D2CB6E9E27C50EAE00A62B57 /* RUMDebugging.swift in Sources */, + D2CB6E9F27C50EAE00A62B57 /* DataCompression.swift in Sources */, + D2CB6EA027C50EAE00A62B57 /* SpanOutput.swift in Sources */, + D2CB6EA127C50EAE00A62B57 /* LogEventEncoder.swift in Sources */, + D2CB6EA227C50EAE00A62B57 /* VitalInfo.swift in Sources */, + D2CB6EA327C50EAE00A62B57 /* RUMEventsMapper.swift in Sources */, + D2CB6EA427C50EAE00A62B57 /* RUMIntegrations.swift in Sources */, + D2CB6EA527C50EAE00A62B57 /* DDSpan.swift in Sources */, + D2CB6EA627C50EAE00A62B57 /* RUMEventBuilder.swift in Sources */, + D2CB6EA727C50EAE00A62B57 /* Versioning.swift in Sources */, + D2CB6EA827C50EAE00A62B57 /* HTTPClient.swift in Sources */, + D2CB6EA927C50EAE00A62B57 /* LogEventMapper.swift in Sources */, + D2CB6EAA27C50EAE00A62B57 /* URLSessionSwizzler.swift in Sources */, + D2CB6EAB27C50EAE00A62B57 /* VitalMemoryReader.swift in Sources */, + D2CB6EAC27C50EAE00A62B57 /* DatadogConfiguration.swift in Sources */, + D2CB6EAD27C50EAE00A62B57 /* DataProcessor.swift in Sources */, + D2CB6EAE27C50EAE00A62B57 /* DataOrchestrator.swift in Sources */, + D2CB6EAF27C50EAE00A62B57 /* BundleType.swift in Sources */, + D2CB6EB027C50EAE00A62B57 /* UIKitRUMViewsPredicate.swift in Sources */, + D2CB6EB127C50EAE00A62B57 /* BatteryStatusProvider.swift in Sources */, + D2CB6EB227C50EAE00A62B57 /* Sampler.swift in Sources */, + D2CB6EB327C50EAE00A62B57 /* KronosNTPClient.swift in Sources */, + D2CB6EB427C50EAE00A62B57 /* VitalInfoSampler.swift in Sources */, + D2CB6EB527C50EAE00A62B57 /* VitalRefreshRateReader.swift in Sources */, + D2CB6EB627C50EAE00A62B57 /* (null) in Sources */, + D2CB6EB727C50EAE00A62B57 /* URLSessionTracingHandler.swift in Sources */, + D2CB6EB827C50EAE00A62B57 /* RUMEventSanitizer.swift in Sources */, + D2CB6EB927C50EAE00A62B57 /* DDError.swift in Sources */, + D2CB6EBA27C50EAE00A62B57 /* DataUploadConditions.swift in Sources */, + D2CB6EBB27C50EAE00A62B57 /* LoggingFeature.swift in Sources */, + D2CB6EBC27C50EAE00A62B57 /* RUMCommand.swift in Sources */, + D2CB6EBD27C50EAE00A62B57 /* LogOutput.swift in Sources */, + D2CB6EBE27C50EAE00A62B57 /* DDNoOps.swift in Sources */, + D2CB6EBF27C50EAE00A62B57 /* KronosData+Bytes.swift in Sources */, + D2CB6EC027C50EAE00A62B57 /* RUMFeature.swift in Sources */, + D2CB6EC127C50EAE00A62B57 /* TracingWithRUMIntegration.swift in Sources */, + D2CB6EC227C50EAE00A62B57 /* ConsentAwareDataWriter.swift in Sources */, + D2CB6EC327C50EAE00A62B57 /* TracingUUIDGenerator.swift in Sources */, + D2CB6EC427C50EAE00A62B57 /* DataUploadDelay.swift in Sources */, + D2CB6EC527C50EAE00A62B57 /* HostsSanitizer.swift in Sources */, + D2CB6EC627C50EAE00A62B57 /* HTTPHeadersWriter.swift in Sources */, + D2CB6EC727C50EAE00A62B57 /* PerformancePreset.swift in Sources */, + D2CB6EC827C50EAE00A62B57 /* RUMUserInfoProvider.swift in Sources */, + D2CB6EC927C50EAE00A62B57 /* Directory.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6ED627C520D400A62B57 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D2CB6ED727C520D400A62B57 /* URLSessionSwizzlerTests.swift in Sources */, + D2CB6ED827C520D400A62B57 /* RUMUserActionScopeTests.swift in Sources */, + D2CB6ED927C520D400A62B57 /* RUMViewsHandlerTests.swift in Sources */, + D2CB6EDA27C520D400A62B57 /* Casting+Tracing.swift in Sources */, + D2CB6EDB27C520D400A62B57 /* LogSanitizerTests.swift in Sources */, + D2CB6EDC27C520D400A62B57 /* ConsentAwareDataWriterTests.swift in Sources */, + D2CB6EDD27C520D400A62B57 /* UIApplicationSwizzlerTests.swift in Sources */, + D2CB6EDE27C520D400A62B57 /* RUMEventMatcher.swift in Sources */, + D2CB6EDF27C520D400A62B57 /* RUMSessionScopeTests.swift in Sources */, + D2CB6EE027C520D400A62B57 /* SpanMatcher.swift in Sources */, + D2DC4BBD27F234E000E4FB96 /* CITestIntegrationTests.swift in Sources */, + D2CB6EE127C520D400A62B57 /* RUMWithCrashContextIntegrationTests.swift in Sources */, + D2CB6EE227C520D400A62B57 /* ServerMock.swift in Sources */, + D2CB6EE327C520D400A62B57 /* RUMViewScopeTests.swift in Sources */, + D2CB6EE427C520D400A62B57 /* FeatureTests.swift in Sources */, + D2CB6EE527C520D400A62B57 /* DataUploadConditionsTests.swift in Sources */, + D2CB6EE627C520D400A62B57 /* DateFormattingTests.swift in Sources */, + D2CB6EE727C520D400A62B57 /* FileTests.swift in Sources */, + D2CB6EE827C520D400A62B57 /* TracingFeatureTests.swift in Sources */, + D2CB6EE927C520D400A62B57 /* SamplerTests.swift in Sources */, + D2CB6EEA27C520D400A62B57 /* LogMatcher.swift in Sources */, + D2CB6EEB27C520D400A62B57 /* DataCompressionTests.swift in Sources */, + D2CB6EEC27C520D400A62B57 /* CustomObjcViewController.m in Sources */, + D2CB6EED27C520D400A62B57 /* RUMIntegrationsTests.swift in Sources */, + D2CB6EEE27C520D400A62B57 /* DDErrorTests.swift in Sources */, + D2CB6EEF27C520D400A62B57 /* Casting+RUM.swift in Sources */, + D2CB6EF027C520D400A62B57 /* InternalLoggersTests.swift in Sources */, + D2CB6EF127C520D400A62B57 /* RUMEventFileOutputTests.swift in Sources */, + D2CB6EF227C520D400A62B57 /* KronosTimeStorageTests.swift in Sources */, + D2CB6EF327C520D400A62B57 /* VitalRefreshRateReaderTests.swift in Sources */, + D2CB6EF427C520D400A62B57 /* FileWriterTests.swift in Sources */, + D2CB6EF527C520D400A62B57 /* TracerConfigurationTests.swift in Sources */, + D2CB6EF627C520D400A62B57 /* DDSpanTests.swift in Sources */, + D2CB6EF727C520D400A62B57 /* URLSessionAutoInstrumentationMocks.swift in Sources */, + D2CB6EF827C520D400A62B57 /* LogConsoleOutputTests.swift in Sources */, + D2CB6EF927C520D400A62B57 /* WebRUMEventConsumerTests.swift in Sources */, + D2CB6EFA27C520D400A62B57 /* FeatureDirectoriesMock.swift in Sources */, + D2CB6EFB27C520D400A62B57 /* SpanSanitizerTests.swift in Sources */, + D2CB6EFC27C520D400A62B57 /* DDGlobal+apiTests.m in Sources */, + D2CB6EFD27C520D400A62B57 /* LoggingFeatureMocks.swift in Sources */, + D2CB6EFE27C520D400A62B57 /* RUMMonitorConfigurationTests.swift in Sources */, + D2CB6EFF27C520D400A62B57 /* AttributesMocks.swift in Sources */, + D2CB6F0027C520D400A62B57 /* RUMSessionMatcher.swift in Sources */, + D2CB6F0127C520D400A62B57 /* DatadogPrivateMocks.swift in Sources */, + D2CB6F0227C520D400A62B57 /* TracingFeatureMocks.swift in Sources */, + D2CB6F0327C520D400A62B57 /* WKUserContentController+DatadogTests.swift in Sources */, + D2CB6F0427C520D400A62B57 /* DDTracerTests.swift in Sources */, + D2CB6F0527C520D400A62B57 /* DDTracerConfigurationTests.swift in Sources */, + D2CB6F0627C520D400A62B57 /* RUMEventsMapperTests.swift in Sources */, + D2CB6F0727C520D400A62B57 /* MoveDataMigratorTests.swift in Sources */, + D2CB6F0827C520D400A62B57 /* DDSpanContextTests.swift in Sources */, + D2CB6F0927C520D400A62B57 /* RUMDataModels+objcTests.swift in Sources */, + D2CB6F0A27C520D400A62B57 /* UIKitRUMUserActionsHandlerTests.swift in Sources */, + D2CB6F0B27C520D400A62B57 /* CodableValueTests.swift in Sources */, + D2CB6F0C27C520D400A62B57 /* KronosNTPPacketTests.swift in Sources */, + D2CB6F0D27C520D400A62B57 /* NetworkConnectionInfoProviderTests.swift in Sources */, + D2CB6F0E27C520D400A62B57 /* DDRUMMonitorTests.swift in Sources */, + D2CB6F0F27C520D400A62B57 /* VitalMemoryReaderTests.swift in Sources */, + D2CB6F1027C520D400A62B57 /* DDNSURLSessionDelegateTests.swift in Sources */, + D2CB6F1127C520D400A62B57 /* CrashReportingWithRUMIntegrationTests.swift in Sources */, + D2CB6F1227C520D400A62B57 /* LoggerBuilderTests.swift in Sources */, + D2CB6F1327C520D400A62B57 /* DDConfigurationTests.swift in Sources */, + D2CB6F1427C520D400A62B57 /* UUID.swift in Sources */, + D2CB6F1527C520D400A62B57 /* URLSessionRUMResourcesHandlerTests.swift in Sources */, + D2CB6F1627C520D400A62B57 /* URLSessionInterceptorTests.swift in Sources */, + D2CB6F1727C520D400A62B57 /* ObjcExceptionHandlerTests.swift in Sources */, + D2CB6F1827C520D400A62B57 /* DatadogTestsObserver.swift in Sources */, + D2CB6F1927C520D400A62B57 /* RequestBuilderTests.swift in Sources */, + D2CB6F1A27C520D400A62B57 /* FileReaderTests.swift in Sources */, + D2CB6F1B27C520D400A62B57 /* RUMOffViewEventsHandlingRuleTests.swift in Sources */, + D2CB6F1C27C520D400A62B57 /* DDNoopRUMMonitorTests.swift in Sources */, + D2CB6F1D27C520D400A62B57 /* DataUploaderTests.swift in Sources */, + D2CB6F1E27C520D400A62B57 /* DataUploadWorkerMock.swift in Sources */, + D2CB6F1F27C520D400A62B57 /* XCTestCase.swift in Sources */, + D2CB6F2027C520D400A62B57 /* FeaturesConfigurationTests.swift in Sources */, + D2CB6F2127C520D400A62B57 /* HTTPClientTests.swift in Sources */, + D2CB6F2227C520D400A62B57 /* DatadogTests.swift in Sources */, + D2CB6F2327C520D400A62B57 /* WebEventBridgeTests.swift in Sources */, + D2CB6F2427C520D400A62B57 /* DDURLSessionDelegateTests.swift in Sources */, + D2CB6F2527C520D400A62B57 /* EquatableInTests.swift in Sources */, + D2CB6F2627C520D400A62B57 /* DataUploadDelayTests.swift in Sources */, + D2CB6F2727C520D400A62B57 /* FirstPartyURLsFilterTests.swift in Sources */, + D2CB6F2827C520D400A62B57 /* DataUploadWorkerTests.swift in Sources */, + D2CB6F2927C520D400A62B57 /* DDGlobalTests.swift in Sources */, + D2CB6F2A27C520D400A62B57 /* GlobalTests.swift in Sources */, + D2CB6F2B27C520D400A62B57 /* CrashContextProviderTests.swift in Sources */, + D2CB6F2C27C520D400A62B57 /* JSONEncoderTests.swift in Sources */, + D2CB6F2D27C520D400A62B57 /* LogFileOutputTests.swift in Sources */, + D2CB6F2E27C520D400A62B57 /* RUMCommandTests.swift in Sources */, + D2CB6F2F27C520D400A62B57 /* LogUtilityOutputsTests.swift in Sources */, + D2CB6F3027C520D400A62B57 /* DatadogExtensions.swift in Sources */, + D2CB6F3127C520D400A62B57 /* InternalMonitoringFeatureMocks.swift in Sources */, + D2CB6F3227C520D400A62B57 /* JSONDataMatcher.swift in Sources */, + D2CB6F3327C520D400A62B57 /* FilesOrchestratorTests.swift in Sources */, + D2CB6F3427C520D400A62B57 /* TracingUUIDGeneratorTests.swift in Sources */, + D2CB6F3527C520D400A62B57 /* MethodSwizzlerTests.swift in Sources */, + D2CB6F3627C520D400A62B57 /* TaskInterceptionTests.swift in Sources */, + D2CB6F3727C520D400A62B57 /* LoggingFeatureTests.swift in Sources */, + D2CB6F3827C520D400A62B57 /* RUMFeatureMocks.swift in Sources */, + D2CB6F3927C520D400A62B57 /* TestsDirectory.swift in Sources */, + D2CB6F3A27C520D400A62B57 /* SwiftExtensions.swift in Sources */, + D2CB6F3B27C520D400A62B57 /* NSURLSessionBridge.m in Sources */, + D2CB6F3C27C520D400A62B57 /* VitalInfoSamplerTests.swift in Sources */, + D2CB6F3D27C520D400A62B57 /* RUMViewIdentityTests.swift in Sources */, + D2CB6F3E27C520D400A62B57 /* DataOrchestratorTests.swift in Sources */, + D2CB6F3F27C520D400A62B57 /* RUMDataModelMocks.swift in Sources */, + D2CB6F4027C520D400A62B57 /* DDLoggerBuilderTests.swift in Sources */, + D2CB6F4127C520D400A62B57 /* VitalInfoTests.swift in Sources */, + D2CB6F4227C520D400A62B57 /* DDNoopTracerTests.swift in Sources */, + D2CB6F4327C520D400A62B57 /* DDLoggerTests.swift in Sources */, + D2CB6F4427C520D400A62B57 /* RUMDataModelsMappingTests.swift in Sources */, + D2CB6F4527C520D400A62B57 /* TracerTests.swift in Sources */, + D2CB6F4627C520D400A62B57 /* CoreMocks.swift in Sources */, + D2CB6F4727C520D400A62B57 /* SpanEventBuilderTests.swift in Sources */, + D2CB6F4827C520D400A62B57 /* CrashReportingFeatureMocks.swift in Sources */, + D2CB6F4927C520D400A62B57 /* CrashReportingWithLoggingIntegrationTests.swift in Sources */, + D2CB6F4A27C520D400A62B57 /* DateCorrectionTests.swift in Sources */, + D2CB6F4B27C520D400A62B57 /* DeleteAllDataMigratorTests.swift in Sources */, + D2CB6F4C27C520D400A62B57 /* TracingUUIDTests.swift in Sources */, + D2CB6F4D27C520D400A62B57 /* DataUploadStatusTests.swift in Sources */, + D2CB6F4E27C520D400A62B57 /* LaunchTimeProviderTests.swift in Sources */, + D2CB6F4F27C520D400A62B57 /* RetryingTests.swift in Sources */, + D2CB6F5027C520D400A62B57 /* DDDatadogTests.swift in Sources */, + D2CB6F5127C520D400A62B57 /* URLSessionAutoInstrumentationTests.swift in Sources */, + D2CB6F5227C520D400A62B57 /* FoundationMocks.swift in Sources */, + D2CB6F5327C520D400A62B57 /* DirectoryTests.swift in Sources */, + D2CB6F5427C520D400A62B57 /* RUMFeatureTests.swift in Sources */, + D2CB6F5527C520D400A62B57 /* ActiveSpansPoolTests.swift in Sources */, + D2CB6F5627C520D400A62B57 /* InternalURLsFilterTests.swift in Sources */, + D2CB6F5727C520D400A62B57 /* CarrierInfoProviderTests.swift in Sources */, + D2CB6F5827C520D400A62B57 /* RUMScopeTests.swift in Sources */, + D2CB6F5927C520D400A62B57 /* WarningsTests.swift in Sources */, + D2CB6F5A27C520D400A62B57 /* SwiftExtensionsTests.swift in Sources */, + D2CB6F5B27C520D400A62B57 /* RUMEventSanitizerTests.swift in Sources */, + D2CB6F5C27C520D400A62B57 /* RUMConnectivityInfoProviderTests.swift in Sources */, + D2CB6F5D27C520D400A62B57 /* UIKitRUMViewsPredicateTests.swift in Sources */, + D2CB6F5E27C520D400A62B57 /* LogBuilderTests.swift in Sources */, + D2CB6F5F27C520D400A62B57 /* DDNSURLSessionDelegate+apiTests.m in Sources */, + D2CB6F6027C520D400A62B57 /* DatadogConfigurationBuilderTests.swift in Sources */, + D2CB6F6127C520D400A62B57 /* Encoding.swift in Sources */, + D2CB6F6227C520D400A62B57 /* WebLogEventConsumerTests.swift in Sources */, + D2CB6F6327C520D400A62B57 /* ConsentProviderTests.swift in Sources */, + D2CB6F6427C520D400A62B57 /* LoggerTests.swift in Sources */, + D2CB6F6527C520D400A62B57 /* KronosMonitorTests.swift in Sources */, + D2CB6F6627C520D400A62B57 /* RUMMonitorTests.swift in Sources */, + D2CB6F6727C520D400A62B57 /* HostsSanitizerTests.swift in Sources */, + D2CB6F6827C520D400A62B57 /* SwiftUIExtensionsTests.swift in Sources */, + D2CB6F6927C520D400A62B57 /* InternalMonitoringFeatureTests.swift in Sources */, + D2CB6F6A27C520D400A62B57 /* DDRUMMonitor+apiTests.m in Sources */, + D2CB6F6B27C520D400A62B57 /* RUMDebuggingTests.swift in Sources */, + D2CB6F6C27C520D400A62B57 /* RUMInstrumentationTests.swift in Sources */, + D2CB6F6D27C520D400A62B57 /* RUMCurrentContextTests.swift in Sources */, + D2CB6F6E27C520D400A62B57 /* SpanFileOutputTests.swift in Sources */, + D2CB6F6F27C520D400A62B57 /* RUMResourceScopeTests.swift in Sources */, + D2CB6F7027C520D400A62B57 /* UIKitMocks.swift in Sources */, + D2CB6F7127C520D400A62B57 /* URLSessionTracingHandlerTests.swift in Sources */, + D2CB6F7227C520D400A62B57 /* ValuePublisherTests.swift in Sources */, + D2CB6F7327C520D400A62B57 /* CoreTelephonyMocks.swift in Sources */, + D2CB6F7427C520D400A62B57 /* VitalCPUReaderTests.swift in Sources */, + D2CB6F7527C520D400A62B57 /* UIKitExtensionsTests.swift in Sources */, + D2CB6F7627C520D400A62B57 /* RUMUserInfoProviderTests.swift in Sources */, + D2CB6F7727C520D400A62B57 /* DDURLSessionDelegateAsSuperclassTests.swift in Sources */, + D2CB6F7827C520D400A62B57 /* BatteryStatusProviderTests.swift in Sources */, + D2CB6F7927C520D400A62B57 /* UIViewControllerSwizzlerTests.swift in Sources */, + D2CB6F7A27C520D400A62B57 /* AppStateListenerTests.swift in Sources */, + D2CB6F7B27C520D400A62B57 /* RUMApplicationScopeTests.swift in Sources */, + D2CB6F7C27C520D400A62B57 /* CrashReporterTests.swift in Sources */, + D2CB6F7D27C520D400A62B57 /* CrashContextTests.swift in Sources */, + D2CB6F7E27C520D400A62B57 /* OTSpanTests.swift in Sources */, + D2CB6F7F27C520D400A62B57 /* DDDatadog+apiTests.m in Sources */, + D2CB6F8027C520D400A62B57 /* LoggingForTracingAdapterTests.swift in Sources */, + D2CB6F8127C520D400A62B57 /* MobileDeviceTests.swift in Sources */, + D2CB6F8227C520D400A62B57 /* RUMEventBuilderTests.swift in Sources */, + D2CB6F8327C520D400A62B57 /* DDConfiguration+apiTests.m in Sources */, + D2CB6F8427C520D400A62B57 /* DatadogTestsObserverLoader.m in Sources */, + D2CB6F8527C520D400A62B57 /* PerformancePresetTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6F9727C5217A00A62B57 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D2CB6F9827C5217A00A62B57 /* AnyEncodable.swift in Sources */, + D2CB6F9927C5217A00A62B57 /* Casting.swift in Sources */, + D2CB6F9A27C5217A00A62B57 /* RUMDataModels+objc.swift in Sources */, + D2CB6F9B27C5217A00A62B57 /* DDSpanContext+objc.swift in Sources */, + D2CB6F9C27C5217A00A62B57 /* OTTracer+objc.swift in Sources */, + D2CB6F9D27C5217A00A62B57 /* TracerConfiguration+objc.swift in Sources */, + D2CB6F9E27C5217A00A62B57 /* Datadog+objc.swift in Sources */, + D2CB6F9F27C5217A00A62B57 /* Logger+objc.swift in Sources */, + D2CB6FA027C5217A00A62B57 /* Tracer+objc.swift in Sources */, + D2CB6FA127C5217A00A62B57 /* HTTPHeadersWriter+objc.swift in Sources */, + D2CB6FA227C5217A00A62B57 /* DDSpan+objc.swift in Sources */, + D2CB6FA327C5217A00A62B57 /* OTSpan+objc.swift in Sources */, + D2CB6FA427C5217A00A62B57 /* DDURLSessionDelegate+objc.swift in Sources */, + D2CB6FA527C5217A00A62B57 /* RUMMonitor+objc.swift in Sources */, + D2CB6FA627C5217A00A62B57 /* OTSpanContext+objc.swift in Sources */, + D2CB6FA727C5217A00A62B57 /* Global+objc.swift in Sources */, + D2CB6FA827C5217A00A62B57 /* DatadogConfiguration+objc.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6FBF27C5348200A62B57 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D2CB6FC027C5348200A62B57 /* DDCrashReportBuilder.swift in Sources */, + D2CB6FC127C5348200A62B57 /* DDCrashReportExporter.swift in Sources */, + D2CB6FC227C5348200A62B57 /* CrashReportMinifier.swift in Sources */, + D2CB6FC327C5348200A62B57 /* PLCrashReporterIntegration.swift in Sources */, + D2CB6FC427C5348200A62B57 /* CrashReport.swift in Sources */, + D2CB6FC527C5348200A62B57 /* SwiftExtensions.swift in Sources */, + D2CB6FC627C5348200A62B57 /* DDCrashReportingPlugin.swift in Sources */, + D2CB6FC727C5348200A62B57 /* ThirdPartyCrashReporter.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6FD827C5352300A62B57 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D2CB6FD927C5352300A62B57 /* DDCrashReportBuilderTests.swift in Sources */, + D2CB6FDA27C5352300A62B57 /* FoundationMocks.swift in Sources */, + D2CB6FDB27C5352300A62B57 /* SwiftExtensionTests.swift in Sources */, + D2CB6FDC27C5352300A62B57 /* PLCrashReporterIntegrationTests.swift in Sources */, + D2CB6FDD27C5352300A62B57 /* CrashReportMinifierTests.swift in Sources */, + D2CB6FDE27C5352300A62B57 /* DDCrashReportExporterTests.swift in Sources */, + D2CB6FDF27C5352300A62B57 /* EquatableInTests.swift in Sources */, + D2CB6FE027C5352300A62B57 /* DDCrashReportingPluginTests.swift in Sources */, + D2CB6FE127C5352300A62B57 /* CrashReportTests.swift in Sources */, + D2CB6FE227C5352300A62B57 /* Mocks.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 61133C732423993200786299 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61133B81242393DE00786299 /* Datadog */; + target = 61133B81242393DE00786299 /* Datadog iOS */; targetProxy = 61133C722423993200786299 /* PBXContainerItemProxy */; }; 61441C3024616F1D003D8BB8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61441C0124616DE9003D8BB8 /* Example */; + target = 61441C0124616DE9003D8BB8 /* Example iOS */; targetProxy = 61441C2F24616F1D003D8BB8 /* PBXContainerItemProxy */; }; - 61441C5024619499003D8BB8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 61133B81242393DE00786299 /* Datadog */; - targetProxy = 61441C4F24619499003D8BB8 /* PBXContainerItemProxy */; - }; 61441C5A24619A08003D8BB8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61441C0124616DE9003D8BB8 /* Example */; + target = 61441C0124616DE9003D8BB8 /* Example iOS */; targetProxy = 61441C5924619A08003D8BB8 /* PBXContainerItemProxy */; }; 61441C7524619FED003D8BB8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61441C0124616DE9003D8BB8 /* Example */; + target = 61441C0124616DE9003D8BB8 /* Example iOS */; targetProxy = 61441C7424619FED003D8BB8 /* PBXContainerItemProxy */; }; - 614ED39D260357FA00C8C519 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 61B7885325C180CB002675B5 /* DatadogCrashReporting */; - targetProxy = 614ED39C260357FA00C8C519 /* PBXContainerItemProxy */; - }; - 6170DC5325C18E57003AED5C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 61B7885325C180CB002675B5 /* DatadogCrashReporting */; - targetProxy = 6170DC5225C18E57003AED5C /* PBXContainerItemProxy */; - }; 618F9846265BC486009959F8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 6199362A265BA958009D7EA8 /* E2E */; @@ -4745,12 +5993,12 @@ }; 61993659265BB6A6009D7EA8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61133B81242393DE00786299 /* Datadog */; + target = 61133B81242393DE00786299 /* Datadog iOS */; targetProxy = 61993658265BB6A6009D7EA8 /* PBXContainerItemProxy */; }; 6199365D265BB6A6009D7EA8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61B7885325C180CB002675B5 /* DatadogCrashReporting */; + target = 61B7885325C180CB002675B5 /* DatadogCrashReporting iOS */; targetProxy = 6199365C265BB6A6009D7EA8 /* PBXContainerItemProxy */; }; 6199366B265BBEDC009D7EA8 /* PBXTargetDependency */ = { @@ -4760,42 +6008,82 @@ }; 61B7885F25C180CB002675B5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61B7885325C180CB002675B5 /* DatadogCrashReporting */; + target = 61B7885325C180CB002675B5 /* DatadogCrashReporting iOS */; targetProxy = 61B7885E25C180CB002675B5 /* PBXContainerItemProxy */; }; 61B7888025C18147002675B5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61441C0124616DE9003D8BB8 /* Example */; + target = 61441C0124616DE9003D8BB8 /* Example iOS */; targetProxy = 61B7887F25C18147002675B5 /* PBXContainerItemProxy */; }; 61DE335825C82941008E3EC2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61133B81242393DE00786299 /* Datadog */; + target = 61133B81242393DE00786299 /* Datadog iOS */; targetProxy = 61DE335725C82941008E3EC2 /* PBXContainerItemProxy */; }; + D240685727CF5D0100C04F44 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2CB6E0A27C50EAE00A62B57 /* Datadog tvOS */; + targetProxy = D240685627CF5D0100C04F44 /* PBXContainerItemProxy */; + }; + D240685B27CF5D0100C04F44 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2CB6FBA27C5348200A62B57 /* DatadogCrashReporting tvOS */; + targetProxy = D240685A27CF5D0100C04F44 /* PBXContainerItemProxy */; + }; + D240686227CF5D0100C04F44 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2CB6F9227C5217A00A62B57 /* DatadogObjc tvOS */; + targetProxy = D240686127CF5D0100C04F44 /* PBXContainerItemProxy */; + }; + D240686B27CF686F00C04F44 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D24067F827CE6C9E00C04F44 /* Example tvOS */; + targetProxy = D240686A27CF686F00C04F44 /* PBXContainerItemProxy */; + }; + D240686D27CF687200C04F44 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D24067F827CE6C9E00C04F44 /* Example tvOS */; + targetProxy = D240686C27CF687200C04F44 /* PBXContainerItemProxy */; + }; + D28D5D5427C53A60008E72D0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2CB6FBA27C5348200A62B57 /* DatadogCrashReporting tvOS */; + targetProxy = D28D5D5327C53A60008E72D0 /* PBXContainerItemProxy */; + }; + D2CB6FB627C5234300A62B57 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2CB6E0A27C50EAE00A62B57 /* Datadog tvOS */; + targetProxy = D2CB6FB527C5234300A62B57 /* PBXContainerItemProxy */; + }; + D2CB6FF127C5365A00A62B57 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2CB6E0A27C50EAE00A62B57 /* Datadog tvOS */; + targetProxy = D2CB6FF027C5365A00A62B57 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ - 61441C0A24616DE9003D8BB8 /* Main.storyboard */ = { + 61441C0A24616DE9003D8BB8 /* Main iOS.storyboard */ = { isa = PBXVariantGroup; children = ( 61441C0B24616DE9003D8BB8 /* Base */, ); - name = Main.storyboard; + name = "Main iOS.storyboard"; sourceTree = ""; }; - 61441C0F24616DEC003D8BB8 /* LaunchScreen.storyboard */ = { + 61993638265BA95A009D7EA8 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( - 61441C1024616DEC003D8BB8 /* Base */, + 61993639265BA95A009D7EA8 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; - 61993638265BA95A009D7EA8 /* LaunchScreen.storyboard */ = { + D240688427CFA64A00C04F44 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( - 61993639265BA95A009D7EA8 /* Base */, + D240688527CFA64A00C04F44 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; @@ -4854,13 +6142,13 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TVOS_DEPLOYMENT_TARGET = 11.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -4911,12 +6199,12 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; + TVOS_DEPLOYMENT_TARGET = 11.0; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -4944,7 +6232,7 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.Datadog; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(DD_SWIFT_SDK_PRODUCT_NAME)"; SKIP_INSTALL = YES; SUPPORTS_MACCATALYST = NO; SWIFT_VERSION = 5.0; @@ -4973,7 +6261,7 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.Datadog; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(DD_SWIFT_SDK_PRODUCT_NAME)"; SKIP_INSTALL = YES; SUPPORTS_MACCATALYST = NO; SWIFT_VERSION = 5.0; @@ -4995,12 +6283,12 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogTests; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = "$(DD_SWIFT_SDK_PRODUCT_NAME)Tests"; SUPPORTS_MACCATALYST = NO; SWIFT_OBJC_BRIDGING_HEADER = "TargetSupport/DatadogTests/DatadogTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example iOS.app/Example iOS"; }; name = Debug; }; @@ -5018,11 +6306,11 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogTests; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = "$(DD_SWIFT_SDK_PRODUCT_NAME)Tests"; SUPPORTS_MACCATALYST = NO; SWIFT_OBJC_BRIDGING_HEADER = "TargetSupport/DatadogTests/DatadogTests-Bridging-Header.h"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example iOS.app/Example iOS"; }; name = Release; }; @@ -5047,7 +6335,7 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogObjc; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(DD_OBJC_SDK_PRODUCT_NAME)"; SKIP_INSTALL = YES; SUPPORTS_MACCATALYST = NO; SWIFT_VERSION = 5.0; @@ -5076,7 +6364,7 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogObjc; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(DD_OBJC_SDK_PRODUCT_NAME)"; SKIP_INSTALL = YES; SUPPORTS_MACCATALYST = NO; SWIFT_VERSION = 5.0; @@ -5097,6 +6385,7 @@ "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.Example; + PRODUCT_MODULE_NAME = Example; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "TargetSupport/Example/Example-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -5118,6 +6407,7 @@ "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.Example; + PRODUCT_MODULE_NAME = Example; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "TargetSupport/Example/Example-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -5138,6 +6428,7 @@ "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.Example; + PRODUCT_MODULE_NAME = Example; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "TargetSupport/Example/Example-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -5160,7 +6451,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG DD_COMPILED_FOR_INTEGRATION_TESTS"; SWIFT_VERSION = 5.0; - TEST_TARGET_NAME = Example; + TEST_TARGET_NAME = "Example iOS"; VALIDATE_WORKSPACE = YES; }; name = Debug; @@ -5180,7 +6471,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DD_COMPILED_FOR_INTEGRATION_TESTS; SWIFT_VERSION = 5.0; - TEST_TARGET_NAME = Example; + TEST_TARGET_NAME = "Example iOS"; VALIDATE_WORKSPACE = YES; }; name = Release; @@ -5200,7 +6491,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DD_COMPILED_FOR_INTEGRATION_TESTS; SWIFT_VERSION = 5.0; - TEST_TARGET_NAME = Example; + TEST_TARGET_NAME = "Example iOS"; VALIDATE_WORKSPACE = YES; }; name = Integration; @@ -5219,7 +6510,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogBenchmarkTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example iOS.app/Example iOS"; }; name = Debug; }; @@ -5237,7 +6528,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogBenchmarkTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example iOS.app/Example iOS"; }; name = Release; }; @@ -5255,7 +6546,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogBenchmarkTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example iOS.app/Example iOS"; }; name = Integration; }; @@ -5461,7 +6752,7 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReporting; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(DD_CR_SDK_PRODUCT_NAME)"; SKIP_INSTALL = YES; SUPPORTS_MACCATALYST = NO; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -5492,7 +6783,7 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReporting; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(DD_CR_SDK_PRODUCT_NAME)"; SKIP_INSTALL = YES; SUPPORTS_MACCATALYST = NO; SWIFT_VERSION = 5.0; @@ -5522,7 +6813,7 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReporting; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(DD_CR_SDK_PRODUCT_NAME)"; SKIP_INSTALL = YES; SUPPORTS_MACCATALYST = NO; SWIFT_VERSION = 5.0; @@ -5543,9 +6834,9 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReportingTests; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = "$(DD_CR_SDK_PRODUCT_NAME)Tests"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example iOS.app/Example iOS"; }; name = Debug; }; @@ -5562,9 +6853,9 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReportingTests; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = "$(DD_CR_SDK_PRODUCT_NAME)Tests"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example iOS.app/Example iOS"; }; name = Release; }; @@ -5581,9 +6872,9 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReportingTests; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = "$(DD_CR_SDK_PRODUCT_NAME)Tests"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example iOS.app/Example iOS"; }; name = Integration; }; @@ -5633,12 +6924,12 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 11.0; - MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; + TVOS_DEPLOYMENT_TARGET = 11.0; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -5666,7 +6957,7 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.Datadog; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(DD_SWIFT_SDK_PRODUCT_NAME)"; SKIP_INSTALL = YES; SUPPORTS_MACCATALYST = NO; SWIFT_VERSION = 5.0; @@ -5695,7 +6986,7 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogObjc; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = "$(DD_OBJC_SDK_PRODUCT_NAME)"; SKIP_INSTALL = YES; SUPPORTS_MACCATALYST = NO; SWIFT_VERSION = 5.0; @@ -5717,60 +7008,525 @@ "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogTests; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = "$(DD_SWIFT_SDK_PRODUCT_NAME)Tests"; SUPPORTS_MACCATALYST = NO; SWIFT_OBJC_BRIDGING_HEADER = "TargetSupport/DatadogTests/DatadogTests-Bridging-Header.h"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example iOS.app/Example iOS"; }; name = Integration; }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 61133B7C242393DE00786299 /* Build configuration list for PBXProject "Datadog" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 61133B94242393DE00786299 /* Debug */, - 61133B95242393DE00786299 /* Release */, - 9E2FB28224476765001C9B7B /* Integration */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 61133B96242393DE00786299 /* Build configuration list for PBXNativeTarget "Datadog" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 61133B97242393DE00786299 /* Debug */, - 61133B98242393DE00786299 /* Release */, - 9E2FB28324476765001C9B7B /* Integration */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + D240684A27CE6C9E00C04F44 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1B082CB25641DF9002DB9D2 /* Example.xcconfig */; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = TargetSupport/Example/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.Example; + PRODUCT_MODULE_NAME = Example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_OBJC_BRIDGING_HEADER = "TargetSupport/Example/Example-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VALIDATE_WORKSPACE = YES; + }; + name = Debug; }; - 61133B99242393DE00786299 /* Build configuration list for PBXNativeTarget "DatadogTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 61133B9A242393DE00786299 /* Debug */, - 61133B9B242393DE00786299 /* Release */, - 9E2FB28524476765001C9B7B /* Integration */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + D240684B27CE6C9E00C04F44 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1B082CB25641DF9002DB9D2 /* Example.xcconfig */; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = TargetSupport/Example/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.Example; + PRODUCT_MODULE_NAME = Example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_OBJC_BRIDGING_HEADER = "TargetSupport/Example/Example-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VALIDATE_WORKSPACE = YES; + }; + name = Release; }; - 61133C01242397DA00786299 /* Build configuration list for PBXNativeTarget "DatadogObjc" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 61133C02242397DA00786299 /* Debug */, - 61133C03242397DA00786299 /* Release */, - 9E2FB28424476765001C9B7B /* Integration */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + D240684C27CE6C9E00C04F44 /* Integration */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1B082CB25641DF9002DB9D2 /* Example.xcconfig */; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = TargetSupport/Example/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.Example; + PRODUCT_MODULE_NAME = Example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_OBJC_BRIDGING_HEADER = "TargetSupport/Example/Example-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VALIDATE_WORKSPACE = YES; + }; + name = Integration; }; - 61441C1324616DEC003D8BB8 /* Build configuration list for PBXNativeTarget "Example" */ = { - isa = XCConfigurationList; - buildConfigurations = ( + D2CB6ECE27C50EAE00A62B57 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 61569894256D0E9A00C6AADA /* Base.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../Carthage/Build/", + ); + INFOPLIST_FILE = TargetSupport/Datadog/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.Datadog; + PRODUCT_NAME = "$(DD_SWIFT_SDK_PRODUCT_NAME)"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = NO; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + D2CB6ECF27C50EAE00A62B57 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 61569894256D0E9A00C6AADA /* Base.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../Carthage/Build/", + ); + INFOPLIST_FILE = TargetSupport/Datadog/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.Datadog; + PRODUCT_NAME = "$(DD_SWIFT_SDK_PRODUCT_NAME)"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = NO; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + D2CB6ED027C50EAE00A62B57 /* Integration */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 61569894256D0E9A00C6AADA /* Base.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../Carthage/Build/", + ); + INFOPLIST_FILE = TargetSupport/Datadog/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.Datadog; + PRODUCT_NAME = "$(DD_SWIFT_SDK_PRODUCT_NAME)"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = NO; + SWIFT_VERSION = 5.0; + }; + name = Integration; + }; + D2CB6F8C27C520D400A62B57 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 61378BA72555329E00F28837 /* DatadogTests.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = TargetSupport/DatadogTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogTests; + PRODUCT_NAME = "$(DD_SWIFT_SDK_PRODUCT_NAME)Tests"; + SDKROOT = appletvos; + SUPPORTS_MACCATALYST = NO; + SWIFT_OBJC_BRIDGING_HEADER = "TargetSupport/DatadogTests/DatadogTests-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example tvOS.app/Example tvOS"; + }; + name = Debug; + }; + D2CB6F8D27C520D400A62B57 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 61378BA72555329E00F28837 /* DatadogTests.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = TargetSupport/DatadogTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogTests; + PRODUCT_NAME = "$(DD_SWIFT_SDK_PRODUCT_NAME)Tests"; + SDKROOT = appletvos; + SUPPORTS_MACCATALYST = NO; + SWIFT_OBJC_BRIDGING_HEADER = "TargetSupport/DatadogTests/DatadogTests-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example tvOS.app/Example tvOS"; + }; + name = Release; + }; + D2CB6F8E27C520D400A62B57 /* Integration */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 61378BA72555329E00F28837 /* DatadogTests.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = TargetSupport/DatadogTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogTests; + PRODUCT_NAME = "$(DD_SWIFT_SDK_PRODUCT_NAME)Tests"; + SDKROOT = appletvos; + SUPPORTS_MACCATALYST = NO; + SWIFT_OBJC_BRIDGING_HEADER = "TargetSupport/DatadogTests/DatadogTests-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example tvOS.app/Example tvOS"; + }; + name = Integration; + }; + D2CB6FAD27C5217A00A62B57 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 61569894256D0E9A00C6AADA /* Base.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../Carthage/Build/", + ); + INFOPLIST_FILE = TargetSupport/DatadogObjc/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogObjc; + PRODUCT_NAME = "$(DD_OBJC_SDK_PRODUCT_NAME)"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + }; + name = Debug; + }; + D2CB6FAE27C5217A00A62B57 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 61569894256D0E9A00C6AADA /* Base.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../Carthage/Build/", + ); + INFOPLIST_FILE = TargetSupport/DatadogObjc/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogObjc; + PRODUCT_NAME = "$(DD_OBJC_SDK_PRODUCT_NAME)"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + }; + name = Release; + }; + D2CB6FAF27C5217A00A62B57 /* Integration */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 61569894256D0E9A00C6AADA /* Base.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../Carthage/Build/", + ); + INFOPLIST_FILE = TargetSupport/DatadogObjc/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogObjc; + PRODUCT_NAME = "$(DD_OBJC_SDK_PRODUCT_NAME)"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + }; + name = Integration; + }; + D2CB6FCE27C5348200A62B57 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 615D9E2626048EAF006DC6D1 /* DatadogCrashReporting.xcconfig */; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../Carthage/Build", + ); + INFOPLIST_FILE = TargetSupport/DatadogCrashReporting/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReporting; + PRODUCT_NAME = "$(DD_CR_SDK_PRODUCT_NAME)"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = NO; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + }; + name = Debug; + }; + D2CB6FCF27C5348200A62B57 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 615D9E2626048EAF006DC6D1 /* DatadogCrashReporting.xcconfig */; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../Carthage/Build", + ); + INFOPLIST_FILE = TargetSupport/DatadogCrashReporting/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReporting; + PRODUCT_NAME = "$(DD_CR_SDK_PRODUCT_NAME)"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + }; + name = Release; + }; + D2CB6FD027C5348200A62B57 /* Integration */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 615D9E2626048EAF006DC6D1 /* DatadogCrashReporting.xcconfig */; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../Carthage/Build", + ); + INFOPLIST_FILE = TargetSupport/DatadogCrashReporting/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReporting; + PRODUCT_NAME = "$(DD_CR_SDK_PRODUCT_NAME)"; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 3; + }; + name = Integration; + }; + D2CB6FE927C5352300A62B57 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6170DC2B25C1883E003AED5C /* DatadogCrashReportingTests.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = TargetSupport/DatadogCrashReportingTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReportingTests; + PRODUCT_NAME = "$(DD_CR_SDK_PRODUCT_NAME)Tests"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example tvOS.app/Example tvOS"; + }; + name = Debug; + }; + D2CB6FEA27C5352300A62B57 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6170DC2B25C1883E003AED5C /* DatadogCrashReportingTests.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = TargetSupport/DatadogCrashReportingTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReportingTests; + PRODUCT_NAME = "$(DD_CR_SDK_PRODUCT_NAME)Tests"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example tvOS.app/Example tvOS"; + }; + name = Release; + }; + D2CB6FEB27C5352300A62B57 /* Integration */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6170DC2B25C1883E003AED5C /* DatadogCrashReportingTests.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = TargetSupport/DatadogCrashReportingTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReportingTests; + PRODUCT_NAME = "$(DD_CR_SDK_PRODUCT_NAME)Tests"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example tvOS.app/Example tvOS"; + }; + name = Integration; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 61133B7C242393DE00786299 /* Build configuration list for PBXProject "Datadog" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 61133B94242393DE00786299 /* Debug */, + 61133B95242393DE00786299 /* Release */, + 9E2FB28224476765001C9B7B /* Integration */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 61133B96242393DE00786299 /* Build configuration list for PBXNativeTarget "Datadog iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 61133B97242393DE00786299 /* Debug */, + 61133B98242393DE00786299 /* Release */, + 9E2FB28324476765001C9B7B /* Integration */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 61133B99242393DE00786299 /* Build configuration list for PBXNativeTarget "DatadogTests iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 61133B9A242393DE00786299 /* Debug */, + 61133B9B242393DE00786299 /* Release */, + 9E2FB28524476765001C9B7B /* Integration */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 61133C01242397DA00786299 /* Build configuration list for PBXNativeTarget "DatadogObjc iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 61133C02242397DA00786299 /* Debug */, + 61133C03242397DA00786299 /* Release */, + 9E2FB28424476765001C9B7B /* Integration */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 61441C1324616DEC003D8BB8 /* Build configuration list for PBXNativeTarget "Example iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( 61441C1424616DEC003D8BB8 /* Debug */, 61441C1524616DEC003D8BB8 /* Release */, 61441C1624616DEC003D8BB8 /* Integration */, @@ -5828,7 +7584,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61B7886B25C180CB002675B5 /* Build configuration list for PBXNativeTarget "DatadogCrashReporting" */ = { + 61B7886B25C180CB002675B5 /* Build configuration list for PBXNativeTarget "DatadogCrashReporting iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 61B7886525C180CB002675B5 /* Debug */, @@ -5838,7 +7594,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61B7886C25C180CB002675B5 /* Build configuration list for PBXNativeTarget "DatadogCrashReportingTests" */ = { + 61B7886C25C180CB002675B5 /* Build configuration list for PBXNativeTarget "DatadogCrashReportingTests iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 61B7886825C180CB002675B5 /* Debug */, @@ -5848,6 +7604,66 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + D240684927CE6C9E00C04F44 /* Build configuration list for PBXNativeTarget "Example tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D240684A27CE6C9E00C04F44 /* Debug */, + D240684B27CE6C9E00C04F44 /* Release */, + D240684C27CE6C9E00C04F44 /* Integration */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D2CB6ECD27C50EAE00A62B57 /* Build configuration list for PBXNativeTarget "Datadog tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D2CB6ECE27C50EAE00A62B57 /* Debug */, + D2CB6ECF27C50EAE00A62B57 /* Release */, + D2CB6ED027C50EAE00A62B57 /* Integration */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D2CB6F8B27C520D400A62B57 /* Build configuration list for PBXNativeTarget "DatadogTests tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D2CB6F8C27C520D400A62B57 /* Debug */, + D2CB6F8D27C520D400A62B57 /* Release */, + D2CB6F8E27C520D400A62B57 /* Integration */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D2CB6FAC27C5217A00A62B57 /* Build configuration list for PBXNativeTarget "DatadogObjc tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D2CB6FAD27C5217A00A62B57 /* Debug */, + D2CB6FAE27C5217A00A62B57 /* Release */, + D2CB6FAF27C5217A00A62B57 /* Integration */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D2CB6FCD27C5348200A62B57 /* Build configuration list for PBXNativeTarget "DatadogCrashReporting tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D2CB6FCE27C5348200A62B57 /* Debug */, + D2CB6FCF27C5348200A62B57 /* Release */, + D2CB6FD027C5348200A62B57 /* Integration */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D2CB6FE827C5352300A62B57 /* Build configuration list for PBXNativeTarget "DatadogCrashReportingTests tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D2CB6FE927C5352300A62B57 /* Debug */, + D2CB6FEA27C5352300A62B57 /* Release */, + D2CB6FEB27C5352300A62B57 /* Integration */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCSwiftPackageProductDependency section */ diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Datadog.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Datadog iOS.xcscheme similarity index 96% rename from Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Datadog.xcscheme rename to Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Datadog iOS.xcscheme index dff85c19f2..202be70ca3 100644 --- a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Datadog.xcscheme +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Datadog iOS.xcscheme @@ -16,7 +16,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61133B81242393DE00786299" BuildableName = "Datadog.framework" - BlueprintName = "Datadog" + BlueprintName = "Datadog iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -35,7 +35,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61133B8A242393DE00786299" BuildableName = "DatadogTests.xctest" - BlueprintName = "DatadogTests" + BlueprintName = "DatadogTests iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -127,14 +127,14 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61133B81242393DE00786299" BuildableName = "Datadog.framework" - BlueprintName = "Datadog" + BlueprintName = "Datadog iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -146,7 +146,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61133B8A242393DE00786299" BuildableName = "DatadogTests.xctest" - BlueprintName = "DatadogTests" + BlueprintName = "DatadogTests iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -174,7 +174,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61133B81242393DE00786299" BuildableName = "Datadog.framework" - BlueprintName = "Datadog" + BlueprintName = "Datadog iOS" ReferencedContainer = "container:Datadog.xcodeproj"> diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Datadog tvOS.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Datadog tvOS.xcscheme new file mode 100644 index 0000000000..0e7e7d0541 --- /dev/null +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Datadog tvOS.xcscheme @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting iOS.xcscheme similarity index 96% rename from Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting.xcscheme rename to Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting iOS.xcscheme index d03534097e..177ee307f6 100644 --- a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting.xcscheme +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting iOS.xcscheme @@ -16,7 +16,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61B7885325C180CB002675B5" BuildableName = "DatadogCrashReporting.framework" - BlueprintName = "DatadogCrashReporting" + BlueprintName = "DatadogCrashReporting iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -35,7 +35,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61B7885B25C180CB002675B5" BuildableName = "DatadogCrashReportingTests.xctest" - BlueprintName = "DatadogCrashReportingTests" + BlueprintName = "DatadogCrashReportingTests iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -182,7 +182,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61B7885325C180CB002675B5" BuildableName = "DatadogCrashReporting.framework" - BlueprintName = "DatadogCrashReporting" + BlueprintName = "DatadogCrashReporting iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -193,7 +193,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61B7885B25C180CB002675B5" BuildableName = "DatadogCrashReportingTests.xctest" - BlueprintName = "DatadogCrashReportingTests" + BlueprintName = "DatadogCrashReportingTests iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -221,7 +221,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61B7885325C180CB002675B5" BuildableName = "DatadogCrashReporting.framework" - BlueprintName = "DatadogCrashReporting" + BlueprintName = "DatadogCrashReporting iOS" ReferencedContainer = "container:Datadog.xcodeproj"> diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting tvOS.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting tvOS.xcscheme new file mode 100644 index 0000000000..7feef26eed --- /dev/null +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting tvOS.xcscheme @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogIntegrationTests.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogIntegrationTests.xcscheme index b73d9d58e8..1b7b188ffe 100644 --- a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogIntegrationTests.xcscheme +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogIntegrationTests.xcscheme @@ -143,14 +143,14 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61133B81242393DE00786299" BuildableName = "Datadog.framework" - BlueprintName = "Datadog" + BlueprintName = "Datadog iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -191,8 +191,8 @@ diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc iOS.xcscheme similarity index 95% rename from Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc.xcscheme rename to Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc iOS.xcscheme index f43d201e2c..2bea2d4751 100644 --- a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc.xcscheme +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc iOS.xcscheme @@ -16,7 +16,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61133BEF242397DA00786299" BuildableName = "DatadogObjc.framework" - BlueprintName = "DatadogObjc" + BlueprintName = "DatadogObjc iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -34,7 +34,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61133B8A242393DE00786299" BuildableName = "DatadogTests.xctest" - BlueprintName = "DatadogTests" + BlueprintName = "DatadogTests iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -121,14 +121,14 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61133B81242393DE00786299" BuildableName = "Datadog.framework" - BlueprintName = "Datadog" + BlueprintName = "Datadog iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -139,7 +139,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61133B8A242393DE00786299" BuildableName = "DatadogTests.xctest" - BlueprintName = "DatadogTests" + BlueprintName = "DatadogTests iOS" ReferencedContainer = "container:Datadog.xcodeproj"> @@ -167,7 +167,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "61133BEF242397DA00786299" BuildableName = "DatadogObjc.framework" - BlueprintName = "DatadogObjc" + BlueprintName = "DatadogObjc iOS" ReferencedContainer = "container:Datadog.xcodeproj"> diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme new file mode 100644 index 0000000000..be13d38968 --- /dev/null +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Example iOS.xcscheme similarity index 96% rename from Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Example.xcscheme rename to Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Example iOS.xcscheme index 2eb066f4ed..3dfe15d9df 100644 --- a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Example.xcscheme +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Example iOS.xcscheme @@ -15,8 +15,8 @@ @@ -45,8 +45,8 @@ @@ -169,8 +169,8 @@ diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Example tvOS.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Example tvOS.xcscheme new file mode 100644 index 0000000000..303f656cc0 --- /dev/null +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Example tvOS.xcscheme @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Datadog/Example/AppConfiguration.swift b/Datadog/Example/AppConfiguration.swift index 4947e4aed7..d6a7839ca3 100644 --- a/Datadog/Example/AppConfiguration.swift +++ b/Datadog/Example/AppConfiguration.swift @@ -41,6 +41,16 @@ struct ExampleAppConfiguration: AppConfiguration { .set(batchSize: .small) .set(uploadFrequency: .frequent) + if let customLogsURL = Environment.readCustomLogsURL() { + _ = configuration.set(customLogsEndpoint: customLogsURL) + } + if let customTraceURL = Environment.readCustomTraceURL() { + _ = configuration.set(customTracesEndpoint: customTraceURL) + } + if let customRUMURL = Environment.readCustomRUMURL() { + _ = configuration.set(customRUMEndpoint: customRUMURL) + } + #if DD_SDK_ENABLE_INTERNAL_MONITORING _ = configuration .enableInternalMonitoring(clientToken: Environment.readClientToken()) @@ -66,7 +76,11 @@ struct ExampleAppConfiguration: AppConfiguration { if let testScenario = testScenario { return UIStoryboard(name: type(of: testScenario).storyboardName, bundle: nil) } - return UIStoryboard(name: "Main", bundle: nil) + #if os(iOS) + return UIStoryboard(name: "Main iOS", bundle: nil) + #else + return nil + #endif } } diff --git a/Datadog/Example/Base.lproj/Main.storyboard b/Datadog/Example/Base.lproj/Main iOS.storyboard similarity index 100% rename from Datadog/Example/Base.lproj/Main.storyboard rename to Datadog/Example/Base.lproj/Main iOS.storyboard diff --git a/Datadog/Example/Debugging/BackgroundEvents/DebugBackgroundEventsViewController.swift b/Datadog/Example/Debugging/BackgroundEvents/DebugBackgroundEventsViewController.swift index 798450887f..90f9c08cbc 100644 --- a/Datadog/Example/Debugging/BackgroundEvents/DebugBackgroundEventsViewController.swift +++ b/Datadog/Example/Debugging/BackgroundEvents/DebugBackgroundEventsViewController.swift @@ -7,14 +7,14 @@ import SwiftUI import Datadog -@available(iOS 13, *) +@available(iOS 13, tvOS 13,*) internal class DebugBackgroundEventsViewController: UIHostingController { required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder, rootView: DebugBackgroundEventsView()) } } -@available(iOS 13.0, *) +@available(iOS 13, tvOS 13,*) private class DebugBackgroundEventsViewModel: ObservableObject { private let locationMonitor: BackgroundLocationMonitor @@ -55,7 +55,7 @@ private class DebugBackgroundEventsViewModel: ObservableObject { } } -@available(iOS 13.0, *) +@available(iOS 13, tvOS 13,*) internal struct DebugBackgroundEventsView: View { @ObservedObject private var viewModel = DebugBackgroundEventsViewModel() @@ -76,7 +76,7 @@ internal struct DebugBackgroundEventsView: View { Text("Location Monitoring:") .font(.body).fontWeight(.light) Spacer() - if #available(iOS 14.0, *) { + if #available(iOS 14, tvOS 14, *) { if viewModel.isLocationMonitoringON { ProgressView().padding(.trailing, 8) } @@ -116,7 +116,7 @@ internal struct DebugBackgroundEventsView: View { // MARK - Preview -@available(iOS 13.0, *) +@available(iOS 13, tvOS 13,*) internal struct DebugBackgroundEventsView_Previews: PreviewProvider { static var previews: some View { Group { diff --git a/Datadog/Example/Debugging/DebugRUMViewController.swift b/Datadog/Example/Debugging/DebugRUMViewController.swift index 063f5db4f7..02a69670b6 100644 --- a/Datadog/Example/Debugging/DebugRUMViewController.swift +++ b/Datadog/Example/Debugging/DebugRUMViewController.swift @@ -179,6 +179,7 @@ extension RUMUserActionType { var toString: String { switch self { case .tap: return "tap" + case .click: return "click" case .scroll: return "scroll" case .swipe: return "swipe" case .custom: return "custom" diff --git a/Datadog/Example/Debugging/Helpers/SwiftUI.swift b/Datadog/Example/Debugging/Helpers/SwiftUI.swift index 56879ec2f9..c111d3b6b1 100644 --- a/Datadog/Example/Debugging/Helpers/SwiftUI.swift +++ b/Datadog/Example/Debugging/Helpers/SwiftUI.swift @@ -6,7 +6,7 @@ import SwiftUI -@available(iOS 13.0, *) +@available(iOS 13, tvOS 13,*) extension Color { /// Datadog purple. static var datadogPurple: Color { @@ -30,7 +30,7 @@ extension Color { } } -@available(iOS 13.0, *) +@available(iOS 13, tvOS 13,*) internal struct DatadogButtonStyle: ButtonStyle { func makeBody(configuration: DatadogButtonStyle.Configuration) -> some View { return configuration.label diff --git a/Datadog/Example/Environment.swift b/Datadog/Example/Environment.swift index 4deeba034b..652bfd8996 100644 --- a/Datadog/Example/Environment.swift +++ b/Datadog/Example/Environment.swift @@ -47,6 +47,10 @@ internal struct Environment { struct InfoPlistKey { static let clientToken = "DatadogClientToken" static let rumApplicationID = "RUMApplicationID" + + static let customLogsURL = "CustomLogsURL" + static let customTraceURL = "CustomTraceURL" + static let customRUMURL = "CustomRUMURL" } // MARK: - Launch Arguments @@ -106,4 +110,28 @@ internal struct Environment { } return rumApplicationID } + + static func readCustomLogsURL() -> URL? { + if let customLogsURL = Bundle.main.infoDictionary![InfoPlistKey.customLogsURL] as? String, + !customLogsURL.isEmpty { + return URL(string: "https://\(customLogsURL)") + } + return nil + } + + static func readCustomTraceURL() -> URL? { + if let customTraceURL = Bundle.main.infoDictionary![InfoPlistKey.customTraceURL] as? String, + !customTraceURL.isEmpty { + return URL(string: "https://\(customTraceURL)") + } + return nil + } + + static func readCustomRUMURL() -> URL? { + if let customRUMURL = Bundle.main.infoDictionary![InfoPlistKey.customRUMURL] as? String, + !customRUMURL.isEmpty { + return URL(string: "https://\(customRUMURL)") + } + return nil + } } diff --git a/Datadog/Example/ExampleAppDelegate.swift b/Datadog/Example/ExampleAppDelegate.swift index fcff4094b8..7947a0340a 100644 --- a/Datadog/Example/ExampleAppDelegate.swift +++ b/Datadog/Example/ExampleAppDelegate.swift @@ -72,11 +72,13 @@ class ExampleAppDelegate: UIResponder, UIApplicationDelegate { launch(storyboard: storyboard) } + #if !os(tvOS) // Instantiate location monitor if the Example app is run in interactive mode. This will // enable background location tracking if it was started in previous session. if Environment.isRunningInteractive() { backgroundLocationMonitor = BackgroundLocationMonitor() } + #endif return true } diff --git a/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift b/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift index 17f457017f..141177742d 100644 --- a/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift +++ b/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift @@ -7,6 +7,37 @@ import Foundation import Datadog +/// An example of instrumenting existing `URLSessionDelegate` with `DDURLSessionDelegate` through inheritance. +private class InheritedURLSessionDelegate: DDURLSessionDelegate { + override func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { + super.urlSession(session, task: task, didCompleteWithError: error) // forward to DD + /* run custom logic */ + } +} + +/// An example of instrumenting existing `URLSessionDelegate` with `DDURLSessionDelegate` through composition. +private class CompositedURLSessionDelegate: NSObject, URLSessionTaskDelegate, URLSessionDataDelegate, __URLSessionDelegateProviding { + // MARK: - __URLSessionDelegateProviding conformance + let ddURLSessionDelegate = DDURLSessionDelegate() + + // MARK: - __URLSessionDelegateProviding handling + + func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) { + ddURLSessionDelegate.urlSession(session, task: task, didFinishCollecting: metrics) // forward to DD + /* run custom logic */ + } + + func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { + ddURLSessionDelegate.urlSession(session, task: task, didCompleteWithError: error) // forward to DD + /* run custom logic */ + } + + func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { + ddURLSessionDelegate.urlSession(session, dataTask: dataTask, didReceive: data) // forward to DD + /* run custom logic */ + } +} + /// Base scenario for `URLSession` and `NSURLSession` instrumentation. It makes /// both Swift and Objective-C tests share the same endpoints and SDK configuration. /// @@ -14,9 +45,21 @@ import Datadog /// calls third party endpoints. @objc class URLSessionBaseScenario: NSObject { - /// Randomizes the way of passing additional first party hosts. - /// If `true`, instrumented endpoints are passed to `DDURLSessionDelegate`; otherwise, they are passed to `DatadogConfiguration.trackURLSession(...)`. - private let feedAdditionalFirstyPartyHosts: Bool + /// The method of instrumenting `URLSession` with `DDURLSessionDelegate` + private enum InstrumentationMethod: CaseIterable { + /// Use `DDURLSessionDelegate` directly and + /// use `firstPartyHosts` defined at SDK level (with `DatadogConfiguration.trackURLSession(firstPartyHosts:)`). + case directWithGlobalFirstPartyHosts + /// Use `DDURLSessionDelegate` directly and + /// use additional `firstPartyHosts` defined when instantiating delegate. + case directWithAdditionalFirstyPartyHosts + /// Use `DDURLSessionDelegate` through inheritance (see: `InheritedURLSessionDelegate`). + case inheritance + /// Use `DDURLSessionDelegate` through composition (see: `CompositedURLSessionDelegate`). + case composition + } + + private let instrumentationMethod: InstrumentationMethod /// Randomizes the way of creating `URLSession` instrumented with `DDURLSessionDelegate`. /// If `true`, the session is created after `Datadog.initialize()`; if `false`, it's created before. @@ -46,7 +89,7 @@ class URLSessionBaseScenario: NSObject { private var ddURLSessionDelegate: DDURLSessionDelegate? override init() { - feedAdditionalFirstyPartyHosts = .random() + instrumentationMethod = InstrumentationMethod.allCases.randomElement()! lazyInitURLSession = .random() if ProcessInfo.processInfo.arguments.contains("IS_RUNNING_UI_TESTS") { @@ -90,9 +133,10 @@ class URLSessionBaseScenario: NSObject { } func configureSDK(builder: Datadog.Configuration.Builder) { - if feedAdditionalFirstyPartyHosts { + switch instrumentationMethod { + case .directWithAdditionalFirstyPartyHosts: _ = builder.trackURLSession() - } else { + case .directWithGlobalFirstPartyHosts, .inheritance, .composition: _ = builder.trackURLSession( firstPartyHosts: [customGETResourceURL.host!, customPOSTRequest.url!.host!, badResourceURL.host!] ) @@ -111,8 +155,12 @@ class URLSessionBaseScenario: NSObject { } private func createInstrumentedURLSession() -> URLSession { - let delegate: DDURLSessionDelegate - if feedAdditionalFirstyPartyHosts { + let delegate: URLSessionDelegate + + switch instrumentationMethod { + case .directWithGlobalFirstPartyHosts: + delegate = DDURLSessionDelegate() + case .directWithAdditionalFirstyPartyHosts: delegate = DDURLSessionDelegate( additionalFirstPartyHosts: [ customGETResourceURL.host!, @@ -120,9 +168,12 @@ class URLSessionBaseScenario: NSObject { badResourceURL.host! ] ) - } else { - delegate = DDURLSessionDelegate() + case .inheritance: + delegate = InheritedURLSessionDelegate() + case .composition: + delegate = CompositedURLSessionDelegate() } + return URLSession( configuration: .default, delegate: delegate, diff --git a/Datadog/Example/Scenarios/WebView/WebViewTrackingFixtureViewController.swift b/Datadog/Example/Scenarios/WebView/WebViewTrackingFixtureViewController.swift index 2e5de7355d..92d0b05b8f 100644 --- a/Datadog/Example/Scenarios/WebView/WebViewTrackingFixtureViewController.swift +++ b/Datadog/Example/Scenarios/WebView/WebViewTrackingFixtureViewController.swift @@ -27,15 +27,20 @@ class ShopistWebviewViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - let controller = WKUserContentController() - controller.trackDatadogEvents(in: ["shopist.io"]) - let config = WKWebViewConfiguration() - config.userContentController = controller - - webView = WKWebView(frame: UIScreen.main.bounds, configuration: config) + webView = WKWebView(frame: UIScreen.main.bounds, configuration: WKWebViewConfiguration()) view.addSubview(webView) } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + webView.configuration.userContentController.trackDatadogEvents(in: ["shopist.io"]) + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + webView.configuration.userContentController.stopTrackingDatadogEvents() + } + override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) webView.load(request) diff --git a/Datadog/Example/Utils/UIButton+Disabling.swift b/Datadog/Example/Utils/UIButton+Disabling.swift index 5bfaaeabd3..4d6b4ca786 100644 --- a/Datadog/Example/Utils/UIButton+Disabling.swift +++ b/Datadog/Example/Utils/UIButton+Disabling.swift @@ -18,11 +18,7 @@ extension UIButton { let originalBackgroundColor = self.backgroundColor self.isEnabled = false - if #available(iOS 13.0, *) { - self.backgroundColor = .systemGray4 - } else { - self.backgroundColor = .systemGray - } + self.backgroundColor = .systemGray return { self.isEnabled = true diff --git a/Datadog/TargetSupport/Example/Info.plist b/Datadog/TargetSupport/Example/Info.plist index 7429cd7f40..c7fe99ec2e 100644 --- a/Datadog/TargetSupport/Example/Info.plist +++ b/Datadog/TargetSupport/Example/Info.plist @@ -2,6 +2,12 @@ + CustomLogsURL + $(CUSTOM_LOGS_URL) + CustomTraceURL + $(CUSTOM_TRACE_URL) + CustomRUMURL + $(CUSTOM_RUM_URL) CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable diff --git a/DatadogSDK.podspec b/DatadogSDK.podspec index 540e49cc71..511457c688 100644 --- a/DatadogSDK.podspec +++ b/DatadogSDK.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "DatadogSDK" s.module_name = "Datadog" - s.version = "1.9.0" + s.version = "1.10.0-beta1" s.summary = "Official Datadog Swift SDK for iOS." s.homepage = "https://www.datadoghq.com" @@ -16,6 +16,7 @@ Pod::Spec.new do |s| s.swift_version = '5.1' s.ios.deployment_target = '11.0' + s.tvos.deployment_target = '11.0' s.source = { :git => "https://github.com/DataDog/dd-sdk-ios.git", :tag => s.version.to_s } diff --git a/DatadogSDK.podspec.src b/DatadogSDK.podspec.src index 4f4578a4ea..23bca14980 100644 --- a/DatadogSDK.podspec.src +++ b/DatadogSDK.podspec.src @@ -16,6 +16,7 @@ Pod::Spec.new do |s| s.swift_version = '5.1' s.ios.deployment_target = '11.0' + s.tvos.deployment_target = '11.0' s.source = { :git => "https://github.com/DataDog/dd-sdk-ios.git", :tag => s.version.to_s } diff --git a/DatadogSDKAlamofireExtension.podspec b/DatadogSDKAlamofireExtension.podspec index 5bcd582e66..ceecf9d863 100644 --- a/DatadogSDKAlamofireExtension.podspec +++ b/DatadogSDKAlamofireExtension.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "DatadogSDKAlamofireExtension" s.module_name = "DatadogAlamofireExtension" - s.version = "1.9.0" + s.version = "1.10.0-beta1" s.summary = "An Official Extensions of Datadog Swift SDK for Alamofire." s.homepage = "https://www.datadoghq.com" @@ -16,6 +16,7 @@ Pod::Spec.new do |s| s.swift_version = '5.1' s.ios.deployment_target = '11.0' + s.tvos.deployment_target = '11.0' # :tag must follow DatadogSDK version below s.source = { :git => "https://github.com/DataDog/dd-sdk-ios.git", :tag => s.version.to_s } diff --git a/DatadogSDKAlamofireExtension.podspec.src b/DatadogSDKAlamofireExtension.podspec.src index 1553e0d72d..b5b6bea600 100644 --- a/DatadogSDKAlamofireExtension.podspec.src +++ b/DatadogSDKAlamofireExtension.podspec.src @@ -16,6 +16,7 @@ Pod::Spec.new do |s| s.swift_version = '5.1' s.ios.deployment_target = '11.0' + s.tvos.deployment_target = '11.0' # :tag must follow DatadogSDK version below s.source = { :git => "https://github.com/DataDog/dd-sdk-ios.git", :tag => s.version.to_s } diff --git a/DatadogSDKCrashReporting.podspec b/DatadogSDKCrashReporting.podspec index 4018132b44..21bc91be6e 100644 --- a/DatadogSDKCrashReporting.podspec +++ b/DatadogSDKCrashReporting.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "DatadogSDKCrashReporting" s.module_name = "DatadogCrashReporting" - s.version = "1.9.0" + s.version = "1.10.0-beta1" s.summary = "Official Datadog Crash Reporting SDK for iOS." s.homepage = "https://www.datadoghq.com" @@ -16,11 +16,12 @@ Pod::Spec.new do |s| s.swift_version = '5.1' s.ios.deployment_target = '11.0' + s.tvos.deployment_target = '11.0' s.source = { :git => 'https://github.com/DataDog/dd-sdk-ios.git', :tag => s.version.to_s } s.static_framework = true s.source_files = "Sources/DatadogCrashReporting/**/*.swift" - s.dependency 'DatadogSDK', '1.9.0' + s.dependency 'DatadogSDK', '1.10.0-beta1' s.dependency 'PLCrashReporter', '~> 1.10.1' end diff --git a/DatadogSDKCrashReporting.podspec.src b/DatadogSDKCrashReporting.podspec.src index af58ffcaf3..9617936c12 100644 --- a/DatadogSDKCrashReporting.podspec.src +++ b/DatadogSDKCrashReporting.podspec.src @@ -16,6 +16,7 @@ Pod::Spec.new do |s| s.swift_version = '5.1' s.ios.deployment_target = '11.0' + s.tvos.deployment_target = '11.0' s.source = { :git => 'https://github.com/DataDog/dd-sdk-ios.git', :tag => s.version.to_s } s.static_framework = true diff --git a/DatadogSDKObjc.podspec b/DatadogSDKObjc.podspec index 92f90781ac..c43456776b 100644 --- a/DatadogSDKObjc.podspec +++ b/DatadogSDKObjc.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "DatadogSDKObjc" s.module_name = "DatadogObjc" - s.version = "1.9.0" + s.version = "1.10.0-beta1" s.summary = "Official Datadog Objective-C SDK for iOS." s.homepage = "https://www.datadoghq.com" @@ -16,9 +16,10 @@ Pod::Spec.new do |s| s.swift_version = '5.1' s.ios.deployment_target = '11.0' + s.tvos.deployment_target = '11.0' s.source = { :git => 'https://github.com/DataDog/dd-sdk-ios.git', :tag => s.version.to_s } s.source_files = "Sources/DatadogObjc/**/*.swift" - s.dependency 'DatadogSDK', '1.9.0' + s.dependency 'DatadogSDK', '1.10.0-beta1' end diff --git a/DatadogSDKObjc.podspec.src b/DatadogSDKObjc.podspec.src index 735f44f97b..40ca41fd04 100644 --- a/DatadogSDKObjc.podspec.src +++ b/DatadogSDKObjc.podspec.src @@ -16,6 +16,7 @@ Pod::Spec.new do |s| s.swift_version = '5.1' s.ios.deployment_target = '11.0' + s.tvos.deployment_target = '11.0' s.source = { :git => 'https://github.com/DataDog/dd-sdk-ios.git', :tag => s.version.to_s } diff --git a/Makefile b/Makefile index df3204a32a..60bb64f757 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ all: dependencies xcodeproj-httpservermock templates # The release version of `dd-sdk-swift-testing` to use for tests instrumentation. -DD_SDK_SWIFT_TESTING_VERSION = 1.1.0 +DD_SDK_SWIFT_TESTING_VERSION = 1.1.1 define DD_SDK_TESTING_XCCONFIG_CI -FRAMEWORK_SEARCH_PATHS=$$(inherited) $$(SRCROOT)/../instrumented-tests/DatadogSDKTesting.xcframework/ios-arm64_x86_64-simulator/\n -LD_RUNPATH_SEARCH_PATHS=$$(inherited) $$(SRCROOT)/../instrumented-tests/DatadogSDKTesting.xcframework/ios-arm64_x86_64-simulator/\n +FRAMEWORK_SEARCH_PATHS=$$(inherited) $$(SRCROOT)/../instrumented-tests/DatadogSDKTesting.xcframework/**\n +LD_RUNPATH_SEARCH_PATHS=$$(inherited) $$(SRCROOT)/../instrumented-tests/DatadogSDKTesting.xcframework/**\n OTHER_LDFLAGS=$$(inherited) -framework DatadogSDKTesting\n DD_TEST_RUNNER=1\n DD_SDK_SWIFT_TESTING_SERVICE=dd-sdk-ios\n @@ -49,7 +49,7 @@ dependencies: @echo "⚙️ Installing dependencies..." @brew list swiftlint &>/dev/null || brew install swiftlint @brew upgrade carthage - @carthage bootstrap --platform iOS --use-xcframeworks + @carthage bootstrap --platform iOS,tvOS --use-xcframeworks @echo $$DD_SDK_BASE_XCCONFIG > xcconfigs/Base.local.xcconfig; ifeq (${ci}, true) @echo $$DD_SDK_BASE_XCCONFIG_CI >> xcconfigs/Base.local.xcconfig; @@ -102,9 +102,9 @@ rum-models-verify: api-surface: @cd tools/api-surface/ && swift build --configuration release @echo "Generating api-surface-swift" - ./tools/api-surface/.build/x86_64-apple-macosx/release/api-surface workspace --workspace-name Datadog.xcworkspace --scheme Datadog --path . > api-surface-swift + ./tools/api-surface/.build/x86_64-apple-macosx/release/api-surface workspace --workspace-name Datadog.xcworkspace --scheme "Datadog iOS" --path . > api-surface-swift @echo "Generating api-surface-objc" - ./tools/api-surface/.build/x86_64-apple-macosx/release/api-surface workspace --workspace-name Datadog.xcworkspace --scheme DatadogObjc --path . > api-surface-objc + ./tools/api-surface/.build/x86_64-apple-macosx/release/api-surface workspace --workspace-name Datadog.xcworkspace --scheme "DatadogObjc iOS" --path . > api-surface-objc # Generate Datadog monitors terraform definition for E2E tests: e2e-monitors-generate: @@ -127,6 +127,3 @@ bump: git add . ; \ git commit -m "Bumped version to $$version"; \ echo Bumped version to $$version - -dogfood: - @cd tools/dogfooding && $(MAKE) diff --git a/Package.swift b/Package.swift index 03baecbbe3..ea613977fd 100644 --- a/Package.swift +++ b/Package.swift @@ -5,7 +5,8 @@ import PackageDescription let package = Package( name: "Datadog", platforms: [ - .iOS(.v11) + .iOS(.v11), + .tvOS(.v11) ], products: [ .library( diff --git a/Sources/Datadog/Core/Feature.swift b/Sources/Datadog/Core/Feature.swift index 6ea0194a3d..813d3b520b 100644 --- a/Sources/Datadog/Core/Feature.swift +++ b/Sources/Datadog/Core/Feature.swift @@ -144,19 +144,17 @@ internal struct FeatureStorage { dataOrchestrator.deleteAllData() } -#if DD_SDK_COMPILED_FOR_TESTING /// Flushes all async write operations and tears down the storage stack. /// - It completes all async writes by synchronously saving data to authorized files. /// - It cancels the storage by preventing all future write operations and marking all authorised files as "ready for upload". /// /// This method is executed synchronously. After return, the storage feature has no more /// pending asynchronous write operations so all its data is ready for upload. - func flushAndTearDown() { + internal func flushAndTearDown() { writer.flushAndCancelSynchronously() arbitraryAuthorizedWriter.flushAndCancelSynchronously() (dataOrchestrator as? DataOrchestrator)?.markAllFilesAsReadable() } -#endif } internal struct FeatureUpload { @@ -202,16 +200,14 @@ internal struct FeatureUpload { self.uploader = uploader } -#if DD_SDK_COMPILED_FOR_TESTING /// Flushes all authorised data and tears down the upload stack. /// - It completes all pending asynchronous work in upload worker and cancels its next schedules. /// - It flushes all data stored in authorized files by performing their arbitrary upload (without retrying). /// /// This method is executed synchronously. After return, the upload feature has no more /// pending asynchronous operations and all its authorized data should be considered uploaded. - func flushAndTearDown() { + internal func flushAndTearDown() { uploader.cancelSynchronously() uploader.flushSynchronously() } -#endif } diff --git a/Sources/Datadog/Core/FeaturesConfiguration.swift b/Sources/Datadog/Core/FeaturesConfiguration.swift index 38aac4540d..bb2efefb4a 100644 --- a/Sources/Datadog/Core/FeaturesConfiguration.swift +++ b/Sources/Datadog/Core/FeaturesConfiguration.swift @@ -19,6 +19,7 @@ internal struct FeaturesConfiguration { let environment: String let performance: PerformancePreset let source: String + let origin: String? let sdkVersion: String let proxyConfiguration: [AnyHashable: Any]? } @@ -171,6 +172,7 @@ extension FeaturesConfiguration { bundleType: appContext.bundleType ), source: source, + origin: CITestIntegration.active?.origin, sdkVersion: sdkVersion, proxyConfiguration: configuration.proxyConfiguration ) diff --git a/Sources/Datadog/Core/Persistence/DataOrchestrator.swift b/Sources/Datadog/Core/Persistence/DataOrchestrator.swift index 51fb95dc67..0aea2d655f 100644 --- a/Sources/Datadog/Core/Persistence/DataOrchestrator.swift +++ b/Sources/Datadog/Core/Persistence/DataOrchestrator.swift @@ -26,12 +26,10 @@ internal struct DataOrchestrator: DataOrchestratorType { } } -#if DD_SDK_COMPILED_FOR_TESTING - func markAllFilesAsReadable() { + internal func markAllFilesAsReadable() { queue.sync { authorizedFilesOrchestrator.ignoreFilesAgeWhenReading = true unauthorizedFilesOrchestrator.ignoreFilesAgeWhenReading = true } } -#endif } diff --git a/Sources/Datadog/Core/Persistence/Files/File.swift b/Sources/Datadog/Core/Persistence/Files/File.swift index 2b1df5d1a7..4fad206713 100644 --- a/Sources/Datadog/Core/Persistence/Files/File.swift +++ b/Sources/Datadog/Core/Persistence/Files/File.swift @@ -66,7 +66,7 @@ internal struct File: WritableFile, ReadableFile { ``` This is fixed in iOS 14/Xcode 12 */ - if #available(iOS 13.4, *) { + if #available(iOS 13.4, tvOS 13.4, *) { defer { try? fileHandle.close() } try fileHandle.seekToEnd() try fileHandle.write(contentsOf: data) @@ -110,7 +110,7 @@ internal struct File: WritableFile, ReadableFile { ``` This is fixed in iOS 14/Xcode 12 */ - if #available(iOS 13.4, *) { + if #available(iOS 13.4, tvOS 13.4, *) { defer { try? fileHandle.close() } return try fileHandle.readToEnd() ?? Data() } else { diff --git a/Sources/Datadog/Core/Persistence/FilesOrchestrator.swift b/Sources/Datadog/Core/Persistence/FilesOrchestrator.swift index cae1d40451..5510d41f59 100644 --- a/Sources/Datadog/Core/Persistence/FilesOrchestrator.swift +++ b/Sources/Datadog/Core/Persistence/FilesOrchestrator.swift @@ -134,10 +134,8 @@ internal class FilesOrchestrator { } } -#if DD_SDK_COMPILED_FOR_TESTING /// If files age should be ignored for obtaining `ReadableFile`. - var ignoreFilesAgeWhenReading = false -#endif + internal var ignoreFilesAgeWhenReading = false // MARK: - Directory size management diff --git a/Sources/Datadog/Core/Persistence/Writing/ArbitraryDataWriter.swift b/Sources/Datadog/Core/Persistence/Writing/ArbitraryDataWriter.swift index d00703174c..b0f44ad1f5 100644 --- a/Sources/Datadog/Core/Persistence/Writing/ArbitraryDataWriter.swift +++ b/Sources/Datadog/Core/Persistence/Writing/ArbitraryDataWriter.swift @@ -33,11 +33,9 @@ internal class ArbitraryDataWriter: AsyncWriter { } } -#if DD_SDK_COMPILED_FOR_TESTING private var isCanceled = false - func flushAndCancelSynchronously() { + internal func flushAndCancelSynchronously() { queue.sync { self.isCanceled = true } } -#endif } diff --git a/Sources/Datadog/Core/Persistence/Writing/ConsentAwareDataWriter.swift b/Sources/Datadog/Core/Persistence/Writing/ConsentAwareDataWriter.swift index 0624641ab7..8da5905f27 100644 --- a/Sources/Datadog/Core/Persistence/Writing/ConsentAwareDataWriter.swift +++ b/Sources/Datadog/Core/Persistence/Writing/ConsentAwareDataWriter.swift @@ -59,14 +59,12 @@ internal class ConsentAwareDataWriter: AsyncWriter, TrackingConsentObserver { } } -#if DD_SDK_COMPILED_FOR_TESTING private var isCanceled = false - func flushAndCancelSynchronously() { + internal func flushAndCancelSynchronously() { queue.sync { self.processor = nil self.isCanceled = true } } -#endif } diff --git a/Sources/Datadog/Core/Persistence/Writing/Writer.swift b/Sources/Datadog/Core/Persistence/Writing/Writer.swift index 65d6b26592..fe5910e0d2 100644 --- a/Sources/Datadog/Core/Persistence/Writing/Writer.swift +++ b/Sources/Datadog/Core/Persistence/Writing/Writer.swift @@ -16,7 +16,5 @@ internal protocol AsyncWriter: Writer { /// Queue used for asynchronous writes. var queue: DispatchQueue { get } -#if DD_SDK_COMPILED_FOR_TESTING func flushAndCancelSynchronously() -#endif } diff --git a/Sources/Datadog/Core/Swizzling/MethodSwizzler.swift b/Sources/Datadog/Core/Swizzling/MethodSwizzler.swift index 0a9df6d088..f2fc965db1 100644 --- a/Sources/Datadog/Core/Swizzling/MethodSwizzler.swift +++ b/Sources/Datadog/Core/Swizzling/MethodSwizzler.swift @@ -73,9 +73,8 @@ internal class MethodSwizzler { } } -#if DD_SDK_COMPILED_FOR_TESTING /// Removes swizzling and resets the method to its original implementation. - func unswizzle() { + internal func unswizzle() { for foundMethod in swizzledMethods { let originalTypedIMP = originalImplementation(of: foundMethod) let originalIMP: IMP = unsafeBitCast(originalTypedIMP, to: IMP.self) @@ -84,7 +83,6 @@ internal class MethodSwizzler { activeSwizzlingNames.removeAll { $0 == foundMethod.swizzlingName } } } -#endif // MARK: - Private methods @@ -121,11 +119,9 @@ internal class MethodSwizzler { } } -#if DD_SDK_COMPILED_FOR_TESTING -extension MethodSwizzler.FoundMethod { +internal extension MethodSwizzler.FoundMethod { var swizzlingName: String { "\(klass).\(method_getName(method))" } } /// The list of active swizzlings to ensure integrity in unit tests. internal var activeSwizzlingNames: [String] = [] -#endif diff --git a/Sources/Datadog/Core/System/CarrierInfoProvider.swift b/Sources/Datadog/Core/System/CarrierInfoProvider.swift index 89aac41367..9cfdec9f9f 100644 --- a/Sources/Datadog/Core/System/CarrierInfoProvider.swift +++ b/Sources/Datadog/Core/System/CarrierInfoProvider.swift @@ -4,7 +4,9 @@ * Copyright 2019-2020 Datadog, Inc. */ +#if os(iOS) import CoreTelephony +#endif /// Network connection details specific to cellular radio access. public struct CarrierInfo: Equatable { @@ -48,7 +50,7 @@ internal protocol CarrierInfoProviderType { extension CarrierInfo.RadioAccessTechnology { init(ctRadioAccessTechnologyConstant: String) { switch ctRadioAccessTechnologyConstant { - #if !targetEnvironment(macCatalyst) + #if os(iOS) case CTRadioAccessTechnologyGPRS: self = .GPRS case CTRadioAccessTechnologyEdge: self = .Edge case CTRadioAccessTechnologyWCDMA: self = .WCDMA @@ -72,16 +74,16 @@ internal class CarrierInfoProvider: CarrierInfoProviderType { private let wrappedProvider: CarrierInfoProviderType convenience init() { - #if targetEnvironment(macCatalyst) - self.init( - wrappedProvider: MacCatalystCarrierInfoProvider() - ) - #else + #if os(iOS) if #available(iOS 12.0, *) { self.init(wrappedProvider: iOS12CarrierInfoProvider(networkInfo: CTTelephonyNetworkInfo())) } else { self.init(wrappedProvider: iOS11CarrierInfoProvider(networkInfo: CTTelephonyNetworkInfo())) } + #else + self.init( + wrappedProvider: NOPCarrierInfoProvider() + ) #endif } @@ -98,16 +100,13 @@ internal class CarrierInfoProvider: CarrierInfoProviderType { } } -#if targetEnvironment(macCatalyst) - -/// Dummy provider for Mac Catalyst which doesn't support carrier info. -internal struct MacCatalystCarrierInfoProvider: CarrierInfoProviderType { +/// Dummy provider for platforms which doesn't support carrier info. +internal struct NOPCarrierInfoProvider: CarrierInfoProviderType { var current: CarrierInfo? { return nil } func subscribe(_ subscriber: Observer) where Observer: ValueObserver, Observer.ObservedValue == CarrierInfo? {} } -#else - +#if os(iOS) /// Carrier info provider for iOS 12 and above. /// It reads `CarrierInfo?` from `CTTelephonyNetworkInfo` only when `CTCarrier` has changed (e.g. when the SIM card was swapped). @available(iOS 12, *) @@ -208,5 +207,4 @@ internal class iOS11CarrierInfoProvider: CarrierInfoProviderType { publisher.subscribe(subscriber) } } - #endif diff --git a/Sources/Datadog/Core/System/LaunchTimeProvider.swift b/Sources/Datadog/Core/System/LaunchTimeProvider.swift index e5d15f5346..0fd14b9144 100644 --- a/Sources/Datadog/Core/System/LaunchTimeProvider.swift +++ b/Sources/Datadog/Core/System/LaunchTimeProvider.swift @@ -19,14 +19,26 @@ internal protocol LaunchTimeProviderType { /// time this variable is requested, the value should represent the time interval between now and the /// process start time. var launchTime: TimeInterval { get } + + /// Returns `true` if the application is pre-warmed. + var isActivePrewarm: Bool { get } } internal class LaunchTimeProvider: LaunchTimeProviderType { var launchTime: TimeInterval { - // Even if __dd_private_AppLaunchTime() is using a lock behind the scenes, TSAN will report a data race if there are no synchronizations at this level. + // Even if __dd_private_AppLaunchTime() is using a lock behind the + // scenes, TSAN will report a data race if there are no + // synchronizations at this level. objc_sync_enter(self) let time = __dd_private_AppLaunchTime() objc_sync_exit(self) return time } + + var isActivePrewarm: Bool { + objc_sync_enter(self) + let isActivePrewarm = __dd_private_isActivePrewarm() + objc_sync_exit(self) + return isActivePrewarm + } } diff --git a/Sources/Datadog/Core/System/MobileDevice.swift b/Sources/Datadog/Core/System/MobileDevice.swift index 45d442e590..bcfd18c5bd 100644 --- a/Sources/Datadog/Core/System/MobileDevice.swift +++ b/Sources/Datadog/Core/System/MobileDevice.swift @@ -52,6 +52,7 @@ internal class MobileDevice { self.currentBatteryStatus = currentBatteryStatus } + #if os(iOS) convenience init(uiDevice: UIDevice, processInfo: ProcessInfo, notificationCenter: NotificationCenter) { let wasBatteryMonitoringEnabled = uiDevice.isBatteryMonitoringEnabled @@ -105,6 +106,24 @@ internal class MobileDevice { @unknown default: return.unknown } } + + #else + convenience init( + uiDevice: UIDevice = .current, + processInfo: ProcessInfo = .processInfo, + notificationCenter: NotificationCenter = .default + ) { + // iOS Simulator - battery monitoring doesn't work on tvOS nor Simulator, so return "always OK" value + self.init( + model: uiDevice.model, + osName: uiDevice.systemName, + osVersion: uiDevice.systemVersion, + enableBatteryStatusMonitoring: {}, + resetBatteryStatusMonitoring: {}, + currentBatteryStatus: { BatteryStatus(state: .full, level: 1, isLowPowerModeEnabled: false) } + ) + } + #endif } /// Observes "Low Power Mode" setting changes and provides `isLowPowerModeEnabled` value in a thread-safe manner. diff --git a/Sources/Datadog/Core/System/NetworkConnectionInfoProvider.swift b/Sources/Datadog/Core/System/NetworkConnectionInfoProvider.swift index c9371755d1..56603efbf2 100644 --- a/Sources/Datadog/Core/System/NetworkConnectionInfoProvider.swift +++ b/Sources/Datadog/Core/System/NetworkConnectionInfoProvider.swift @@ -65,7 +65,7 @@ internal class NetworkConnectionInfoProvider: NetworkConnectionInfoProviderType private let publisher: ValuePublisher convenience init() { - if #available(iOS 12, *) { + if #available(iOS 12, tvOS 12, *) { self.init(wrappedProvider: NWPathNetworkConnectionInfoProvider()) } else { self.init(wrappedProvider: iOS11NetworkConnectionInfoProvider()) @@ -103,7 +103,7 @@ internal class NetworkConnectionInfoProvider: NetworkConnectionInfoProviderType /// We found the pulling model to not be thread-safe: accessing `currentPath` properties lead to occasional crashes. /// The `ThreadSafeNWPathMonitor` listens to path updates and synchonizes the values on `.current` property. /// This adds the necessary thread-safety and keeps the convenience of pulling. -@available(iOS 12, *) +@available(iOS 12, tvOS 12, *) internal class NWPathNetworkConnectionInfoProvider: WrappedNetworkConnectionInfoProvider { /// Queue synchronizing the reads and updates to `NWPath`. private let queue = DispatchQueue( @@ -122,7 +122,7 @@ internal class NWPathNetworkConnectionInfoProvider: WrappedNetworkConnectionInfo supportsIPv6: path.supportsIPv6, isExpensive: path.isExpensive, isConstrained: { - if #available(iOS 13.0, *) { + if #available(iOS 13, tvOS 13, *) { return path.isConstrained } else { return nil @@ -175,7 +175,7 @@ internal class iOS11NetworkConnectionInfoProvider: WrappedNetworkConnectionInfoP // MARK: - Conversion helpers extension NetworkConnectionInfo.Reachability { - @available(iOS 12, *) + @available(iOS 12, tvOS 12, *) init(from status: NWPath.Status) { switch status { case .satisfied: self = .yes @@ -195,7 +195,7 @@ extension NetworkConnectionInfo.Reachability { } extension Array where Element == NetworkConnectionInfo.Interface { - @available(iOS 12, *) + @available(iOS 12, tvOS 12, *) init(fromInterfaceTypes interfaceTypes: [NWInterface.InterfaceType]) { self = interfaceTypes.map { interface in switch interface { diff --git a/Sources/Datadog/Core/Upload/DataUploadWorker.swift b/Sources/Datadog/Core/Upload/DataUploadWorker.swift index 1ce5134a0a..f0fc4dd4d4 100644 --- a/Sources/Datadog/Core/Upload/DataUploadWorker.swift +++ b/Sources/Datadog/Core/Upload/DataUploadWorker.swift @@ -8,10 +8,8 @@ import Foundation /// Abstracts the `DataUploadWorker`, so we can have no-op uploader in tests. internal protocol DataUploadWorkerType { -#if DD_SDK_COMPILED_FOR_TESTING func flushSynchronously() func cancelSynchronously() -#endif } internal class DataUploadWorker: DataUploadWorkerType { @@ -109,10 +107,9 @@ internal class DataUploadWorker: DataUploadWorkerType { queue.asyncAfter(deadline: .now() + delay, execute: work) } -#if DD_SDK_COMPILED_FOR_TESTING /// Sends all unsent data synchronously. /// - It performs arbitrary upload (without checking upload condition and without re-transmitting failed uploads). - func flushSynchronously() { + internal func flushSynchronously() { queue.sync { while let nextBatch = self.fileReader.readNextBatch() { _ = self.dataUploader.upload(data: nextBatch.data) @@ -124,7 +121,7 @@ internal class DataUploadWorker: DataUploadWorkerType { /// Cancels scheduled uploads and stops scheduling next ones. /// - It does not affect the upload that has already begun. /// - It blocks the caller thread if called in the middle of upload execution. - func cancelSynchronously() { + internal func cancelSynchronously() { queue.sync { // This cancellation must be performed on the `queue` to ensure that it is not called // in the middle of a `DispatchWorkItem` execution - otherwise, as the pending block would be @@ -133,7 +130,6 @@ internal class DataUploadWorker: DataUploadWorkerType { self.uploadWork = nil } } -#endif } extension DataUploadConditions.Blocker: CustomStringConvertible { diff --git a/Sources/Datadog/Core/Upload/RequestBuilder.swift b/Sources/Datadog/Core/Upload/RequestBuilder.swift index 71a2cb6286..20a284ec47 100644 --- a/Sources/Datadog/Core/Upload/RequestBuilder.swift +++ b/Sources/Datadog/Core/Upload/RequestBuilder.swift @@ -57,9 +57,17 @@ internal struct RequestBuilder { /// Standard "User-Agent" header. static func userAgentHeader(appName: String, appVersion: String, device: MobileDevice) -> HTTPHeader { + let sanitizedAppName: String + do { + let regex = try NSRegularExpression(pattern: "[^a-zA-Z0-9 -]+") + sanitizedAppName = regex.stringByReplacingMatches(in: appName, options: [], range: NSRange((appName.startIndex.. LogEvent) -> Builder { + public func setLogEventMapper(_ mapper: @escaping (LogEvent) -> LogEvent?) -> Builder { configuration.logEventMapper = mapper return self } diff --git a/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift b/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift new file mode 100644 index 0000000000..7a362252e0 --- /dev/null +++ b/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift @@ -0,0 +1,74 @@ +/* + * 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-2020 Datadog, Inc. + */ + +import Foundation + +private enum DDCFMessageID { + static let setCustomTags: Int32 = 0x1111 + static let enableRUM: Int32 = 0x2222 + static let forceFlush: Int32 = 0x3333 +} + +internal class CITestIntegration { + /// Current and active integration with CIApp. + /// `nil` if the integration is not enabled. + static let active: CITestIntegration? = CITestIntegration() + /// RUMCITest model to be attached to events, it contains the CI context + let rumCITest: RUMCITest + /// Tag that must be added to spans and headers when running inside a CIApp test + let origin = "ciapp-test" + + private init?(processInfo: ProcessInfo = .processInfo) { + guard let testID = processInfo.environment["CI_VISIBILITY_TEST_EXECUTION_ID"] else { + return nil + } + self.rumCITest = RUMCITest(testExecutionId: testID) + } + + /// Entry point for running all the tasks needed for CIApp integration + func startIntegration() { + startMessageListener() + notifyRUMSession() + } + + /// Notifies the CIApp framework that a RUM session is being started. It sends a message to a CFMessagePort that is + /// created in the CIApp framework + private func notifyRUMSession() { + let timeout: CFTimeInterval = 1.0 + guard let remotePort = CFMessagePortCreateRemote(nil, "DatadogTestingPort" as CFString) else { + return + } + CFMessagePortSendRequest( + remotePort, + DDCFMessageID.enableRUM, // Message ID for notifying the test that rum is enabled + nil, + timeout, + timeout, + nil, + nil + ) + } + + /// Creates a CFMessagePort that is used by the CIApp framework to notify that a test is going to finish, so all + /// information must be flushed to the backend. It uses a non public API `internalFlushAndDeinitialize()` + private func startMessageListener() { + func attributeCallback(port: CFMessagePort?, msgid: Int32, data: CFData?, info: UnsafeMutableRawPointer?) -> Unmanaged? { + switch msgid { + case DDCFMessageID.forceFlush: + Datadog.internalFlushAndDeinitialize() + default: + break + } + return nil + } + + guard let port = CFMessagePortCreateLocal(nil, "DatadogRUMTestingPort" as CFString, attributeCallback, nil, nil) else { + return + } + let runLoopSource = CFMessagePortCreateRunLoopSource(nil, port, 0) + CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, CFRunLoopMode.commonModes) + } +} diff --git a/Sources/Datadog/FeaturesIntegration/CrashReporting/CrashReportingWithRUMIntegration.swift b/Sources/Datadog/FeaturesIntegration/CrashReporting/CrashReportingWithRUMIntegration.swift index 311001156f..0da340e949 100644 --- a/Sources/Datadog/FeaturesIntegration/CrashReporting/CrashReportingWithRUMIntegration.swift +++ b/Sources/Datadog/FeaturesIntegration/CrashReporting/CrashReportingWithRUMIntegration.swift @@ -231,7 +231,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { ), action: nil, application: .init(id: lastRUMView.application.id), - ciTest: nil, + ciTest: lastRUMView.ciTest, connectivity: lastRUMView.connectivity, context: nil, date: crashDate.timeIntervalSince1970.toInt64Milliseconds, @@ -251,7 +251,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { session: .init( hasReplay: lastRUMView.session.hasReplay, id: lastRUMView.session.id, - type: .user + type: lastRUMView.ciTest != nil ? .ciTest : .user ), source: .ios, synthetics: nil, @@ -279,7 +279,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { session: .init(plan: .plan1) ), application: original.application, - ciTest: nil, + ciTest: original.ciTest, connectivity: original.connectivity, context: original.context, date: crashDate.timeIntervalSince1970.toInt64Milliseconds - 1, // -1ms to put the crash after view in RUM session @@ -344,7 +344,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { application: .init( id: rumConfiguration.applicationID ), - ciTest: nil, + ciTest: CITestIntegration.active?.rumCITest, connectivity: RUMConnectivity( networkInfo: crashContext.lastNetworkConnectionInfo, carrierInfo: crashContext.lastCarrierInfo @@ -355,7 +355,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { session: .init( hasReplay: nil, id: sessionUUID.toRUMDataFormat, - type: .user + type: CITestIntegration.active != nil ? .ciTest : .user ), source: .ios, synthetics: nil, diff --git a/Sources/Datadog/FeaturesIntegration/EnvironmentSpanIntegration.swift b/Sources/Datadog/FeaturesIntegration/EnvironmentSpanIntegration.swift deleted file mode 100644 index 7b0bdb46a2..0000000000 --- a/Sources/Datadog/FeaturesIntegration/EnvironmentSpanIntegration.swift +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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-2020 Datadog, Inc. - */ - -import Foundation - -fileprivate struct EnvironmentSpanIntegration { - /// Tracing context read from environment variables if injected - static var environmentContext: (spanID: String, traceID: String)? { - guard let spanIDValue = ProcessInfo.processInfo.environment[TracingHTTPHeaders.parentSpanIDField] , - let traceIDValue = ProcessInfo.processInfo.environment[TracingHTTPHeaders.traceIDField] else { - return nil - } - return (spanIDValue, traceIDValue) - } -} - -internal struct TracingWithEnvironmentSpanIntegration { - /// Span context to be attached to all root spans in order to continue the trace - /// injected by external process through ENV variables. - var environmentSpanContext: (spanID: TracingUUID, traceID: TracingUUID)? { - guard let environmentContext = EnvironmentSpanIntegration.environmentContext, - let spanID = UInt64(environmentContext.spanID).flatMap({ TracingUUID(rawValue: $0) }), - let traceID = UInt64(environmentContext.traceID).flatMap({ TracingUUID(rawValue: $0) }) else { - return nil - } - return (spanID, traceID) - } -} - -internal struct LoggingWithEnvironmentSpanIntegration { - struct Attributes { - static let spanID = "dd.span_id" - static let traceID = "dd.trace_id" - } - /// Additional log attributes describing the ENV span injected by external process. - /// Adding those attributes to `Log` will correlate them with that span. - var environmentSpanAttributes: [String: Encodable]? { - guard let environmentContext = EnvironmentSpanIntegration.environmentContext else { - return nil - } - return [ - Attributes.spanID: environmentContext.spanID, - Attributes.traceID: environmentContext.traceID - ] - } -} diff --git a/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift b/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift index 10922285cd..6992e1b2c2 100644 --- a/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift +++ b/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift @@ -4,7 +4,8 @@ * Copyright 2019-2020 Datadog, Inc. */ -#if DD_SDK_ENABLE_EXPERIMENTAL_APIS +#if !os(tvOS) + import Foundation import WebKit @@ -27,6 +28,22 @@ public extension WKUserContentController { addDatadogMessageHandler(allowedWebViewHosts: hosts, hostsSanitizer: HostsSanitizer()) } + /// Disables Datadog iOS SDK and Datadog Browser SDK integration. + /// + /// Removes Datadog's ScriptMessageHandler and UserScript from the caller. + /// - Note: This method **must** be called when the webview can be deinitialized. + func stopTrackingDatadogEvents() { + removeScriptMessageHandler(forName: DatadogMessageHandler.name) + + let nonDatadogUserScripts = userScripts.filter { + return !$0.source.starts(with: Self.jsCodePrefix) + } + removeAllUserScripts() + nonDatadogUserScripts.forEach { + addUserScript($0) + } + } + internal func addDatadogMessageHandler(allowedWebViewHosts: Set, hostsSanitizer: HostsSanitizing) { guard !isTracking else { userLogger.warn("`trackDatadogEvents(in:)` was called more than once for the same WebView. Second call will be ignored. Make sure you call it only once.") @@ -130,4 +147,5 @@ internal class DatadogMessageHandler: NSObject, WKScriptMessageHandler { } } } + #endif diff --git a/Sources/Datadog/InternalMonitoring/InternalMonitoringFeature.swift b/Sources/Datadog/InternalMonitoring/InternalMonitoringFeature.swift index da58e7b919..b202d6810e 100644 --- a/Sources/Datadog/InternalMonitoring/InternalMonitoringFeature.swift +++ b/Sources/Datadog/InternalMonitoring/InternalMonitoringFeature.swift @@ -79,7 +79,7 @@ internal final class InternalMonitoringFeature { device: commonDependencies.mobileDevice ), .ddAPIKeyHeader(clientToken: configuration.clientToken), - .ddEVPOriginHeader(source: configuration.common.source), + .ddEVPOriginHeader(source: configuration.common.origin ?? configuration.common.source), .ddEVPOriginVersionHeader(sdkVersion: configuration.common.sdkVersion), .ddRequestIDHeader(), ], @@ -149,11 +149,9 @@ internal final class InternalMonitoringFeature { self.monitor = InternalMonitor(sdkLogger: internalLogger) } -#if DD_SDK_COMPILED_FOR_TESTING - func deinitialize() { + internal func deinitialize() { logsStorage.flushAndTearDown() logsUpload.flushAndTearDown() InternalMonitoringFeature.instance = nil } -#endif } diff --git a/Sources/Datadog/InternalMonitoring/Kronos/KronosMonitor.swift b/Sources/Datadog/InternalMonitoring/Kronos/KronosMonitor.swift index ae927989d8..66e52c04e8 100644 --- a/Sources/Datadog/InternalMonitoring/Kronos/KronosMonitor.swift +++ b/Sources/Datadog/InternalMonitoring/Kronos/KronosMonitor.swift @@ -80,7 +80,7 @@ internal class KronosInternalMonitor: KronosMonitor { convenience init() { let queue = DispatchQueue(label: "com.datadoghq.kronos-monitor", qos: .utility) - if #available(iOS 14.2, *) { + if #available(iOS 14.2, tvOS 14.2, *) { self.init( queue: queue, connectionMonitor: IPConnectionMonitor(queue: queue) @@ -229,7 +229,7 @@ internal protocol IPConnectionMonitorType { func checkConnection(to ip: KronosInternetAddress, resultCallback: @escaping (IPConnectionCheckResult) -> Void) } -@available(iOS 14.2, *) +@available(iOS 14.2, tvOS 14.2, *) internal class IPConnectionMonitor: IPConnectionMonitorType { /// Timeout for checking each connection. private let timeout: TimeInterval = 20 diff --git a/Sources/Datadog/Logger.swift b/Sources/Datadog/Logger.swift index 6ac3b8cd78..46c060409b 100644 --- a/Sources/Datadog/Logger.swift +++ b/Sources/Datadog/Logger.swift @@ -74,8 +74,6 @@ public class Logger { internal let rumContextIntegration: LoggingWithRUMContextIntegration? /// Integration with Tracing. `nil` if disabled for this Logger or if the Tracing feature disabled. internal let activeSpanIntegration: LoggingWithActiveSpanIntegration? - /// Integration with Span context injected by environment. - internal let environmentSpanIntegration = LoggingWithEnvironmentSpanIntegration() init( logBuilder: LogEventBuilder?, @@ -263,8 +261,6 @@ public class Logger { } if let activeSpanAttributes = activeSpanIntegration?.activeSpanAttributes { combinedInternalAttributes.merge(activeSpanAttributes) { $1 } - } else if let environmentSpanAttributes = environmentSpanIntegration.environmentSpanAttributes { - combinedInternalAttributes.merge(environmentSpanAttributes) { $1 } } let tags = queue.sync { diff --git a/Sources/Datadog/Logging/LoggingFeature.swift b/Sources/Datadog/Logging/LoggingFeature.swift index f32088083d..27228fbe42 100644 --- a/Sources/Datadog/Logging/LoggingFeature.swift +++ b/Sources/Datadog/Logging/LoggingFeature.swift @@ -85,7 +85,7 @@ internal final class LoggingFeature { device: commonDependencies.mobileDevice ), .ddAPIKeyHeader(clientToken: configuration.clientToken), - .ddEVPOriginHeader(source: configuration.common.source), + .ddEVPOriginHeader(source: configuration.common.origin ?? configuration.common.source), .ddEVPOriginVersionHeader(sdkVersion: configuration.common.sdkVersion), .ddRequestIDHeader(), ], @@ -142,11 +142,9 @@ internal final class LoggingFeature { self.upload = upload } -#if DD_SDK_COMPILED_FOR_TESTING - func deinitialize() { + internal func deinitialize() { storage.flushAndTearDown() upload.flushAndTearDown() LoggingFeature.instance = nil } -#endif } diff --git a/Sources/Datadog/RUM/DataModels/RUMDataModels.swift b/Sources/Datadog/RUM/DataModels/RUMDataModels.swift index fba88de49a..9f50c31fc3 100644 --- a/Sources/Datadog/RUM/DataModels/RUMDataModels.swift +++ b/Sources/Datadog/RUM/DataModels/RUMDataModels.swift @@ -8,16 +8,19 @@ internal protocol RUMDataModel: Codable {} -/// Schema of all properties of a View event -public struct RUMViewEvent: RUMDataModel { +/// Schema of all properties of an Action event +public struct RUMActionEvent: RUMDataModel { /// Internal properties public let dd: DD + /// Action properties + public var action: Action + /// Application properties public let application: Application /// CI Visibility properties - public let ciTest: CiTest? + public let ciTest: RUMCITest? /// Device connectivity properties public let connectivity: RUMConnectivity? @@ -41,7 +44,7 @@ public struct RUMViewEvent: RUMDataModel { public let synthetics: Synthetics? /// RUM event type - public let type: String = "view" + public let type: String = "action" /// User properties public internal(set) var usr: RUMUser? @@ -51,6 +54,7 @@ public struct RUMViewEvent: RUMDataModel { enum CodingKeys: String, CodingKey { case dd = "_dd" + case action = "action" case application = "application" case ciTest = "ci_test" case connectivity = "connectivity" @@ -70,9 +74,6 @@ public struct RUMViewEvent: RUMDataModel { /// Browser SDK version public let browserSdkVersion: String? - /// Version of the update of the view event - public let documentVersion: Int64 - /// Version of the RUM event format public let formatVersion: Int64 = 2 @@ -81,7 +82,6 @@ public struct RUMViewEvent: RUMDataModel { enum CodingKeys: String, CodingKey { case browserSdkVersion = "browser_sdk_version" - case documentVersion = "document_version" case formatVersion = "format_version" case session = "session" } @@ -103,23 +103,112 @@ public struct RUMViewEvent: RUMDataModel { } } - /// Application properties - public struct Application: Codable { - /// UUID of the application - public let id: String + /// Action properties + public struct Action: Codable { + /// Properties of the crashes of the action + public let crash: Crash? + + /// Properties of the errors of the action + public let error: Error? + + /// UUID of the action + public let id: String? + + /// Duration in ns to the action is considered loaded + public let loadingTime: Int64? + + /// Properties of the long tasks of the action + public let longTask: LongTask? + + /// Properties of the resources of the action + public let resource: Resource? + + /// Action target properties + public var target: Target? + + /// Type of the action + public let type: ActionType enum CodingKeys: String, CodingKey { + case crash = "crash" + case error = "error" case id = "id" + case loadingTime = "loading_time" + case longTask = "long_task" + case resource = "resource" + case target = "target" + case type = "type" + } + + /// Properties of the crashes of the action + public struct Crash: Codable { + /// Number of crashes that occurred on the action + public let count: Int64 + + enum CodingKeys: String, CodingKey { + case count = "count" + } + } + + /// Properties of the errors of the action + public struct Error: Codable { + /// Number of errors that occurred on the action + public let count: Int64 + + enum CodingKeys: String, CodingKey { + case count = "count" + } + } + + /// Properties of the long tasks of the action + public struct LongTask: Codable { + /// Number of long tasks that occurred on the action + public let count: Int64 + + enum CodingKeys: String, CodingKey { + case count = "count" + } + } + + /// Properties of the resources of the action + public struct Resource: Codable { + /// Number of resources that occurred on the action + public let count: Int64 + + enum CodingKeys: String, CodingKey { + case count = "count" + } + } + + /// Action target properties + public struct Target: Codable { + /// Target name + public var name: String + + enum CodingKeys: String, CodingKey { + case name = "name" + } + } + + /// Type of the action + public enum ActionType: String, Codable { + case custom = "custom" + case click = "click" + case tap = "tap" + case scroll = "scroll" + case swipe = "swipe" + case applicationStart = "application_start" + case back = "back" } } - /// CI Visibility properties - public struct CiTest: Codable { - /// The identifier of the current CI Visibility test execution - public let testExecutionId: String + /// Application properties + public struct Application: Codable { + /// UUID of the application + public let id: String enum CodingKeys: String, CodingKey { - case testExecutionId = "test_execution_id" + case id = "id" } } @@ -177,221 +266,568 @@ public struct RUMViewEvent: RUMDataModel { /// View properties public struct View: Codable { - /// Properties of the actions of the view - public let action: Action + /// UUID of the view + public let id: String - /// Total number of cpu ticks during the view’s lifetime - public let cpuTicksCount: Double? + /// Is the action starting in the foreground (focus in browser) + public let inForeground: Bool? - /// Average number of cpu ticks per second during the view’s lifetime - public let cpuTicksPerSecond: Double? + /// User defined name of the view + public var name: String? - /// Properties of the crashes of the view - public let crash: Crash? + /// URL that linked to the initial view of the page + public var referrer: String? - /// Total layout shift score that occured on the view - public let cumulativeLayoutShift: Double? + /// URL of the view + public var url: String - /// User custom timings of the view. As timing name is used as facet path, it must contain only letters, digits, or the characters - _ . @ $ - public let customTimings: [String: Int64]? + enum CodingKeys: String, CodingKey { + case id = "id" + case inForeground = "in_foreground" + case name = "name" + case referrer = "referrer" + case url = "url" + } + } +} - /// Duration in ns to the complete parsing and loading of the document and its sub resources - public let domComplete: Int64? +/// Schema of all properties of an Error event +public struct RUMErrorEvent: RUMDataModel { + /// Internal properties + public let dd: DD - /// Duration in ns to the complete parsing and loading of the document without its sub resources - public let domContentLoaded: Int64? + /// Action properties + public let action: Action? - /// Duration in ns to the end of the parsing of the document - public let domInteractive: Int64? + /// Application properties + public let application: Application - /// Properties of the errors of the view - public let error: Error + /// CI Visibility properties + public let ciTest: RUMCITest? - /// Duration in ns to the first rendering - public let firstContentfulPaint: Int64? + /// Device connectivity properties + public let connectivity: RUMConnectivity? - /// Duration in ns of the first input event delay - public let firstInputDelay: Int64? + /// User provided context + public internal(set) var context: RUMEventAttributes? - /// Duration in ns to the first input - public let firstInputTime: Int64? + /// Start of the event in ms from epoch + public let date: Int64 - /// Properties of the frozen frames of the view - public let frozenFrame: FrozenFrame? + /// Error properties + public var error: Error - /// UUID of the view - public let id: String + /// The service name for this application + public let service: String? - /// List of the periods of time the user had the view in foreground (focused in the browser) - public let inForegroundPeriods: [InForegroundPeriods]? + /// Session properties + public let session: Session - /// Whether the View corresponding to this event is considered active - public let isActive: Bool? + /// The source of this event + public let source: Source? - /// Whether the View had a low average refresh rate - public let isSlowRendered: Bool? + /// Synthetics properties + public let synthetics: Synthetics? - /// Duration in ns to the largest contentful paint - public let largestContentfulPaint: Int64? + /// RUM event type + public let type: String = "error" - /// Duration in ns to the end of the load event handler execution - public let loadEvent: Int64? + /// User properties + public internal(set) var usr: RUMUser? - /// Duration in ns to the view is considered loaded - public let loadingTime: Int64? + /// View properties + public var view: View - /// Type of the loading of the view - public let loadingType: LoadingType? + enum CodingKeys: String, CodingKey { + case dd = "_dd" + case action = "action" + case application = "application" + case ciTest = "ci_test" + case connectivity = "connectivity" + case context = "context" + case date = "date" + case error = "error" + case service = "service" + case session = "session" + case source = "source" + case synthetics = "synthetics" + case type = "type" + case usr = "usr" + case view = "view" + } - /// Properties of the long tasks of the view - public let longTask: LongTask? + /// Internal properties + public struct DD: Codable { + /// Browser SDK version + public let browserSdkVersion: String? - /// Average memory used during the view lifetime (in bytes) - public let memoryAverage: Double? + /// Version of the RUM event format + public let formatVersion: Int64 = 2 - /// Peak memory used during the view lifetime (in bytes) - public let memoryMax: Double? + /// Session-related internal properties + public let session: Session? - /// User defined name of the view - public var name: String? + enum CodingKeys: String, CodingKey { + case browserSdkVersion = "browser_sdk_version" + case formatVersion = "format_version" + case session = "session" + } - /// URL that linked to the initial view of the page - public var referrer: String? + /// Session-related internal properties + public struct Session: Codable { + /// Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan + public let plan: Plan - /// Average refresh rate during the view’s lifetime (in frames per second) - public let refreshRateAverage: Double? + enum CodingKeys: String, CodingKey { + case plan = "plan" + } + + /// Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan + public enum Plan: Int, Codable { + case plan1 = 1 + case plan2 = 2 + } + } + } + + /// Action properties + public struct Action: Codable { + /// UUID of the action + public let id: String + + enum CodingKeys: String, CodingKey { + case id = "id" + } + } + + /// Application properties + public struct Application: Codable { + /// UUID of the application + public let id: String + + enum CodingKeys: String, CodingKey { + case id = "id" + } + } + + /// Error properties + public struct Error: Codable { + /// Whether the error has been handled manually in the source code or not + public let handling: Handling? + + /// Handling call stack + public let handlingStack: String? + + /// UUID of the error + public let id: String? + + /// Whether this error crashed the host application + public let isCrash: Bool? + + /// Error message + public var message: String + + /// Resource properties of the error + public var resource: Resource? + + /// Source of the error + public let source: Source + + /// Source type of the error (the language or platform impacting the error stacktrace format) + public let sourceType: SourceType? + + /// Stacktrace of the error + public var stack: String? + + /// The type of the error + public let type: String? + + enum CodingKeys: String, CodingKey { + case handling = "handling" + case handlingStack = "handling_stack" + case id = "id" + case isCrash = "is_crash" + case message = "message" + case resource = "resource" + case source = "source" + case sourceType = "source_type" + case stack = "stack" + case type = "type" + } + + /// Whether the error has been handled manually in the source code or not + public enum Handling: String, Codable { + case handled = "handled" + case unhandled = "unhandled" + } + + /// Resource properties of the error + public struct Resource: Codable { + /// HTTP method of the resource + public let method: RUMMethod + + /// The provider for this resource + public let provider: Provider? + + /// HTTP Status code of the resource + public let statusCode: Int64 + + /// URL of the resource + public var url: String + + enum CodingKeys: String, CodingKey { + case method = "method" + case provider = "provider" + case statusCode = "status_code" + case url = "url" + } + + /// The provider for this resource + public struct Provider: Codable { + /// The domain name of the provider + public let domain: String? + + /// The user friendly name of the provider + public let name: String? + + /// The type of provider + public let type: ProviderType? + + enum CodingKeys: String, CodingKey { + case domain = "domain" + case name = "name" + case type = "type" + } + + /// The type of provider + public enum ProviderType: String, Codable { + case ad = "ad" + case advertising = "advertising" + case analytics = "analytics" + case cdn = "cdn" + case content = "content" + case customerSuccess = "customer-success" + case firstParty = "first party" + case hosting = "hosting" + case marketing = "marketing" + case other = "other" + case social = "social" + case tagManager = "tag-manager" + case utility = "utility" + case video = "video" + } + } + } + + /// Source of the error + public enum Source: String, Codable { + case network = "network" + case source = "source" + case console = "console" + case logger = "logger" + case agent = "agent" + case webview = "webview" + case custom = "custom" + case report = "report" + } + + /// Source type of the error (the language or platform impacting the error stacktrace format) + public enum SourceType: String, Codable { + case android = "android" + case browser = "browser" + case ios = "ios" + case reactNative = "react-native" + case flutter = "flutter" + } + } + + /// Session properties + public struct Session: Codable { + /// Whether this session has a replay + public let hasReplay: Bool? + + /// UUID of the session + public let id: String + + /// Type of the session + public let type: SessionType + + enum CodingKeys: String, CodingKey { + case hasReplay = "has_replay" + case id = "id" + case type = "type" + } + + /// Type of the session + public enum SessionType: String, Codable { + case user = "user" + case synthetics = "synthetics" + case ciTest = "ci_test" + } + } + + /// The source of this event + public enum Source: String, Codable { + case android = "android" + case ios = "ios" + case browser = "browser" + case flutter = "flutter" + case reactNative = "react-native" + } + + /// Synthetics properties + public struct Synthetics: Codable { + /// Whether the event comes from a SDK instance injected by Synthetics + public let injected: Bool? + + /// The identifier of the current Synthetics test results + public let resultId: String + + /// The identifier of the current Synthetics test + public let testId: String + + enum CodingKeys: String, CodingKey { + case injected = "injected" + case resultId = "result_id" + case testId = "test_id" + } + } + + /// View properties + public struct View: Codable { + /// UUID of the view + public let id: String + + /// Is the error starting in the foreground (focus in browser) + public let inForeground: Bool? + + /// User defined name of the view + public var name: String? + + /// URL that linked to the initial view of the page + public var referrer: String? + + /// URL of the view + public var url: String + + enum CodingKeys: String, CodingKey { + case id = "id" + case inForeground = "in_foreground" + case name = "name" + case referrer = "referrer" + case url = "url" + } + } +} + +/// Schema of all properties of a Long Task event +public struct RUMLongTaskEvent: RUMDataModel { + /// Internal properties + public let dd: DD + + /// Action properties + public let action: Action? + + /// Application properties + public let application: Application + + /// CI Visibility properties + public let ciTest: RUMCITest? + + /// Device connectivity properties + public let connectivity: RUMConnectivity? + + /// User provided context + public internal(set) var context: RUMEventAttributes? + + /// Start of the event in ms from epoch + public let date: Int64 + + /// Long Task properties + public let longTask: LongTask + + /// The service name for this application + public let service: String? + + /// Session properties + public let session: Session - /// Minimum refresh rate during the view’s lifetime (in frames per second) - public let refreshRateMin: Double? + /// The source of this event + public let source: Source? - /// Properties of the resources of the view - public let resource: Resource + /// Synthetics properties + public let synthetics: Synthetics? - /// Time spent on the view in ns - public let timeSpent: Int64 + /// RUM event type + public let type: String = "long_task" - /// URL of the view - public var url: String + /// User properties + public internal(set) var usr: RUMUser? + + /// View properties + public var view: View + + enum CodingKeys: String, CodingKey { + case dd = "_dd" + case action = "action" + case application = "application" + case ciTest = "ci_test" + case connectivity = "connectivity" + case context = "context" + case date = "date" + case longTask = "long_task" + case service = "service" + case session = "session" + case source = "source" + case synthetics = "synthetics" + case type = "type" + case usr = "usr" + case view = "view" + } + + /// Internal properties + public struct DD: Codable { + /// Browser SDK version + public let browserSdkVersion: String? + + /// Version of the RUM event format + public let formatVersion: Int64 = 2 + + /// Session-related internal properties + public let session: Session? enum CodingKeys: String, CodingKey { - case action = "action" - case cpuTicksCount = "cpu_ticks_count" - case cpuTicksPerSecond = "cpu_ticks_per_second" - case crash = "crash" - case cumulativeLayoutShift = "cumulative_layout_shift" - case customTimings = "custom_timings" - case domComplete = "dom_complete" - case domContentLoaded = "dom_content_loaded" - case domInteractive = "dom_interactive" - case error = "error" - case firstContentfulPaint = "first_contentful_paint" - case firstInputDelay = "first_input_delay" - case firstInputTime = "first_input_time" - case frozenFrame = "frozen_frame" - case id = "id" - case inForegroundPeriods = "in_foreground_periods" - case isActive = "is_active" - case isSlowRendered = "is_slow_rendered" - case largestContentfulPaint = "largest_contentful_paint" - case loadEvent = "load_event" - case loadingTime = "loading_time" - case loadingType = "loading_type" - case longTask = "long_task" - case memoryAverage = "memory_average" - case memoryMax = "memory_max" - case name = "name" - case referrer = "referrer" - case refreshRateAverage = "refresh_rate_average" - case refreshRateMin = "refresh_rate_min" - case resource = "resource" - case timeSpent = "time_spent" - case url = "url" + case browserSdkVersion = "browser_sdk_version" + case formatVersion = "format_version" + case session = "session" } - /// Properties of the actions of the view - public struct Action: Codable { - /// Number of actions that occurred on the view - public let count: Int64 + /// Session-related internal properties + public struct Session: Codable { + /// Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan + public let plan: Plan enum CodingKeys: String, CodingKey { - case count = "count" + case plan = "plan" + } + + /// Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan + public enum Plan: Int, Codable { + case plan1 = 1 + case plan2 = 2 } } + } - /// Properties of the crashes of the view - public struct Crash: Codable { - /// Number of crashes that occurred on the view - public let count: Int64 + /// Action properties + public struct Action: Codable { + /// UUID of the action + public let id: String - enum CodingKeys: String, CodingKey { - case count = "count" - } + enum CodingKeys: String, CodingKey { + case id = "id" } + } - /// Properties of the errors of the view - public struct Error: Codable { - /// Number of errors that occurred on the view - public let count: Int64 + /// Application properties + public struct Application: Codable { + /// UUID of the application + public let id: String - enum CodingKeys: String, CodingKey { - case count = "count" - } + enum CodingKeys: String, CodingKey { + case id = "id" } + } - /// Properties of the frozen frames of the view - public struct FrozenFrame: Codable { - /// Number of frozen frames that occurred on the view - public let count: Int64 + /// Long Task properties + public struct LongTask: Codable { + /// Duration in ns of the long task + public let duration: Int64 - enum CodingKeys: String, CodingKey { - case count = "count" - } + /// UUID of the long task + public let id: String? + + /// Whether this long task is considered a frozen frame + public let isFrozenFrame: Bool? + + enum CodingKeys: String, CodingKey { + case duration = "duration" + case id = "id" + case isFrozenFrame = "is_frozen_frame" } + } - /// Properties of the foreground period of the view - public struct InForegroundPeriods: Codable { - /// Duration in ns of the view foreground period - public let duration: Int64 + /// Session properties + public struct Session: Codable { + /// Whether this session has a replay + public let hasReplay: Bool? - /// Duration in ns between start of the view and start of foreground period - public let start: Int64 + /// UUID of the session + public let id: String - enum CodingKeys: String, CodingKey { - case duration = "duration" - case start = "start" - } + /// Type of the session + public let type: SessionType + + enum CodingKeys: String, CodingKey { + case hasReplay = "has_replay" + case id = "id" + case type = "type" } - /// Type of the loading of the view - public enum LoadingType: String, Codable { - case initialLoad = "initial_load" - case routeChange = "route_change" - case activityDisplay = "activity_display" - case activityRedisplay = "activity_redisplay" - case fragmentDisplay = "fragment_display" - case fragmentRedisplay = "fragment_redisplay" - case viewControllerDisplay = "view_controller_display" - case viewControllerRedisplay = "view_controller_redisplay" + /// Type of the session + public enum SessionType: String, Codable { + case user = "user" + case synthetics = "synthetics" + case ciTest = "ci_test" } + } - /// Properties of the long tasks of the view - public struct LongTask: Codable { - /// Number of long tasks that occurred on the view - public let count: Int64 + /// The source of this event + public enum Source: String, Codable { + case android = "android" + case ios = "ios" + case browser = "browser" + case flutter = "flutter" + case reactNative = "react-native" + } - enum CodingKeys: String, CodingKey { - case count = "count" - } + /// Synthetics properties + public struct Synthetics: Codable { + /// Whether the event comes from a SDK instance injected by Synthetics + public let injected: Bool? + + /// The identifier of the current Synthetics test results + public let resultId: String + + /// The identifier of the current Synthetics test + public let testId: String + + enum CodingKeys: String, CodingKey { + case injected = "injected" + case resultId = "result_id" + case testId = "test_id" } + } - /// Properties of the resources of the view - public struct Resource: Codable { - /// Number of resources that occurred on the view - public let count: Int64 + /// View properties + public struct View: Codable { + /// UUID of the view + public let id: String - enum CodingKeys: String, CodingKey { - case count = "count" - } + /// User defined name of the view + public var name: String? + + /// URL that linked to the initial view of the page + public var referrer: String? + + /// URL of the view + public var url: String + + enum CodingKeys: String, CodingKey { + case id = "id" + case name = "name" + case referrer = "referrer" + case url = "url" } } } @@ -408,7 +844,7 @@ public struct RUMResourceEvent: RUMDataModel { public let application: Application /// CI Visibility properties - public let ciTest: CiTest? + public let ciTest: RUMCITest? /// Device connectivity properties public let connectivity: RUMConnectivity? @@ -514,22 +950,12 @@ public struct RUMResourceEvent: RUMDataModel { } /// Application properties - public struct Application: Codable { - /// UUID of the application - public let id: String - - enum CodingKeys: String, CodingKey { - case id = "id" - } - } - - /// CI Visibility properties - public struct CiTest: Codable { - /// The identifier of the current CI Visibility test execution - public let testExecutionId: String + public struct Application: Codable { + /// UUID of the application + public let id: String enum CodingKeys: String, CodingKey { - case testExecutionId = "test_execution_id" + case id = "id" } } @@ -805,19 +1231,16 @@ public struct RUMResourceEvent: RUMDataModel { } } -/// Schema of all properties of an Action event -public struct RUMActionEvent: RUMDataModel { +/// Schema of all properties of a View event +public struct RUMViewEvent: RUMDataModel { /// Internal properties public let dd: DD - /// Action properties - public var action: Action - /// Application properties public let application: Application /// CI Visibility properties - public let ciTest: CiTest? + public let ciTest: RUMCITest? /// Device connectivity properties public let connectivity: RUMConnectivity? @@ -841,7 +1264,7 @@ public struct RUMActionEvent: RUMDataModel { public let synthetics: Synthetics? /// RUM event type - public let type: String = "action" + public let type: String = "view" /// User properties public internal(set) var usr: RUMUser? @@ -851,7 +1274,6 @@ public struct RUMActionEvent: RUMDataModel { enum CodingKeys: String, CodingKey { case dd = "_dd" - case action = "action" case application = "application" case ciTest = "ci_test" case connectivity = "connectivity" @@ -871,6 +1293,9 @@ public struct RUMActionEvent: RUMDataModel { /// Browser SDK version public let browserSdkVersion: String? + /// Version of the update of the view event + public let documentVersion: Int64 + /// Version of the RUM event format public let formatVersion: Int64 = 2 @@ -879,6 +1304,7 @@ public struct RUMActionEvent: RUMDataModel { enum CodingKeys: String, CodingKey { case browserSdkVersion = "browser_sdk_version" + case documentVersion = "document_version" case formatVersion = "format_version" case session = "session" } @@ -900,105 +1326,6 @@ public struct RUMActionEvent: RUMDataModel { } } - /// Action properties - public struct Action: Codable { - /// Properties of the crashes of the action - public let crash: Crash? - - /// Properties of the errors of the action - public let error: Error? - - /// UUID of the action - public let id: String? - - /// Duration in ns to the action is considered loaded - public let loadingTime: Int64? - - /// Properties of the long tasks of the action - public let longTask: LongTask? - - /// Properties of the resources of the action - public let resource: Resource? - - /// Action target properties - public var target: Target? - - /// Type of the action - public let type: ActionType - - enum CodingKeys: String, CodingKey { - case crash = "crash" - case error = "error" - case id = "id" - case loadingTime = "loading_time" - case longTask = "long_task" - case resource = "resource" - case target = "target" - case type = "type" - } - - /// Properties of the crashes of the action - public struct Crash: Codable { - /// Number of crashes that occurred on the action - public let count: Int64 - - enum CodingKeys: String, CodingKey { - case count = "count" - } - } - - /// Properties of the errors of the action - public struct Error: Codable { - /// Number of errors that occurred on the action - public let count: Int64 - - enum CodingKeys: String, CodingKey { - case count = "count" - } - } - - /// Properties of the long tasks of the action - public struct LongTask: Codable { - /// Number of long tasks that occurred on the action - public let count: Int64 - - enum CodingKeys: String, CodingKey { - case count = "count" - } - } - - /// Properties of the resources of the action - public struct Resource: Codable { - /// Number of resources that occurred on the action - public let count: Int64 - - enum CodingKeys: String, CodingKey { - case count = "count" - } - } - - /// Action target properties - public struct Target: Codable { - /// Target name - public var name: String - - enum CodingKeys: String, CodingKey { - case name = "name" - } - } - - /// Type of the action - public enum ActionType: String, Codable { - case custom = "custom" - case click = "click" - case tap = "tap" - case scroll = "scroll" - case swipe = "swipe" - case applicationStart = "application_start" - case back = "back" - } - } - /// Application properties public struct Application: Codable { /// UUID of the application @@ -1009,16 +1336,6 @@ public struct RUMActionEvent: RUMDataModel { } } - /// CI Visibility properties - public struct CiTest: Codable { - /// The identifier of the current CI Visibility test execution - public let testExecutionId: String - - enum CodingKeys: String, CodingKey { - case testExecutionId = "test_execution_id" - } - } - /// Session properties public struct Session: Codable { /// Whether this session has a replay @@ -1073,339 +1390,325 @@ public struct RUMActionEvent: RUMDataModel { /// View properties public struct View: Codable { - /// UUID of the view - public let id: String - - /// Is the action starting in the foreground (focus in browser) - public let inForeground: Bool? - - /// User defined name of the view - public var name: String? - - /// URL that linked to the initial view of the page - public var referrer: String? - - /// URL of the view - public var url: String - - enum CodingKeys: String, CodingKey { - case id = "id" - case inForeground = "in_foreground" - case name = "name" - case referrer = "referrer" - case url = "url" - } - } -} - -/// Schema of all properties of an Error event -public struct RUMErrorEvent: RUMDataModel { - /// Internal properties - public let dd: DD - - /// Action properties - public let action: Action? - - /// Application properties - public let application: Application - - /// CI Visibility properties - public let ciTest: CiTest? - - /// Device connectivity properties - public let connectivity: RUMConnectivity? - - /// User provided context - public internal(set) var context: RUMEventAttributes? - - /// Start of the event in ms from epoch - public let date: Int64 - - /// Error properties - public var error: Error - - /// The service name for this application - public let service: String? - - /// Session properties - public let session: Session - - /// The source of this event - public let source: Source? - - /// Synthetics properties - public let synthetics: Synthetics? + /// Properties of the actions of the view + public let action: Action - /// RUM event type - public let type: String = "error" + /// Total number of cpu ticks during the view’s lifetime + public let cpuTicksCount: Double? - /// User properties - public internal(set) var usr: RUMUser? + /// Average number of cpu ticks per second during the view’s lifetime + public let cpuTicksPerSecond: Double? - /// View properties - public var view: View + /// Properties of the crashes of the view + public let crash: Crash? - enum CodingKeys: String, CodingKey { - case dd = "_dd" - case action = "action" - case application = "application" - case ciTest = "ci_test" - case connectivity = "connectivity" - case context = "context" - case date = "date" - case error = "error" - case service = "service" - case session = "session" - case source = "source" - case synthetics = "synthetics" - case type = "type" - case usr = "usr" - case view = "view" - } + /// Total layout shift score that occured on the view + public let cumulativeLayoutShift: Double? - /// Internal properties - public struct DD: Codable { - /// Browser SDK version - public let browserSdkVersion: String? + /// User custom timings of the view. As timing name is used as facet path, it must contain only letters, digits, or the characters - _ . @ $ + public let customTimings: [String: Int64]? - /// Version of the RUM event format - public let formatVersion: Int64 = 2 + /// Duration in ns to the complete parsing and loading of the document and its sub resources + public let domComplete: Int64? - /// Session-related internal properties - public let session: Session? + /// Duration in ns to the complete parsing and loading of the document without its sub resources + public let domContentLoaded: Int64? - enum CodingKeys: String, CodingKey { - case browserSdkVersion = "browser_sdk_version" - case formatVersion = "format_version" - case session = "session" - } + /// Duration in ns to the end of the parsing of the document + public let domInteractive: Int64? - /// Session-related internal properties - public struct Session: Codable { - /// Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan - public let plan: Plan + /// Properties of the errors of the view + public let error: Error - enum CodingKeys: String, CodingKey { - case plan = "plan" - } + /// Duration in ns to the first rendering + public let firstContentfulPaint: Int64? - /// Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan - public enum Plan: Int, Codable { - case plan1 = 1 - case plan2 = 2 - } - } - } + /// Duration in ns of the first input event delay + public let firstInputDelay: Int64? - /// Action properties - public struct Action: Codable { - /// UUID of the action - public let id: String + /// Duration in ns to the first input + public let firstInputTime: Int64? - enum CodingKeys: String, CodingKey { - case id = "id" - } - } + /// Properties of the frozen frames of the view + public let frozenFrame: FrozenFrame? - /// Application properties - public struct Application: Codable { - /// UUID of the application + /// UUID of the view public let id: String - enum CodingKeys: String, CodingKey { - case id = "id" - } - } + /// List of the periods of time the user had the view in foreground (focused in the browser) + public let inForegroundPeriods: [InForegroundPeriods]? - /// CI Visibility properties - public struct CiTest: Codable { - /// The identifier of the current CI Visibility test execution - public let testExecutionId: String + /// Whether the View corresponding to this event is considered active + public let isActive: Bool? - enum CodingKeys: String, CodingKey { - case testExecutionId = "test_execution_id" - } - } + /// Whether the View had a low average refresh rate + public let isSlowRendered: Bool? - /// Error properties - public struct Error: Codable { - /// Whether the error has been handled manually in the source code or not - public let handling: Handling? + /// Duration in ns to the largest contentful paint + public let largestContentfulPaint: Int64? - /// Handling call stack - public let handlingStack: String? + /// Duration in ns to the end of the load event handler execution + public let loadEvent: Int64? - /// UUID of the error - public let id: String? + /// Duration in ns to the view is considered loaded + public let loadingTime: Int64? - /// Whether this error crashed the host application - public let isCrash: Bool? + /// Type of the loading of the view + public let loadingType: LoadingType? - /// Error message - public var message: String + /// Properties of the long tasks of the view + public let longTask: LongTask? - /// Resource properties of the error - public var resource: Resource? + /// Average memory used during the view lifetime (in bytes) + public let memoryAverage: Double? - /// Source of the error - public let source: Source + /// Peak memory used during the view lifetime (in bytes) + public let memoryMax: Double? - /// Source type of the error (the language or platform impacting the error stacktrace format) - public let sourceType: SourceType? + /// User defined name of the view + public var name: String? - /// Stacktrace of the error - public var stack: String? + /// URL that linked to the initial view of the page + public var referrer: String? - /// The type of the error - public let type: String? + /// Average refresh rate during the view’s lifetime (in frames per second) + public let refreshRateAverage: Double? + + /// Minimum refresh rate during the view’s lifetime (in frames per second) + public let refreshRateMin: Double? + + /// Properties of the resources of the view + public let resource: Resource + + /// Time spent on the view in ns + public let timeSpent: Int64 + + /// URL of the view + public var url: String enum CodingKeys: String, CodingKey { - case handling = "handling" - case handlingStack = "handling_stack" + case action = "action" + case cpuTicksCount = "cpu_ticks_count" + case cpuTicksPerSecond = "cpu_ticks_per_second" + case crash = "crash" + case cumulativeLayoutShift = "cumulative_layout_shift" + case customTimings = "custom_timings" + case domComplete = "dom_complete" + case domContentLoaded = "dom_content_loaded" + case domInteractive = "dom_interactive" + case error = "error" + case firstContentfulPaint = "first_contentful_paint" + case firstInputDelay = "first_input_delay" + case firstInputTime = "first_input_time" + case frozenFrame = "frozen_frame" case id = "id" - case isCrash = "is_crash" - case message = "message" + case inForegroundPeriods = "in_foreground_periods" + case isActive = "is_active" + case isSlowRendered = "is_slow_rendered" + case largestContentfulPaint = "largest_contentful_paint" + case loadEvent = "load_event" + case loadingTime = "loading_time" + case loadingType = "loading_type" + case longTask = "long_task" + case memoryAverage = "memory_average" + case memoryMax = "memory_max" + case name = "name" + case referrer = "referrer" + case refreshRateAverage = "refresh_rate_average" + case refreshRateMin = "refresh_rate_min" case resource = "resource" - case source = "source" - case sourceType = "source_type" - case stack = "stack" - case type = "type" + case timeSpent = "time_spent" + case url = "url" } - /// Whether the error has been handled manually in the source code or not - public enum Handling: String, Codable { - case handled = "handled" - case unhandled = "unhandled" - } + /// Properties of the actions of the view + public struct Action: Codable { + /// Number of actions that occurred on the view + public let count: Int64 - /// Resource properties of the error - public struct Resource: Codable { - /// HTTP method of the resource - public let method: RUMMethod + enum CodingKeys: String, CodingKey { + case count = "count" + } + } - /// The provider for this resource - public let provider: Provider? + /// Properties of the crashes of the view + public struct Crash: Codable { + /// Number of crashes that occurred on the view + public let count: Int64 - /// HTTP Status code of the resource - public let statusCode: Int64 + enum CodingKeys: String, CodingKey { + case count = "count" + } + } - /// URL of the resource - public var url: String + /// Properties of the errors of the view + public struct Error: Codable { + /// Number of errors that occurred on the view + public let count: Int64 enum CodingKeys: String, CodingKey { - case method = "method" - case provider = "provider" - case statusCode = "status_code" - case url = "url" + case count = "count" } + } - /// The provider for this resource - public struct Provider: Codable { - /// The domain name of the provider - public let domain: String? + /// Properties of the frozen frames of the view + public struct FrozenFrame: Codable { + /// Number of frozen frames that occurred on the view + public let count: Int64 - /// The user friendly name of the provider - public let name: String? + enum CodingKeys: String, CodingKey { + case count = "count" + } + } - /// The type of provider - public let type: ProviderType? + /// Properties of the foreground period of the view + public struct InForegroundPeriods: Codable { + /// Duration in ns of the view foreground period + public let duration: Int64 - enum CodingKeys: String, CodingKey { - case domain = "domain" - case name = "name" - case type = "type" - } + /// Duration in ns between start of the view and start of foreground period + public let start: Int64 - /// The type of provider - public enum ProviderType: String, Codable { - case ad = "ad" - case advertising = "advertising" - case analytics = "analytics" - case cdn = "cdn" - case content = "content" - case customerSuccess = "customer-success" - case firstParty = "first party" - case hosting = "hosting" - case marketing = "marketing" - case other = "other" - case social = "social" - case tagManager = "tag-manager" - case utility = "utility" - case video = "video" - } + enum CodingKeys: String, CodingKey { + case duration = "duration" + case start = "start" } } - /// Source of the error - public enum Source: String, Codable { - case network = "network" - case source = "source" - case console = "console" - case logger = "logger" - case agent = "agent" - case webview = "webview" - case custom = "custom" + /// Type of the loading of the view + public enum LoadingType: String, Codable { + case initialLoad = "initial_load" + case routeChange = "route_change" + case activityDisplay = "activity_display" + case activityRedisplay = "activity_redisplay" + case fragmentDisplay = "fragment_display" + case fragmentRedisplay = "fragment_redisplay" + case viewControllerDisplay = "view_controller_display" + case viewControllerRedisplay = "view_controller_redisplay" } - /// Source type of the error (the language or platform impacting the error stacktrace format) - public enum SourceType: String, Codable { - case android = "android" - case browser = "browser" - case ios = "ios" - case reactNative = "react-native" - case flutter = "flutter" + /// Properties of the long tasks of the view + public struct LongTask: Codable { + /// Number of long tasks that occurred on the view + public let count: Int64 + + enum CodingKeys: String, CodingKey { + case count = "count" + } + } + + /// Properties of the resources of the view + public struct Resource: Codable { + /// Number of resources that occurred on the view + public let count: Int64 + + enum CodingKeys: String, CodingKey { + case count = "count" + } } } +} + +/// Schema of all properties of a telemetry error event +public struct TelemetryErrorEvent: RUMDataModel { + /// Internal properties + public let dd: DD + + /// Action properties + public let action: Action? + + /// Application properties + public let application: Application? + + /// Start of the event in ms from epoch + public let date: Int64 + + /// Error properties + public let error: Error? + + /// Body of the log + public let message: String + + /// The SDK generating the telemetry event + public let service: String /// Session properties - public struct Session: Codable { - /// Whether this session has a replay - public let hasReplay: Bool? + public let session: Session? - /// UUID of the session - public let id: String + /// Level/severity of the log + public let status: String = "error" - /// Type of the session - public let type: SessionType + /// The version of the SDK generating the telemetry event + public let version: String + + /// View properties + public let view: View? + + enum CodingKeys: String, CodingKey { + case dd = "_dd" + case action = "action" + case application = "application" + case date = "date" + case error = "error" + case message = "message" + case service = "service" + case session = "session" + case status = "status" + case version = "version" + case view = "view" + } + + /// Internal properties + public struct DD: Codable { + /// Event type + public let eventType: String = "internal_telemetry" enum CodingKeys: String, CodingKey { - case hasReplay = "has_replay" - case id = "id" - case type = "type" + case eventType = "event_type" } + } - /// Type of the session - public enum SessionType: String, Codable { - case user = "user" - case synthetics = "synthetics" - case ciTest = "ci_test" + /// Action properties + public struct Action: Codable { + /// UUID of the action + public let id: String + + enum CodingKeys: String, CodingKey { + case id = "id" } } - /// The source of this event - public enum Source: String, Codable { - case android = "android" - case ios = "ios" - case browser = "browser" - case flutter = "flutter" - case reactNative = "react-native" + /// Application properties + public struct Application: Codable { + /// UUID of the application + public let id: String + + enum CodingKeys: String, CodingKey { + case id = "id" + } } - /// Synthetics properties - public struct Synthetics: Codable { - /// Whether the event comes from a SDK instance injected by Synthetics - public let injected: Bool? + /// Error properties + public struct Error: Codable { + /// The error type or kind (or code in some cases) + public let kind: String? - /// The identifier of the current Synthetics test results - public let resultId: String + /// The stack trace or the complementary information about the error + public let stack: String? - /// The identifier of the current Synthetics test - public let testId: String + enum CodingKeys: String, CodingKey { + case kind = "kind" + case stack = "stack" + } + } + + /// Session properties + public struct Session: Codable { + /// UUID of the session + public let id: String enum CodingKeys: String, CodingKey { - case injected = "injected" - case resultId = "result_id" - case testId = "test_id" + case id = "id" } } @@ -1414,30 +1717,14 @@ public struct RUMErrorEvent: RUMDataModel { /// UUID of the view public let id: String - /// Is the error starting in the foreground (focus in browser) - public let inForeground: Bool? - - /// User defined name of the view - public var name: String? - - /// URL that linked to the initial view of the page - public var referrer: String? - - /// URL of the view - public var url: String - enum CodingKeys: String, CodingKey { case id = "id" - case inForeground = "in_foreground" - case name = "name" - case referrer = "referrer" - case url = "url" } } } -/// Schema of all properties of a Long Task event -public struct RUMLongTaskEvent: RUMDataModel { +/// Schema of all properties of a telemetry debug event +public struct TelemetryDebugEvent: RUMDataModel { /// Internal properties public let dd: DD @@ -1445,93 +1732,49 @@ public struct RUMLongTaskEvent: RUMDataModel { public let action: Action? /// Application properties - public let application: Application - - /// CI Visibility properties - public let ciTest: CiTest? - - /// Device connectivity properties - public let connectivity: RUMConnectivity? - - /// User provided context - public internal(set) var context: RUMEventAttributes? + public let application: Application? /// Start of the event in ms from epoch public let date: Int64 - /// Long Task properties - public let longTask: LongTask + /// Body of the log + public let message: String - /// The service name for this application - public let service: String? + /// The SDK generating the telemetry event + public let service: String /// Session properties - public let session: Session - - /// The source of this event - public let source: Source? - - /// Synthetics properties - public let synthetics: Synthetics? + public let session: Session? - /// RUM event type - public let type: String = "long_task" + /// Level/severity of the log + public let status: String = "debug" - /// User properties - public internal(set) var usr: RUMUser? + /// The version of the SDK generating the telemetry event + public let version: String /// View properties - public var view: View + public let view: View? enum CodingKeys: String, CodingKey { case dd = "_dd" case action = "action" case application = "application" - case ciTest = "ci_test" - case connectivity = "connectivity" - case context = "context" case date = "date" - case longTask = "long_task" + case message = "message" case service = "service" case session = "session" - case source = "source" - case synthetics = "synthetics" - case type = "type" - case usr = "usr" + case status = "status" + case version = "version" case view = "view" } /// Internal properties public struct DD: Codable { - /// Browser SDK version - public let browserSdkVersion: String? - - /// Version of the RUM event format - public let formatVersion: Int64 = 2 - - /// Session-related internal properties - public let session: Session? + /// Event type + public let eventType: String = "internal_telemetry" enum CodingKeys: String, CodingKey { - case browserSdkVersion = "browser_sdk_version" - case formatVersion = "format_version" - case session = "session" - } - - /// Session-related internal properties - public struct Session: Codable { - /// Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan - public let plan: Plan - - enum CodingKeys: String, CodingKey { - case plan = "plan" - } - - /// Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan - public enum Plan: Int, Codable { - case plan1 = 1 - case plan2 = 2 - } + case eventType = "event_type" } } @@ -1555,83 +1798,13 @@ public struct RUMLongTaskEvent: RUMDataModel { } } - /// CI Visibility properties - public struct CiTest: Codable { - /// The identifier of the current CI Visibility test execution - public let testExecutionId: String - - enum CodingKeys: String, CodingKey { - case testExecutionId = "test_execution_id" - } - } - - /// Long Task properties - public struct LongTask: Codable { - /// Duration in ns of the long task - public let duration: Int64 - - /// UUID of the long task - public let id: String? - - /// Whether this long task is considered a frozen frame - public let isFrozenFrame: Bool? - - enum CodingKeys: String, CodingKey { - case duration = "duration" - case id = "id" - case isFrozenFrame = "is_frozen_frame" - } - } - /// Session properties public struct Session: Codable { - /// Whether this session has a replay - public let hasReplay: Bool? - /// UUID of the session public let id: String - /// Type of the session - public let type: SessionType - enum CodingKeys: String, CodingKey { - case hasReplay = "has_replay" case id = "id" - case type = "type" - } - - /// Type of the session - public enum SessionType: String, Codable { - case user = "user" - case synthetics = "synthetics" - case ciTest = "ci_test" - } - } - - /// The source of this event - public enum Source: String, Codable { - case android = "android" - case ios = "ios" - case browser = "browser" - case flutter = "flutter" - case reactNative = "react-native" - } - - /// Synthetics properties - public struct Synthetics: Codable { - /// Whether the event comes from a SDK instance injected by Synthetics - public let injected: Bool? - - /// The identifier of the current Synthetics test results - public let resultId: String - - /// The identifier of the current Synthetics test - public let testId: String - - enum CodingKeys: String, CodingKey { - case injected = "injected" - case resultId = "result_id" - case testId = "test_id" } } @@ -1640,24 +1813,22 @@ public struct RUMLongTaskEvent: RUMDataModel { /// UUID of the view public let id: String - /// User defined name of the view - public var name: String? - - /// URL that linked to the initial view of the page - public var referrer: String? - - /// URL of the view - public var url: String - enum CodingKeys: String, CodingKey { case id = "id" - case name = "name" - case referrer = "referrer" - case url = "url" } } } +/// CI Visibility properties +public struct RUMCITest: Codable { + /// The identifier of the current CI Visibility test execution + public let testExecutionId: String + + enum CodingKeys: String, CodingKey { + case testExecutionId = "test_execution_id" + } +} + /// Device connectivity properties public struct RUMConnectivity: Codable { /// Cellular connectivity properties @@ -1821,4 +1992,4 @@ public enum RUMMethod: String, Codable { case patch = "PATCH" } -// Generated from https://github.com/DataDog/rum-events-format/tree/114c173caac5ea15446a157b666acbab05431361 +// Generated from https://github.com/DataDog/rum-events-format/tree/c8a844abb59cb376be2fcdc9deda74dc328af660 diff --git a/Sources/Datadog/RUM/DataModels/RUMDataModelsMapping.swift b/Sources/Datadog/RUM/DataModels/RUMDataModelsMapping.swift index 4e5706da10..a9dd68c7ad 100644 --- a/Sources/Datadog/RUM/DataModels/RUMDataModelsMapping.swift +++ b/Sources/Datadog/RUM/DataModels/RUMDataModelsMapping.swift @@ -37,6 +37,7 @@ internal extension RUMUserActionType { var toRUMDataFormat: RUMActionEvent.Action.ActionType { switch self { case .tap: return .tap + case .click: return .click case .scroll: return .scroll case .swipe: return .swipe case .custom: return .custom diff --git a/Sources/Datadog/RUM/Debugging/RUMDebugging.swift b/Sources/Datadog/RUM/Debugging/RUMDebugging.swift index 5d1f49e2cb..382ad7971e 100644 --- a/Sources/Datadog/RUM/Debugging/RUMDebugging.swift +++ b/Sources/Datadog/RUM/Debugging/RUMDebugging.swift @@ -35,6 +35,7 @@ internal class RUMDebugging { // MARK: - Initialization + #if !os(tvOS) init() { DispatchQueue.main.async { UIDevice.current.beginGeneratingDeviceOrientationNotifications() @@ -62,6 +63,17 @@ internal class RUMDebugging { object: nil ) } + #else + init() { + } + + deinit { + let canvas = self.canvas + DispatchQueue.main.async { + canvas.removeFromSuperview() + } + } + #endif // MARK: - Internal diff --git a/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift b/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift index 424e483456..820232fa64 100644 --- a/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift +++ b/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift @@ -7,6 +7,8 @@ #if canImport(SwiftUI) import SwiftUI +#if !os(tvOS) + /// `SwiftUI.ViewModifier` for RUM which invoke `addUserAction` from the /// global RUM Monitor when the modified view receives a tap. @available(iOS 13, *) @@ -49,3 +51,4 @@ public extension SwiftUI.View { } #endif +#endif diff --git a/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIApplicationSwizzler.swift b/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIApplicationSwizzler.swift index a03843ca6c..a2e013d5e7 100644 --- a/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIApplicationSwizzler.swift +++ b/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIApplicationSwizzler.swift @@ -17,11 +17,9 @@ internal class UIApplicationSwizzler { sendEvent.swizzle() } -#if DD_SDK_COMPILED_FOR_TESTING - func unswizzle() { + internal func unswizzle() { sendEvent.unswizzle() } -#endif // MARK: - Swizzlings diff --git a/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandler.swift b/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandler.swift index 57b8f4437c..1ee048b5bf 100644 --- a/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandler.swift +++ b/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandler.swift @@ -10,13 +10,25 @@ internal protocol UIEventHandler: RUMCommandPublisher { func notify_sendEvent(application: UIApplication, event: UIEvent) } +internal protocol UIEventCommandFactory { + func command(from event: UIEvent) -> RUMAddUserActionCommand? +} + internal class UIKitRUMUserActionsHandler: UIEventHandler { - private let dateProvider: DateProvider - let predicate: UIKitRUMUserActionsPredicate + let factory: UIEventCommandFactory + + convenience init(dateProvider: DateProvider, predicate: UITouchRUMUserActionsPredicate) { + let factory = UITouchCommandFactory(dateProvider: dateProvider, predicate: predicate) + self.init(factory: factory) + } - init(dateProvider: DateProvider, predicate: UIKitRUMUserActionsPredicate) { - self.dateProvider = dateProvider - self.predicate = predicate + convenience init(dateProvider: DateProvider, predicate: UIPressRUMUserActionsPredicate) { + let factory = UIPressCommandFactory(dateProvider: dateProvider, predicate: predicate) + self.init(factory: factory) + } + + init(factory: UIEventCommandFactory) { + self.factory = factory } // MARK: - UIKitRUMUserActionsHandlerType @@ -28,17 +40,11 @@ internal class UIKitRUMUserActionsHandler: UIEventHandler { } func notify_sendEvent(application: UIApplication, event: UIEvent) { - guard let tappedView = captureSingleTouch(event: event)?.view else { + guard let command = factory.command(from: event) else { return // Not a "tap" event or doesn't have the view. } - guard isSafeForPrivacy(tappedView) else { - return // Ignore for privacy reason. - } - guard let actionTargetView = bestActionTarget(for: tappedView) else { - return // Tapped view is not eligible for producing RUM Action - } - if subscriber == nil { + guard let subscriber = subscriber else { userLogger.warn( """ RUM Action was detected, but no `RUMMonitor` is registered on `Global.rum`. RUM auto instrumentation will not work. @@ -48,22 +54,43 @@ internal class UIKitRUMUserActionsHandler: UIEventHandler { return } - if let rumAction = predicate.rumAction(targetView: actionTargetView) { - subscriber?.process( - command: RUMAddUserActionCommand( - time: dateProvider.currentDate(), - attributes: rumAction.attributes, - actionType: .tap, - name: rumAction.name - ) - ) + subscriber.process(command: command) + } +} + +private extension UIView { + /// Traverses the hierarchy of this view from bottom-up to find any parent view matching + /// the given predicate. It starts from `self`. + func findInParentHierarchy(viewMatching predicate: (UIView) -> Bool) -> UIView? { + if predicate(self) { + return self + } else if let superview = superview { + return superview.findInParentHierarchy(viewMatching: predicate) + } else { + return nil + } + } +} + +extension UIEventCommandFactory { + /// Tells if capturing given `UIView` is safe for the user privacy. + func isSafeForPrivacy(_ view: UIView) -> Bool { + guard let window = view.window else { + return false // The view is invisible, we can't determine if it's safe. + } + guard !NSStringFromClass(type(of: window)).contains("Keyboard") else { + return false // The window class name suggests that it's the on-screen keyboard. } + return true } +} - // MARK: - Events Filtering +internal struct UITouchCommandFactory: UIEventCommandFactory { + let dateProvider: DateProvider - /// Returns the `UITouch` for given `event` only if the event describes the "single tap ended" interaction. - private func captureSingleTouch(event: UIEvent) -> UITouch? { + let predicate: UITouchRUMUserActionsPredicate + + func command(from event: UIEvent) -> RUMAddUserActionCommand? { guard let allTouches = event.allTouches else { return nil // not a touch event } @@ -71,20 +98,23 @@ internal class UIKitRUMUserActionsHandler: UIEventHandler { return nil // not a single touch event } guard tap.phase == .ended else { - return nil // touch is not in the `.ended` phase + return nil // not in `.ended` phase } - return tap - } - - /// Tells if capturing given `UIView` is safe for the user privacy. - private func isSafeForPrivacy(_ view: UIView) -> Bool { - guard let window = view.window else { - return false // The view is invisible, we can't determine if it's safe. + guard let view = tap.view, isSafeForPrivacy(view) else { + return nil // no valid view } - guard !NSStringFromClass(type(of: window)).contains("Keyboard") else { - return false // The window class name suggests that it's the on-screen keyboard. + guard let targetView = bestActionTarget(for: view) else { + return nil // Tapped view is not eligible for producing RUM Action } - return true + guard let action = predicate.rumAction(targetView: targetView) else { + return nil + } + return RUMAddUserActionCommand( + time: dateProvider.currentDate(), + attributes: action.attributes, + actionType: .tap, + name: action.name + ) } // MARK: - RUM Action Target Capturing @@ -112,16 +142,32 @@ internal class UIKitRUMUserActionsHandler: UIEventHandler { } } -private extension UIView { - /// Traverses the hierarchy of this view from bottom-up to find any parent view matching - /// the given predicate. It starts from `self`. - func findInParentHierarchy(viewMatching predicate: (UIView) -> Bool) -> UIView? { - if predicate(self) { - return self - } else if let superview = superview { - return superview.findInParentHierarchy(viewMatching: predicate) - } else { +internal struct UIPressCommandFactory: UIEventCommandFactory { + let dateProvider: DateProvider + + let predicate: UIPressRUMUserActionsPredicate + + func command(from event: UIEvent) -> RUMAddUserActionCommand? { + guard let event = event as? UIPressesEvent else { + return nil // not a press event + } + guard event.allPresses.count == 1, let press = event.allPresses.first else { + return nil // not a single press event + } + guard press.phase == .ended else { + return nil // not in `.ended` phase + } + guard let view = press.responder as? UIView, isSafeForPrivacy(view) else { + return nil // no valid view + } + guard let action = predicate.rumAction(press: press.type, targetView: view) else { return nil } + return RUMAddUserActionCommand( + time: dateProvider.currentDate(), + attributes: action.attributes, + actionType: .click, + name: action.name + ) } } diff --git a/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsPredicate.swift b/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsPredicate.swift index 543b7c8045..558bae5f33 100644 --- a/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsPredicate.swift +++ b/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsPredicate.swift @@ -24,29 +24,41 @@ public struct RUMAction { } } +#if os(tvOS) +public typealias UIKitRUMUserActionsPredicate = UIPressRUMUserActionsPredicate +#else +public typealias UIKitRUMUserActionsPredicate = UITouchRUMUserActionsPredicate +#endif + /// The predicate deciding if a given RUM Action should be recorded. /// -/// When the app is running, the SDK will ask the implementation of `UIKitRUMUserActionsPredicate` if any noticed user action on the target view should +/// When the app is running, the SDK will ask the implementation of `UITouchRUMUserActionsPredicate` if any noticed user action on the target view should /// be considered as the RUM Action. The predicate implementation should return RUM Action parameters if it should be recorded or `nil` otherwise. -public protocol UIKitRUMUserActionsPredicate { +public protocol UITouchRUMUserActionsPredicate { /// The predicate deciding if the RUM Action should be recorded. /// - Parameter targetView: an instance of the `UIView` which received the action. /// - Returns: RUM Action if it should be recorded, `nil` otherwise. func rumAction(targetView: UIView) -> RUMAction? } +/// The predicate deciding if a given RUM Action should be recorded. +/// +/// When the app is running, the SDK will ask the implementation of `UIPressRUMUserActionsPredicate` if any noticed user action on the target view should +/// be considered as the RUM Action. The predicate implementation should return RUM Action parameters if it should be recorded or `nil` otherwise. +public protocol UIPressRUMUserActionsPredicate { + /// The predicate deciding if the RUM Action should be recorded. + /// - Parameters: + /// - type: the `UIPress.PressType` which received the action. + /// - targetView: an instance of the `UIView` which received the action. + /// - Returns: RUM Action if it should be recorded, `nil` otherwise. + func rumAction(press type: UIPress.PressType, targetView: UIView) -> RUMAction? +} + /// Default implementation of `UIKitRUMUserActionsPredicate`. /// It names RUM Actions by the `accessibilityIdentifier` or `className` otherwise. -public struct DefaultUIKitRUMUserActionsPredicate: UIKitRUMUserActionsPredicate { +public struct DefaultUIKitRUMUserActionsPredicate { public init () {} - public func rumAction(targetView: UIView) -> RUMAction? { - return RUMAction( - name: targetName(for: targetView), - attributes: [:] - ) - } - /// Builds the RUM Action's `target` name for given `UIView`. private func targetName(for view: UIView) -> String { let className = NSStringFromClass(type(of: view)) @@ -58,3 +70,31 @@ public struct DefaultUIKitRUMUserActionsPredicate: UIKitRUMUserActionsPredicate } } } + +extension DefaultUIKitRUMUserActionsPredicate: UITouchRUMUserActionsPredicate { + public func rumAction(targetView: UIView) -> RUMAction? { + return RUMAction( + name: targetName(for: targetView), + attributes: [:] + ) + } +} + +extension DefaultUIKitRUMUserActionsPredicate: UIPressRUMUserActionsPredicate { + public func rumAction(press type: UIPress.PressType, targetView: UIView) -> RUMAction? { + var name: String + + switch type { + case .select: + name = targetName(for: targetView) + case .menu: + name = "menu" + case .playPause: + name = "play-pause" + default: + return nil + } + + return RUMAction(name: name, attributes: [:]) + } +} diff --git a/Sources/Datadog/RUM/Instrumentation/RUMInstrumentation.swift b/Sources/Datadog/RUM/Instrumentation/RUMInstrumentation.swift index 922de7b545..ca8c622481 100644 --- a/Sources/Datadog/RUM/Instrumentation/RUMInstrumentation.swift +++ b/Sources/Datadog/RUM/Instrumentation/RUMInstrumentation.swift @@ -84,12 +84,10 @@ internal final class RUMInstrumentation: RUMCommandPublisher { longTasks?.publish(to: subscriber) } -#if DD_SDK_COMPILED_FOR_TESTING /// Removes RUM instrumentation swizzlings and deinitializes this component. - func deinitialize() { + internal func deinitialize() { viewControllerSwizzler?.unswizzle() userActionsAutoInstrumentation?.swizzler.unswizzle() RUMInstrumentation.instance = nil } -#endif } diff --git a/Sources/Datadog/RUM/Instrumentation/Views/SwiftUI/SwiftUIViewModifier.swift b/Sources/Datadog/RUM/Instrumentation/Views/SwiftUI/SwiftUIViewModifier.swift index bbc08096b2..efca7547ba 100644 --- a/Sources/Datadog/RUM/Instrumentation/Views/SwiftUI/SwiftUIViewModifier.swift +++ b/Sources/Datadog/RUM/Instrumentation/Views/SwiftUI/SwiftUIViewModifier.swift @@ -9,7 +9,7 @@ import SwiftUI /// `SwiftUI.ViewModifier` for RUM which invoke `startView` and `stopView` from the /// global RUM Monitor when the modified view appears and disappears. -@available(iOS 13, *) +@available(iOS 13, tvOS 13, *) internal struct RUMViewModifier: SwiftUI.ViewModifier { /// The Content View identifier. /// The id will be unique per modified view. @@ -41,7 +41,7 @@ internal struct RUMViewModifier: SwiftUI.ViewModifier { } } -@available(iOS 13, *) +@available(iOS 13, tvOS 13, *) public extension SwiftUI.View { /// Monitor this view with Datadog RUM. A start and stop events will be logged when this view appears /// and disappears. diff --git a/Sources/Datadog/RUM/Instrumentation/Views/UIKit/UIViewControllerSwizzler.swift b/Sources/Datadog/RUM/Instrumentation/Views/UIKit/UIViewControllerSwizzler.swift index 857f217806..00ab1092c7 100644 --- a/Sources/Datadog/RUM/Instrumentation/Views/UIKit/UIViewControllerSwizzler.swift +++ b/Sources/Datadog/RUM/Instrumentation/Views/UIKit/UIViewControllerSwizzler.swift @@ -20,12 +20,10 @@ internal class UIViewControllerSwizzler { viewDidDisappear.swizzle() } -#if DD_SDK_COMPILED_FOR_TESTING - func unswizzle() { + internal func unswizzle() { viewDidAppear.unswizzle() viewDidDisappear.unswizzle() } -#endif // MARK: - Swizzlings diff --git a/Sources/Datadog/RUM/RUMFeature.swift b/Sources/Datadog/RUM/RUMFeature.swift index e802d4562a..69a48f5fa9 100644 --- a/Sources/Datadog/RUM/RUMFeature.swift +++ b/Sources/Datadog/RUM/RUMFeature.swift @@ -105,7 +105,7 @@ internal final class RUMFeature { device: commonDependencies.mobileDevice ), .ddAPIKeyHeader(clientToken: configuration.clientToken), - .ddEVPOriginHeader(source: configuration.common.source), + .ddEVPOriginHeader(source: configuration.common.origin ?? configuration.common.source), .ddEVPOriginVersionHeader(sdkVersion: configuration.common.sdkVersion), .ddRequestIDHeader(), ], @@ -189,11 +189,9 @@ internal final class RUMFeature { self.onSessionStart = onSessionStart } -#if DD_SDK_COMPILED_FOR_TESTING - func deinitialize() { + internal func deinitialize() { storage.flushAndTearDown() upload.flushAndTearDown() RUMFeature.instance = nil } -#endif } diff --git a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMApplicationScope.swift b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMApplicationScope.swift index 56c1bd9344..8844aa16df 100644 --- a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMApplicationScope.swift +++ b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMApplicationScope.swift @@ -23,6 +23,8 @@ internal struct RUMScopeDependencies { /// Integration with Crash Reporting. It updates the crash context with RUM info. /// `nil` if Crash Reporting feature is not enabled. let crashContextIntegration: RUMWithCrashContextIntegration? + /// Integration with CIApp tests. It contains the CIApp test context when active. + let ciTest: RUMCITest? let vitalCPUReader: SamplingBasedVitalReader let vitalMemoryReader: SamplingBasedVitalReader diff --git a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMResourceScope.swift b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMResourceScope.swift index 25cc393749..7d79f0d457 100644 --- a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMResourceScope.swift +++ b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMResourceScope.swift @@ -139,7 +139,7 @@ internal class RUMResourceScope: RUMScope { .init(id: rumUUID.toRUMDataFormat) }, application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: resourceStartTime).timeIntervalSince1970.toInt64Milliseconds, @@ -190,7 +190,11 @@ internal class RUMResourceScope: RUMScope { url: resourceURL ), service: dependencies.serviceName, - session: .init(hasReplay: nil, id: context.sessionID.toRUMDataFormat, type: .user), + session: .init( + hasReplay: nil, + id: context.sessionID.toRUMDataFormat, + type: dependencies.ciTest != nil ? .ciTest : .user + ), source: .ios, synthetics: nil, usr: dependencies.userInfoProvider.current, @@ -221,7 +225,7 @@ internal class RUMResourceScope: RUMScope { .init(id: rumUUID.toRUMDataFormat) }, application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: command.time).timeIntervalSince1970.toInt64Milliseconds, @@ -243,7 +247,11 @@ internal class RUMResourceScope: RUMScope { type: command.errorType ), service: dependencies.serviceName, - session: .init(hasReplay: nil, id: context.sessionID.toRUMDataFormat, type: .user), + session: .init( + hasReplay: nil, + id: context.sessionID.toRUMDataFormat, + type: dependencies.ciTest != nil ? .ciTest : .user + ), source: .ios, synthetics: nil, usr: dependencies.userInfoProvider.current, diff --git a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMUserActionScope.swift b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMUserActionScope.swift index ef9cd3e573..733b3548bf 100644 --- a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMUserActionScope.swift +++ b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMUserActionScope.swift @@ -148,12 +148,16 @@ internal class RUMUserActionScope: RUMScope, RUMContextProvider { type: actionType.toRUMDataFormat ), application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: actionStartTime).timeIntervalSince1970.toInt64Milliseconds, service: dependencies.serviceName, - session: .init(hasReplay: nil, id: context.sessionID.toRUMDataFormat, type: .user), + session: .init( + hasReplay: nil, + id: context.sessionID.toRUMDataFormat, + type: dependencies.ciTest != nil ? .ciTest : .user + ), source: .ios, synthetics: nil, usr: dependencies.userInfoProvider.current, diff --git a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift index 5db56123be..93680472a8 100644 --- a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift +++ b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift @@ -10,6 +10,8 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { struct Constants { static let frozenFrameThresholdInNs = (0.07).toInt64Nanoseconds // 70ms static let slowRenderingThresholdFPS = 55.0 + /// The pre-warming detection attribute key + static let activePrewarm = "active_pre_warm" } // MARK: - Child Scopes @@ -123,7 +125,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { // Send "application start" action if this is the very first view tracked in the app let hasSentNoViewUpdatesYet = version == 0 - if isInitialView && hasSentNoViewUpdatesYet { + if isInitialView, hasSentNoViewUpdatesYet { actionsCount += 1 if !sendApplicationStartAction() { actionsCount -= 1 @@ -284,10 +286,10 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { let customActionScope = createDiscreteUserActionScope(on: command) _ = customActionScope.process( command: RUMStopUserActionCommand( - time: command.time, - attributes: [:], - actionType: .custom, - name: nil + time: command.time, + attributes: [:], + actionType: .custom, + name: nil ) ) } @@ -303,6 +305,18 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { // MARK: - Sending RUM Events private func sendApplicationStartAction() -> Bool { + var attributes = self.attributes + var loadingTime: Int64? = nil + + if dependencies.launchTimeProvider.isActivePrewarm { + // Set `active_pre_warm` attribute to true in case + // of pre-warmed app + attributes[Constants.activePrewarm] = true + } else { + // Report Application Launch Time only if not pre-warmed + loadingTime = dependencies.launchTimeProvider.launchTime.toInt64Nanoseconds + } + let eventData = RUMActionEvent( dd: .init( browserSdkVersion: nil, @@ -312,19 +326,23 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { crash: nil, error: nil, id: dependencies.rumUUIDGenerator.generateUnique().toRUMDataFormat, - loadingTime: dependencies.launchTimeProvider.launchTime.toInt64Nanoseconds, + loadingTime: loadingTime, longTask: nil, resource: nil, target: nil, type: .applicationStart ), application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: viewStartTime).timeIntervalSince1970.toInt64Milliseconds, service: dependencies.serviceName, - session: .init(hasReplay: nil, id: context.sessionID.toRUMDataFormat, type: .user), + session: .init( + hasReplay: nil, + id: context.sessionID.toRUMDataFormat, + type: dependencies.ciTest != nil ? .ciTest : .user + ), source: .ios, synthetics: nil, usr: dependencies.userInfoProvider.current, @@ -364,12 +382,16 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { session: .init(plan: .plan1) ), application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: viewStartTime).timeIntervalSince1970.toInt64Milliseconds, service: dependencies.serviceName, - session: .init(hasReplay: nil, id: context.sessionID.toRUMDataFormat, type: .user), + session: .init( + hasReplay: nil, + id: context.sessionID.toRUMDataFormat, + type: dependencies.ciTest != nil ? .ciTest : .user + ), source: .ios, synthetics: nil, usr: dependencies.userInfoProvider.current, @@ -433,7 +455,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { .init(id: rumUUID.toRUMDataFormat) }, application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: command.time).timeIntervalSince1970.toInt64Milliseconds, @@ -450,7 +472,11 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { type: command.type ), service: dependencies.serviceName, - session: .init(hasReplay: nil, id: context.sessionID.toRUMDataFormat, type: .user), + session: .init( + hasReplay: nil, + id: context.sessionID.toRUMDataFormat, + type: dependencies.ciTest != nil ? .ciTest : .user + ), source: .ios, synthetics: nil, usr: dependencies.userInfoProvider.current, @@ -475,21 +501,24 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { let taskDurationInNs = command.duration.toInt64Nanoseconds let isFrozenFrame = taskDurationInNs > Constants.frozenFrameThresholdInNs - let eventData = RUMLongTaskEvent( dd: .init( - browserSdkVersion: nil, - session: .init(plan: .plan1) + browserSdkVersion: nil, + session: .init(plan: .plan1) ), action: context.activeUserActionID.flatMap { RUMLongTaskEvent.Action(id: $0.toRUMDataFormat) }, application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: command.time - command.duration).timeIntervalSince1970.toInt64Milliseconds, longTask: .init(duration: taskDurationInNs, id: nil, isFrozenFrame: isFrozenFrame), service: dependencies.serviceName, - session: .init(hasReplay: nil, id: context.sessionID.toRUMDataFormat, type: .user), + session: .init( + hasReplay: nil, + id: context.sessionID.toRUMDataFormat, + type: dependencies.ciTest != nil ? .ciTest : .user + ), source: .ios, synthetics: nil, usr: dependencies.userInfoProvider.current, diff --git a/Sources/Datadog/RUMMonitor.swift b/Sources/Datadog/RUMMonitor.swift index 765b0ce728..d4cdc7b52d 100644 --- a/Sources/Datadog/RUMMonitor.swift +++ b/Sources/Datadog/RUMMonitor.swift @@ -76,6 +76,7 @@ internal extension RUMErrorSourceType { /// Describes the type of a RUM Action. public enum RUMUserActionType { case tap + case click case scroll case swipe case custom @@ -195,6 +196,7 @@ public class RUMMonitor: DDRUMMonitor, RUMCommandSubscriber { rumUUIDGenerator: rumFeature.configuration.uuidGenerator, dateCorrector: rumFeature.dateCorrector, crashContextIntegration: RUMWithCrashContextIntegration(), + ciTest: CITestIntegration.active?.rumCITest, vitalCPUReader: rumFeature.vitalCPUReader, vitalMemoryReader: rumFeature.vitalMemoryReader, vitalRefreshRateReader: rumFeature.vitalRefreshRateReader, @@ -221,6 +223,8 @@ public class RUMMonitor: DDRUMMonitor, RUMCommandSubscriber { if Datadog.debugRUM { self.enableRUMDebugging(true) } + + CITestIntegration.active?.startIntegration() } // MARK: - Public DDRUMMonitor conformance diff --git a/Sources/Datadog/Tracer.swift b/Sources/Datadog/Tracer.swift index 6b69fdc52a..2221101f3c 100644 --- a/Sources/Datadog/Tracer.swift +++ b/Sources/Datadog/Tracer.swift @@ -55,8 +55,6 @@ public class Tracer: OTTracer { internal let queue: DispatchQueue /// Integration with RUM Context. `nil` if disabled for this Tracer or if the RUM feature disabled. internal let rumContextIntegration: TracingWithRUMContextIntegration? - /// Integration with Span context injected by environment. - internal let environmentSpanIntegration = TracingWithEnvironmentSpanIntegration() private let dateProvider: DateProvider private let tracingUUIDGenerator: TracingUUIDGenerator @@ -108,6 +106,7 @@ public class Tracer: OTTracer { carrierInfoProvider: tracerConfiguration.sendNetworkInfo ? tracingFeature.carrierInfoProvider : nil, dateCorrector: tracingFeature.dateCorrector, source: tracingFeature.configuration.common.source, + origin: tracingFeature.configuration.common.origin , eventsMapper: tracingFeature.configuration.spanEventMapper ), spanOutput: SpanFileOutput( @@ -188,9 +187,9 @@ public class Tracer: OTTracer { internal func createSpanContext(parentSpanContext: DDSpanContext? = nil) -> DDSpanContext { return DDSpanContext( - traceID: parentSpanContext?.traceID ?? (environmentSpanIntegration.environmentSpanContext?.traceID ?? tracingUUIDGenerator.generateUnique()), + traceID: parentSpanContext?.traceID ?? tracingUUIDGenerator.generateUnique(), spanID: tracingUUIDGenerator.generateUnique(), - parentSpanID: parentSpanContext?.spanID ?? environmentSpanIntegration.environmentSpanContext?.spanID, + parentSpanID: parentSpanContext?.spanID, baggageItems: BaggageItems(targetQueue: queue, parentSpanItems: parentSpanContext?.baggageItems) ) } diff --git a/Sources/Datadog/Tracing/Span/SpanEventBuilder.swift b/Sources/Datadog/Tracing/Span/SpanEventBuilder.swift index 345c956123..499cebcc57 100644 --- a/Sources/Datadog/Tracing/Span/SpanEventBuilder.swift +++ b/Sources/Datadog/Tracing/Span/SpanEventBuilder.swift @@ -24,6 +24,8 @@ internal struct SpanEventBuilder { let dateCorrector: DateCorrectorType /// Source tag to encode in span (e.g. `ios` for native iOS). let source: String + /// Optional Origin tag to encode in span (e.g. `ciapp-test`). + let origin: String? /// Span events mapper configured by the user, `nil` if not set. let eventsMapper: SpanEventMapper? @@ -69,6 +71,7 @@ internal struct SpanEventBuilder { duration: finishTime.timeIntervalSince(startTime), isError: tagsReducer.extractedIsError ?? false, source: source, + origin: origin, tracerVersion: sdkVersion, applicationVersion: applicationVersion, networkConnectionInfo: networkConnectionInfoProvider?.current, diff --git a/Sources/Datadog/Tracing/Span/SpanEventEncoder.swift b/Sources/Datadog/Tracing/Span/SpanEventEncoder.swift index 7f37f563a3..d421d6f137 100644 --- a/Sources/Datadog/Tracing/Span/SpanEventEncoder.swift +++ b/Sources/Datadog/Tracing/Span/SpanEventEncoder.swift @@ -53,6 +53,8 @@ public struct SpanEvent: Encodable { public let isError: Bool /// Name of the component sourcing the span, for iOS SDK it is set to `ios`. internal let source: String + /// The origin for the Span, it is used to label the spans used created under testing + internal let origin: String? // MARK: - Meta @@ -116,6 +118,8 @@ internal struct SpanEventEncoder { case applicationVersion = "meta.version" case tracerVersion = "meta.tracer.version" + case origin = "meta._dd.origin" + case userId = "meta.usr.id" case userName = "meta.usr.name" case userEmail = "meta.usr.email" @@ -184,6 +188,8 @@ internal struct SpanEventEncoder { try container.encode(span.tracerVersion, forKey: .tracerVersion) try container.encode(span.applicationVersion, forKey: .applicationVersion) + try span.origin.ifNotNil { try container.encode($0, forKey: .origin) } + try span.userInfo.id.ifNotNil { try container.encode($0, forKey: .userId) } try span.userInfo.name.ifNotNil { try container.encode($0, forKey: .userName) } try span.userInfo.email.ifNotNil { try container.encode($0, forKey: .userEmail) } diff --git a/Sources/Datadog/Tracing/TracingFeature.swift b/Sources/Datadog/Tracing/TracingFeature.swift index 4425087a9b..e1a20d2a1c 100644 --- a/Sources/Datadog/Tracing/TracingFeature.swift +++ b/Sources/Datadog/Tracing/TracingFeature.swift @@ -90,7 +90,7 @@ internal final class TracingFeature { device: commonDependencies.mobileDevice ), .ddAPIKeyHeader(clientToken: configuration.clientToken), - .ddEVPOriginHeader(source: configuration.common.source), + .ddEVPOriginHeader(source: configuration.common.origin ?? configuration.common.source), .ddEVPOriginVersionHeader(sdkVersion: configuration.common.sdkVersion), .ddRequestIDHeader(), ], @@ -157,11 +157,9 @@ internal final class TracingFeature { self.upload = upload } -#if DD_SDK_COMPILED_FOR_TESTING - func deinitialize() { + internal func deinitialize() { storage.flushAndTearDown() upload.flushAndTearDown() TracingFeature.instance = nil } -#endif } diff --git a/Sources/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegate.swift b/Sources/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegate.swift index 5cd529cbbf..5814bc8585 100644 --- a/Sources/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegate.swift +++ b/Sources/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegate.swift @@ -56,7 +56,7 @@ open class DDURLSessionDelegate: NSObject, URLSessionTaskDelegate, URLSessionDat interceptor?.taskCompleted(task: task, error: error) } - public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { + open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { // NOTE: This delegate method is only called for `URLSessionTasks` created without the completion handler. interceptor?.taskReceivedData(task: dataTask, data: data) diff --git a/Sources/Datadog/URLSessionAutoInstrumentation/Interception/TaskInterception.swift b/Sources/Datadog/URLSessionAutoInstrumentation/Interception/TaskInterception.swift index 7d0403e8e6..72b6a5a746 100644 --- a/Sources/Datadog/URLSessionAutoInstrumentation/Interception/TaskInterception.swift +++ b/Sources/Datadog/URLSessionAutoInstrumentation/Interception/TaskInterception.swift @@ -178,7 +178,7 @@ extension ResourceMetrics { download = DateInterval(start: downloadStart, end: downloadEnd) } - if #available(iOS 13.0, *) { + if #available(iOS 13.0, tvOS 13, *) { responseSize = mainTransaction.countOfResponseBodyBytesAfterDecoding } } diff --git a/Sources/Datadog/URLSessionAutoInstrumentation/URLSessionAutoInstrumentation.swift b/Sources/Datadog/URLSessionAutoInstrumentation/URLSessionAutoInstrumentation.swift index ba06f212ee..450a9d88e9 100644 --- a/Sources/Datadog/URLSessionAutoInstrumentation/URLSessionAutoInstrumentation.swift +++ b/Sources/Datadog/URLSessionAutoInstrumentation/URLSessionAutoInstrumentation.swift @@ -48,11 +48,9 @@ internal final class URLSessionAutoInstrumentation: RUMCommandPublisher { rumResourceHandler?.publish(to: subscriber) } -#if DD_SDK_COMPILED_FOR_TESTING /// Removes `URLSession` swizzling and deinitializes this component. - func deinitialize() { + internal func deinitialize() { swizzler.unswizzle() URLSessionAutoInstrumentation.instance = nil } -#endif } diff --git a/Sources/Datadog/URLSessionAutoInstrumentation/URLSessionSwizzler.swift b/Sources/Datadog/URLSessionAutoInstrumentation/URLSessionSwizzler.swift index fe434a84dd..7d30bd2360 100644 --- a/Sources/Datadog/URLSessionAutoInstrumentation/URLSessionSwizzler.swift +++ b/Sources/Datadog/URLSessionAutoInstrumentation/URLSessionSwizzler.swift @@ -39,14 +39,12 @@ internal class URLSessionSwizzler { dataTaskWithURL?.swizzle() } -#if DD_SDK_COMPILED_FOR_TESTING - func unswizzle() { + internal func unswizzle() { dataTaskWithURLRequestAndCompletion.unswizzle() dataTaskWithURLRequest.unswizzle() dataTaskWithURLAndCompletion?.unswizzle() dataTaskWithURL?.unswizzle() } -#endif // MARK: - Swizzlings diff --git a/Sources/Datadog/Utils/Globals.swift b/Sources/Datadog/Utils/Globals.swift index 1f6b7e0fd4..22045c862a 100644 --- a/Sources/Datadog/Utils/Globals.swift +++ b/Sources/Datadog/Utils/Globals.swift @@ -11,9 +11,7 @@ import _Datadog_Private #endif /// Function printing `String` content to console. -internal var consolePrint: (String) -> Void = { content in - print(content) -} +public var consolePrint: (String) -> Void = { print($0) } /// Exception handler rethrowing `NSExceptions` to Swift `NSError`. internal var objcExceptionHandler = __dd_private_ObjcExceptionHandler() diff --git a/Sources/Datadog/Utils/SwiftUIExtensions.swift b/Sources/Datadog/Utils/SwiftUIExtensions.swift index 072fb22b57..03cd77fc13 100644 --- a/Sources/Datadog/Utils/SwiftUIExtensions.swift +++ b/Sources/Datadog/Utils/SwiftUIExtensions.swift @@ -18,7 +18,7 @@ internal extension Bundle { } #if canImport(SwiftUI) -@available(iOS 13, *) +@available(iOS 13, tvOS 13, *) internal extension SwiftUI.View { /// The Type descriptionof this view. var typeDescription: String { diff --git a/Sources/Datadog/Versioning.swift b/Sources/Datadog/Versioning.swift index 37b43bf44c..711cb64ce1 100644 --- a/Sources/Datadog/Versioning.swift +++ b/Sources/Datadog/Versioning.swift @@ -1,3 +1,3 @@ // GENERATED FILE: Do not edit directly -internal let __sdkVersion = "1.9.0" +internal let __sdkVersion = "1.10.0-beta1" diff --git a/Sources/DatadogCrashReporting/PLCrashReporterIntegration/DDCrashReportExporter.swift b/Sources/DatadogCrashReporting/PLCrashReporterIntegration/DDCrashReportExporter.swift index 4e243f8c1f..5d3f8e46b9 100644 --- a/Sources/DatadogCrashReporting/PLCrashReporterIntegration/DDCrashReportExporter.swift +++ b/Sources/DatadogCrashReporting/PLCrashReporterIntegration/DDCrashReportExporter.swift @@ -122,7 +122,22 @@ internal struct DDCrashReportExporter { return unavailable // should never be reached } - return string(from: stackFrames) + return string(from: sanitized(stackFrames: stackFrames)) + } + + // MARK: - Sanitizing + + private func sanitized(stackFrames: [StackFrame]) -> [StackFrame] { + guard let lastFrame = stackFrames.last else { + return stackFrames + } + + // RUMM-2025: Often the last frame has no library name nor its base address. This results with + // producing malformed frame, e.g. `XX ??? 0x00000001045f0250 0x000000000 + 4368302672` + // which can't be symbolicated. To make it cleaner in UI and to avoid BE symbolication errors, we filter + // out such trailing frame. Ref.: https://github.com/microsoft/plcrashreporter/issues/193 + let sanitizedFrames = lastFrame.libraryBaseAddress == nil ? stackFrames.dropLast() : stackFrames + return sanitizedFrames } // MARK: - Exporting threads and binary images @@ -131,7 +146,7 @@ internal struct DDCrashReportExporter { return crashReport.threads.map { thread in return DDCrashReport.Thread( name: "Thread \(thread.threadNumber)", - stack: string(from: thread.stackFrames), + stack: string(from: thread.stackFrames), // we don't sanitize frames in `error.threads[]` crashed: thread.crashed, state: nil // TODO: RUMM-1462 Send registers state for crashed thread ) diff --git a/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift b/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift index 001b65d7db..30d1d5afa6 100644 --- a/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift +++ b/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift @@ -12,32 +12,36 @@ import Foundation // swiftlint:disable force_unwrapping @objc -public class DDRUMViewEvent: NSObject { - internal var swiftModel: RUMViewEvent - internal var root: DDRUMViewEvent { self } +public class DDRUMActionEvent: NSObject { + internal var swiftModel: RUMActionEvent + internal var root: DDRUMActionEvent { self } - internal init(swiftModel: RUMViewEvent) { + internal init(swiftModel: RUMActionEvent) { self.swiftModel = swiftModel } - @objc public var dd: DDRUMViewEventDD { - DDRUMViewEventDD(root: root) + @objc public var dd: DDRUMActionEventDD { + DDRUMActionEventDD(root: root) } - @objc public var application: DDRUMViewEventApplication { - DDRUMViewEventApplication(root: root) + @objc public var action: DDRUMActionEventAction { + DDRUMActionEventAction(root: root) } - @objc public var ciTest: DDRUMViewEventCiTest? { - root.swiftModel.ciTest != nil ? DDRUMViewEventCiTest(root: root) : nil + @objc public var application: DDRUMActionEventApplication { + DDRUMActionEventApplication(root: root) } - @objc public var connectivity: DDRUMViewEventRUMConnectivity? { - root.swiftModel.connectivity != nil ? DDRUMViewEventRUMConnectivity(root: root) : nil + @objc public var ciTest: DDRUMActionEventRUMCITest? { + root.swiftModel.ciTest != nil ? DDRUMActionEventRUMCITest(root: root) : nil } - @objc public var context: DDRUMViewEventRUMEventAttributes? { - root.swiftModel.context != nil ? DDRUMViewEventRUMEventAttributes(root: root) : nil + @objc public var connectivity: DDRUMActionEventRUMConnectivity? { + root.swiftModel.connectivity != nil ? DDRUMActionEventRUMConnectivity(root: root) : nil + } + + @objc public var context: DDRUMActionEventRUMEventAttributes? { + root.swiftModel.context != nil ? DDRUMActionEventRUMEventAttributes(root: root) : nil } @objc public var date: NSNumber { @@ -48,36 +52,36 @@ public class DDRUMViewEvent: NSObject { root.swiftModel.service } - @objc public var session: DDRUMViewEventSession { - DDRUMViewEventSession(root: root) + @objc public var session: DDRUMActionEventSession { + DDRUMActionEventSession(root: root) } - @objc public var source: DDRUMViewEventSource { + @objc public var source: DDRUMActionEventSource { .init(swift: root.swiftModel.source) } - @objc public var synthetics: DDRUMViewEventSynthetics? { - root.swiftModel.synthetics != nil ? DDRUMViewEventSynthetics(root: root) : nil + @objc public var synthetics: DDRUMActionEventSynthetics? { + root.swiftModel.synthetics != nil ? DDRUMActionEventSynthetics(root: root) : nil } @objc public var type: String { root.swiftModel.type } - @objc public var usr: DDRUMViewEventRUMUser? { - root.swiftModel.usr != nil ? DDRUMViewEventRUMUser(root: root) : nil + @objc public var usr: DDRUMActionEventRUMUser? { + root.swiftModel.usr != nil ? DDRUMActionEventRUMUser(root: root) : nil } - @objc public var view: DDRUMViewEventView { - DDRUMViewEventView(root: root) + @objc public var view: DDRUMActionEventView { + DDRUMActionEventView(root: root) } } @objc -public class DDRUMViewEventDD: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMActionEventDD: NSObject { + internal let root: DDRUMActionEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMActionEvent) { self.root = root } @@ -85,42 +89,38 @@ public class DDRUMViewEventDD: NSObject { root.swiftModel.dd.browserSdkVersion } - @objc public var documentVersion: NSNumber { - root.swiftModel.dd.documentVersion as NSNumber - } - @objc public var formatVersion: NSNumber { root.swiftModel.dd.formatVersion as NSNumber } - @objc public var session: DDRUMViewEventDDSession? { - root.swiftModel.dd.session != nil ? DDRUMViewEventDDSession(root: root) : nil + @objc public var session: DDRUMActionEventDDSession? { + root.swiftModel.dd.session != nil ? DDRUMActionEventDDSession(root: root) : nil } } @objc -public class DDRUMViewEventDDSession: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMActionEventDDSession: NSObject { + internal let root: DDRUMActionEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMActionEvent) { self.root = root } - @objc public var plan: DDRUMViewEventDDSessionPlan { + @objc public var plan: DDRUMActionEventDDSessionPlan { .init(swift: root.swiftModel.dd.session!.plan) } } @objc -public enum DDRUMViewEventDDSessionPlan: Int { - internal init(swift: RUMViewEvent.DD.Session.Plan) { +public enum DDRUMActionEventDDSessionPlan: Int { + internal init(swift: RUMActionEvent.DD.Session.Plan) { switch swift { case .plan1: self = .plan1 case .plan2: self = .plan2 } } - internal var toSwift: RUMViewEvent.DD.Session.Plan { + internal var toSwift: RUMActionEvent.DD.Session.Plan { switch self { case .plan1: return .plan1 case .plan2: return .plan2 @@ -132,10 +132,152 @@ public enum DDRUMViewEventDDSessionPlan: Int { } @objc -public class DDRUMViewEventApplication: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMActionEventAction: NSObject { + internal let root: DDRUMActionEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMActionEvent) { + self.root = root + } + + @objc public var crash: DDRUMActionEventActionCrash? { + root.swiftModel.action.crash != nil ? DDRUMActionEventActionCrash(root: root) : nil + } + + @objc public var error: DDRUMActionEventActionError? { + root.swiftModel.action.error != nil ? DDRUMActionEventActionError(root: root) : nil + } + + @objc public var id: String? { + root.swiftModel.action.id + } + + @objc public var loadingTime: NSNumber? { + root.swiftModel.action.loadingTime as NSNumber? + } + + @objc public var longTask: DDRUMActionEventActionLongTask? { + root.swiftModel.action.longTask != nil ? DDRUMActionEventActionLongTask(root: root) : nil + } + + @objc public var resource: DDRUMActionEventActionResource? { + root.swiftModel.action.resource != nil ? DDRUMActionEventActionResource(root: root) : nil + } + + @objc public var target: DDRUMActionEventActionTarget? { + root.swiftModel.action.target != nil ? DDRUMActionEventActionTarget(root: root) : nil + } + + @objc public var type: DDRUMActionEventActionActionType { + .init(swift: root.swiftModel.action.type) + } +} + +@objc +public class DDRUMActionEventActionCrash: NSObject { + internal let root: DDRUMActionEvent + + internal init(root: DDRUMActionEvent) { + self.root = root + } + + @objc public var count: NSNumber { + root.swiftModel.action.crash!.count as NSNumber + } +} + +@objc +public class DDRUMActionEventActionError: NSObject { + internal let root: DDRUMActionEvent + + internal init(root: DDRUMActionEvent) { + self.root = root + } + + @objc public var count: NSNumber { + root.swiftModel.action.error!.count as NSNumber + } +} + +@objc +public class DDRUMActionEventActionLongTask: NSObject { + internal let root: DDRUMActionEvent + + internal init(root: DDRUMActionEvent) { + self.root = root + } + + @objc public var count: NSNumber { + root.swiftModel.action.longTask!.count as NSNumber + } +} + +@objc +public class DDRUMActionEventActionResource: NSObject { + internal let root: DDRUMActionEvent + + internal init(root: DDRUMActionEvent) { + self.root = root + } + + @objc public var count: NSNumber { + root.swiftModel.action.resource!.count as NSNumber + } +} + +@objc +public class DDRUMActionEventActionTarget: NSObject { + internal let root: DDRUMActionEvent + + internal init(root: DDRUMActionEvent) { + self.root = root + } + + @objc public var name: String { + set { root.swiftModel.action.target!.name = newValue } + get { root.swiftModel.action.target!.name } + } +} + +@objc +public enum DDRUMActionEventActionActionType: Int { + internal init(swift: RUMActionEvent.Action.ActionType) { + switch swift { + case .custom: self = .custom + case .click: self = .click + case .tap: self = .tap + case .scroll: self = .scroll + case .swipe: self = .swipe + case .applicationStart: self = .applicationStart + case .back: self = .back + } + } + + internal var toSwift: RUMActionEvent.Action.ActionType { + switch self { + case .custom: return .custom + case .click: return .click + case .tap: return .tap + case .scroll: return .scroll + case .swipe: return .swipe + case .applicationStart: return .applicationStart + case .back: return .back + } + } + + case custom + case click + case tap + case scroll + case swipe + case applicationStart + case back +} + +@objc +public class DDRUMActionEventApplication: NSObject { + internal let root: DDRUMActionEvent + + internal init(root: DDRUMActionEvent) { self.root = root } @@ -145,10 +287,10 @@ public class DDRUMViewEventApplication: NSObject { } @objc -public class DDRUMViewEventCiTest: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMActionEventRUMCITest: NSObject { + internal let root: DDRUMActionEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMActionEvent) { self.root = root } @@ -158,31 +300,31 @@ public class DDRUMViewEventCiTest: NSObject { } @objc -public class DDRUMViewEventRUMConnectivity: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMActionEventRUMConnectivity: NSObject { + internal let root: DDRUMActionEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMActionEvent) { self.root = root } - @objc public var cellular: DDRUMViewEventRUMConnectivityCellular? { - root.swiftModel.connectivity!.cellular != nil ? DDRUMViewEventRUMConnectivityCellular(root: root) : nil + @objc public var cellular: DDRUMActionEventRUMConnectivityCellular? { + root.swiftModel.connectivity!.cellular != nil ? DDRUMActionEventRUMConnectivityCellular(root: root) : nil } @objc public var interfaces: [Int] { - root.swiftModel.connectivity!.interfaces.map { DDRUMViewEventRUMConnectivityInterfaces(swift: $0).rawValue } + root.swiftModel.connectivity!.interfaces.map { DDRUMActionEventRUMConnectivityInterfaces(swift: $0).rawValue } } - @objc public var status: DDRUMViewEventRUMConnectivityStatus { + @objc public var status: DDRUMActionEventRUMConnectivityStatus { .init(swift: root.swiftModel.connectivity!.status) } } @objc -public class DDRUMViewEventRUMConnectivityCellular: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMActionEventRUMConnectivityCellular: NSObject { + internal let root: DDRUMActionEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMActionEvent) { self.root = root } @@ -196,7 +338,7 @@ public class DDRUMViewEventRUMConnectivityCellular: NSObject { } @objc -public enum DDRUMViewEventRUMConnectivityInterfaces: Int { +public enum DDRUMActionEventRUMConnectivityInterfaces: Int { internal init(swift: RUMConnectivity.Interfaces) { switch swift { case .bluetooth: self = .bluetooth @@ -237,7 +379,7 @@ public enum DDRUMViewEventRUMConnectivityInterfaces: Int { } @objc -public enum DDRUMViewEventRUMConnectivityStatus: Int { +public enum DDRUMActionEventRUMConnectivityStatus: Int { internal init(swift: RUMConnectivity.Status) { switch swift { case .connected: self = .connected @@ -260,10 +402,10 @@ public enum DDRUMViewEventRUMConnectivityStatus: Int { } @objc -public class DDRUMViewEventRUMEventAttributes: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMActionEventRUMEventAttributes: NSObject { + internal let root: DDRUMActionEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMActionEvent) { self.root = root } @@ -273,10 +415,10 @@ public class DDRUMViewEventRUMEventAttributes: NSObject { } @objc -public class DDRUMViewEventSession: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMActionEventSession: NSObject { + internal let root: DDRUMActionEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMActionEvent) { self.root = root } @@ -288,14 +430,14 @@ public class DDRUMViewEventSession: NSObject { root.swiftModel.session.id } - @objc public var type: DDRUMViewEventSessionSessionType { + @objc public var type: DDRUMActionEventSessionSessionType { .init(swift: root.swiftModel.session.type) } } @objc -public enum DDRUMViewEventSessionSessionType: Int { - internal init(swift: RUMViewEvent.Session.SessionType) { +public enum DDRUMActionEventSessionSessionType: Int { + internal init(swift: RUMActionEvent.Session.SessionType) { switch swift { case .user: self = .user case .synthetics: self = .synthetics @@ -303,7 +445,7 @@ public enum DDRUMViewEventSessionSessionType: Int { } } - internal var toSwift: RUMViewEvent.Session.SessionType { + internal var toSwift: RUMActionEvent.Session.SessionType { switch self { case .user: return .user case .synthetics: return .synthetics @@ -317,8 +459,8 @@ public enum DDRUMViewEventSessionSessionType: Int { } @objc -public enum DDRUMViewEventSource: Int { - internal init(swift: RUMViewEvent.Source?) { +public enum DDRUMActionEventSource: Int { + internal init(swift: RUMActionEvent.Source?) { switch swift { case nil: self = .none case .android?: self = .android @@ -329,7 +471,7 @@ public enum DDRUMViewEventSource: Int { } } - internal var toSwift: RUMViewEvent.Source? { + internal var toSwift: RUMActionEvent.Source? { switch self { case .none: return nil case .android: return .android @@ -349,10 +491,10 @@ public enum DDRUMViewEventSource: Int { } @objc -public class DDRUMViewEventSynthetics: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMActionEventSynthetics: NSObject { + internal let root: DDRUMActionEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMActionEvent) { self.root = root } @@ -370,10 +512,10 @@ public class DDRUMViewEventSynthetics: NSObject { } @objc -public class DDRUMViewEventRUMUser: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMActionEventRUMUser: NSObject { + internal let root: DDRUMActionEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMActionEvent) { self.root = root } @@ -395,903 +537,1055 @@ public class DDRUMViewEventRUMUser: NSObject { } @objc -public class DDRUMViewEventView: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMActionEventView: NSObject { + internal let root: DDRUMActionEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMActionEvent) { self.root = root } - @objc public var action: DDRUMViewEventViewAction { - DDRUMViewEventViewAction(root: root) + @objc public var id: String { + root.swiftModel.view.id } - @objc public var cpuTicksCount: NSNumber? { - root.swiftModel.view.cpuTicksCount as NSNumber? + @objc public var inForeground: NSNumber? { + root.swiftModel.view.inForeground as NSNumber? } - @objc public var cpuTicksPerSecond: NSNumber? { - root.swiftModel.view.cpuTicksPerSecond as NSNumber? + @objc public var name: String? { + set { root.swiftModel.view.name = newValue } + get { root.swiftModel.view.name } } - @objc public var crash: DDRUMViewEventViewCrash? { - root.swiftModel.view.crash != nil ? DDRUMViewEventViewCrash(root: root) : nil + @objc public var referrer: String? { + set { root.swiftModel.view.referrer = newValue } + get { root.swiftModel.view.referrer } } - @objc public var cumulativeLayoutShift: NSNumber? { - root.swiftModel.view.cumulativeLayoutShift as NSNumber? + @objc public var url: String { + set { root.swiftModel.view.url = newValue } + get { root.swiftModel.view.url } } +} - @objc public var customTimings: [String: NSNumber]? { - root.swiftModel.view.customTimings as [String: NSNumber]? - } +@objc +public class DDRUMErrorEvent: NSObject { + internal var swiftModel: RUMErrorEvent + internal var root: DDRUMErrorEvent { self } - @objc public var domComplete: NSNumber? { - root.swiftModel.view.domComplete as NSNumber? + internal init(swiftModel: RUMErrorEvent) { + self.swiftModel = swiftModel } - @objc public var domContentLoaded: NSNumber? { - root.swiftModel.view.domContentLoaded as NSNumber? + @objc public var dd: DDRUMErrorEventDD { + DDRUMErrorEventDD(root: root) } - @objc public var domInteractive: NSNumber? { - root.swiftModel.view.domInteractive as NSNumber? + @objc public var action: DDRUMErrorEventAction? { + root.swiftModel.action != nil ? DDRUMErrorEventAction(root: root) : nil } - @objc public var error: DDRUMViewEventViewError { - DDRUMViewEventViewError(root: root) + @objc public var application: DDRUMErrorEventApplication { + DDRUMErrorEventApplication(root: root) } - @objc public var firstContentfulPaint: NSNumber? { - root.swiftModel.view.firstContentfulPaint as NSNumber? + @objc public var ciTest: DDRUMErrorEventRUMCITest? { + root.swiftModel.ciTest != nil ? DDRUMErrorEventRUMCITest(root: root) : nil } - @objc public var firstInputDelay: NSNumber? { - root.swiftModel.view.firstInputDelay as NSNumber? + @objc public var connectivity: DDRUMErrorEventRUMConnectivity? { + root.swiftModel.connectivity != nil ? DDRUMErrorEventRUMConnectivity(root: root) : nil } - @objc public var firstInputTime: NSNumber? { - root.swiftModel.view.firstInputTime as NSNumber? + @objc public var context: DDRUMErrorEventRUMEventAttributes? { + root.swiftModel.context != nil ? DDRUMErrorEventRUMEventAttributes(root: root) : nil } - @objc public var frozenFrame: DDRUMViewEventViewFrozenFrame? { - root.swiftModel.view.frozenFrame != nil ? DDRUMViewEventViewFrozenFrame(root: root) : nil + @objc public var date: NSNumber { + root.swiftModel.date as NSNumber } - @objc public var id: String { - root.swiftModel.view.id + @objc public var error: DDRUMErrorEventError { + DDRUMErrorEventError(root: root) } - @objc public var inForegroundPeriods: [DDRUMViewEventViewInForegroundPeriods]? { - root.swiftModel.view.inForegroundPeriods?.map { DDRUMViewEventViewInForegroundPeriods(swiftModel: $0) } + @objc public var service: String? { + root.swiftModel.service } - @objc public var isActive: NSNumber? { - root.swiftModel.view.isActive as NSNumber? + @objc public var session: DDRUMErrorEventSession { + DDRUMErrorEventSession(root: root) } - @objc public var isSlowRendered: NSNumber? { - root.swiftModel.view.isSlowRendered as NSNumber? + @objc public var source: DDRUMErrorEventSource { + .init(swift: root.swiftModel.source) } - @objc public var largestContentfulPaint: NSNumber? { - root.swiftModel.view.largestContentfulPaint as NSNumber? + @objc public var synthetics: DDRUMErrorEventSynthetics? { + root.swiftModel.synthetics != nil ? DDRUMErrorEventSynthetics(root: root) : nil } - @objc public var loadEvent: NSNumber? { - root.swiftModel.view.loadEvent as NSNumber? + @objc public var type: String { + root.swiftModel.type } - @objc public var loadingTime: NSNumber? { - root.swiftModel.view.loadingTime as NSNumber? + @objc public var usr: DDRUMErrorEventRUMUser? { + root.swiftModel.usr != nil ? DDRUMErrorEventRUMUser(root: root) : nil } - @objc public var loadingType: DDRUMViewEventViewLoadingType { - .init(swift: root.swiftModel.view.loadingType) + @objc public var view: DDRUMErrorEventView { + DDRUMErrorEventView(root: root) } +} - @objc public var longTask: DDRUMViewEventViewLongTask? { - root.swiftModel.view.longTask != nil ? DDRUMViewEventViewLongTask(root: root) : nil - } +@objc +public class DDRUMErrorEventDD: NSObject { + internal let root: DDRUMErrorEvent - @objc public var memoryAverage: NSNumber? { - root.swiftModel.view.memoryAverage as NSNumber? + internal init(root: DDRUMErrorEvent) { + self.root = root } - @objc public var memoryMax: NSNumber? { - root.swiftModel.view.memoryMax as NSNumber? + @objc public var browserSdkVersion: String? { + root.swiftModel.dd.browserSdkVersion } - @objc public var name: String? { - set { root.swiftModel.view.name = newValue } - get { root.swiftModel.view.name } + @objc public var formatVersion: NSNumber { + root.swiftModel.dd.formatVersion as NSNumber } - @objc public var referrer: String? { - set { root.swiftModel.view.referrer = newValue } - get { root.swiftModel.view.referrer } + @objc public var session: DDRUMErrorEventDDSession? { + root.swiftModel.dd.session != nil ? DDRUMErrorEventDDSession(root: root) : nil } +} - @objc public var refreshRateAverage: NSNumber? { - root.swiftModel.view.refreshRateAverage as NSNumber? - } +@objc +public class DDRUMErrorEventDDSession: NSObject { + internal let root: DDRUMErrorEvent - @objc public var refreshRateMin: NSNumber? { - root.swiftModel.view.refreshRateMin as NSNumber? + internal init(root: DDRUMErrorEvent) { + self.root = root } - @objc public var resource: DDRUMViewEventViewResource { - DDRUMViewEventViewResource(root: root) + @objc public var plan: DDRUMErrorEventDDSessionPlan { + .init(swift: root.swiftModel.dd.session!.plan) } +} - @objc public var timeSpent: NSNumber { - root.swiftModel.view.timeSpent as NSNumber +@objc +public enum DDRUMErrorEventDDSessionPlan: Int { + internal init(swift: RUMErrorEvent.DD.Session.Plan) { + switch swift { + case .plan1: self = .plan1 + case .plan2: self = .plan2 + } } - @objc public var url: String { - set { root.swiftModel.view.url = newValue } - get { root.swiftModel.view.url } + internal var toSwift: RUMErrorEvent.DD.Session.Plan { + switch self { + case .plan1: return .plan1 + case .plan2: return .plan2 + } } + + case plan1 + case plan2 } @objc -public class DDRUMViewEventViewAction: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMErrorEventAction: NSObject { + internal let root: DDRUMErrorEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMErrorEvent) { self.root = root } - @objc public var count: NSNumber { - root.swiftModel.view.action.count as NSNumber + @objc public var id: String { + root.swiftModel.action!.id } } @objc -public class DDRUMViewEventViewCrash: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMErrorEventApplication: NSObject { + internal let root: DDRUMErrorEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMErrorEvent) { self.root = root } - @objc public var count: NSNumber { - root.swiftModel.view.crash!.count as NSNumber + @objc public var id: String { + root.swiftModel.application.id } } @objc -public class DDRUMViewEventViewError: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMErrorEventRUMCITest: NSObject { + internal let root: DDRUMErrorEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMErrorEvent) { self.root = root } - @objc public var count: NSNumber { - root.swiftModel.view.error.count as NSNumber + @objc public var testExecutionId: String { + root.swiftModel.ciTest!.testExecutionId } } @objc -public class DDRUMViewEventViewFrozenFrame: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMErrorEventRUMConnectivity: NSObject { + internal let root: DDRUMErrorEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMErrorEvent) { self.root = root } - @objc public var count: NSNumber { - root.swiftModel.view.frozenFrame!.count as NSNumber + @objc public var cellular: DDRUMErrorEventRUMConnectivityCellular? { + root.swiftModel.connectivity!.cellular != nil ? DDRUMErrorEventRUMConnectivityCellular(root: root) : nil + } + + @objc public var interfaces: [Int] { + root.swiftModel.connectivity!.interfaces.map { DDRUMErrorEventRUMConnectivityInterfaces(swift: $0).rawValue } + } + + @objc public var status: DDRUMErrorEventRUMConnectivityStatus { + .init(swift: root.swiftModel.connectivity!.status) } } @objc -public class DDRUMViewEventViewInForegroundPeriods: NSObject { - internal let swiftModel: RUMViewEvent.View.InForegroundPeriods - internal var root: DDRUMViewEventViewInForegroundPeriods { self } +public class DDRUMErrorEventRUMConnectivityCellular: NSObject { + internal let root: DDRUMErrorEvent - internal init(swiftModel: RUMViewEvent.View.InForegroundPeriods) { - self.swiftModel = swiftModel + internal init(root: DDRUMErrorEvent) { + self.root = root } - @objc public var duration: NSNumber { - root.swiftModel.duration as NSNumber + @objc public var carrierName: String? { + root.swiftModel.connectivity!.cellular!.carrierName } - @objc public var start: NSNumber { - root.swiftModel.start as NSNumber + @objc public var technology: String? { + root.swiftModel.connectivity!.cellular!.technology } } @objc -public enum DDRUMViewEventViewLoadingType: Int { - internal init(swift: RUMViewEvent.View.LoadingType?) { +public enum DDRUMErrorEventRUMConnectivityInterfaces: Int { + internal init(swift: RUMConnectivity.Interfaces) { switch swift { - case nil: self = .none - case .initialLoad?: self = .initialLoad - case .routeChange?: self = .routeChange - case .activityDisplay?: self = .activityDisplay - case .activityRedisplay?: self = .activityRedisplay - case .fragmentDisplay?: self = .fragmentDisplay - case .fragmentRedisplay?: self = .fragmentRedisplay - case .viewControllerDisplay?: self = .viewControllerDisplay - case .viewControllerRedisplay?: self = .viewControllerRedisplay + case .bluetooth: self = .bluetooth + case .cellular: self = .cellular + case .ethernet: self = .ethernet + case .wifi: self = .wifi + case .wimax: self = .wimax + case .mixed: self = .mixed + case .other: self = .other + case .unknown: self = .unknown + case .none: self = .none } } - internal var toSwift: RUMViewEvent.View.LoadingType? { + internal var toSwift: RUMConnectivity.Interfaces { switch self { - case .none: return nil - case .initialLoad: return .initialLoad - case .routeChange: return .routeChange - case .activityDisplay: return .activityDisplay - case .activityRedisplay: return .activityRedisplay - case .fragmentDisplay: return .fragmentDisplay - case .fragmentRedisplay: return .fragmentRedisplay - case .viewControllerDisplay: return .viewControllerDisplay - case .viewControllerRedisplay: return .viewControllerRedisplay + case .bluetooth: return .bluetooth + case .cellular: return .cellular + case .ethernet: return .ethernet + case .wifi: return .wifi + case .wimax: return .wimax + case .mixed: return .mixed + case .other: return .other + case .unknown: return .unknown + case .none: return .none } } + case bluetooth + case cellular + case ethernet + case wifi + case wimax + case mixed + case other + case unknown case none - case initialLoad - case routeChange - case activityDisplay - case activityRedisplay - case fragmentDisplay - case fragmentRedisplay - case viewControllerDisplay - case viewControllerRedisplay } @objc -public class DDRUMViewEventViewLongTask: NSObject { - internal let root: DDRUMViewEvent - - internal init(root: DDRUMViewEvent) { - self.root = root +public enum DDRUMErrorEventRUMConnectivityStatus: Int { + internal init(swift: RUMConnectivity.Status) { + switch swift { + case .connected: self = .connected + case .notConnected: self = .notConnected + case .maybe: self = .maybe + } } - @objc public var count: NSNumber { - root.swiftModel.view.longTask!.count as NSNumber + internal var toSwift: RUMConnectivity.Status { + switch self { + case .connected: return .connected + case .notConnected: return .notConnected + case .maybe: return .maybe + } } + + case connected + case notConnected + case maybe } @objc -public class DDRUMViewEventViewResource: NSObject { - internal let root: DDRUMViewEvent +public class DDRUMErrorEventRUMEventAttributes: NSObject { + internal let root: DDRUMErrorEvent - internal init(root: DDRUMViewEvent) { + internal init(root: DDRUMErrorEvent) { self.root = root } - @objc public var count: NSNumber { - root.swiftModel.view.resource.count as NSNumber + @objc public var contextInfo: [String: Any] { + root.swiftModel.context!.contextInfo.castToObjectiveC() } } @objc -public class DDRUMResourceEvent: NSObject { - internal var swiftModel: RUMResourceEvent - internal var root: DDRUMResourceEvent { self } - - internal init(swiftModel: RUMResourceEvent) { - self.swiftModel = swiftModel - } - - @objc public var dd: DDRUMResourceEventDD { - DDRUMResourceEventDD(root: root) - } +public class DDRUMErrorEventError: NSObject { + internal let root: DDRUMErrorEvent - @objc public var action: DDRUMResourceEventAction? { - root.swiftModel.action != nil ? DDRUMResourceEventAction(root: root) : nil + internal init(root: DDRUMErrorEvent) { + self.root = root } - @objc public var application: DDRUMResourceEventApplication { - DDRUMResourceEventApplication(root: root) + @objc public var handling: DDRUMErrorEventErrorHandling { + .init(swift: root.swiftModel.error.handling) } - @objc public var ciTest: DDRUMResourceEventCiTest? { - root.swiftModel.ciTest != nil ? DDRUMResourceEventCiTest(root: root) : nil + @objc public var handlingStack: String? { + root.swiftModel.error.handlingStack } - @objc public var connectivity: DDRUMResourceEventRUMConnectivity? { - root.swiftModel.connectivity != nil ? DDRUMResourceEventRUMConnectivity(root: root) : nil + @objc public var id: String? { + root.swiftModel.error.id } - @objc public var context: DDRUMResourceEventRUMEventAttributes? { - root.swiftModel.context != nil ? DDRUMResourceEventRUMEventAttributes(root: root) : nil + @objc public var isCrash: NSNumber? { + root.swiftModel.error.isCrash as NSNumber? } - @objc public var date: NSNumber { - root.swiftModel.date as NSNumber + @objc public var message: String { + set { root.swiftModel.error.message = newValue } + get { root.swiftModel.error.message } } - @objc public var resource: DDRUMResourceEventResource { - DDRUMResourceEventResource(root: root) + @objc public var resource: DDRUMErrorEventErrorResource? { + root.swiftModel.error.resource != nil ? DDRUMErrorEventErrorResource(root: root) : nil } - @objc public var service: String? { - root.swiftModel.service + @objc public var source: DDRUMErrorEventErrorSource { + .init(swift: root.swiftModel.error.source) } - @objc public var session: DDRUMResourceEventSession { - DDRUMResourceEventSession(root: root) + @objc public var sourceType: DDRUMErrorEventErrorSourceType { + .init(swift: root.swiftModel.error.sourceType) } - @objc public var source: DDRUMResourceEventSource { - .init(swift: root.swiftModel.source) + @objc public var stack: String? { + set { root.swiftModel.error.stack = newValue } + get { root.swiftModel.error.stack } } - @objc public var synthetics: DDRUMResourceEventSynthetics? { - root.swiftModel.synthetics != nil ? DDRUMResourceEventSynthetics(root: root) : nil + @objc public var type: String? { + root.swiftModel.error.type } +} - @objc public var type: String { - root.swiftModel.type +@objc +public enum DDRUMErrorEventErrorHandling: Int { + internal init(swift: RUMErrorEvent.Error.Handling?) { + switch swift { + case nil: self = .none + case .handled?: self = .handled + case .unhandled?: self = .unhandled + } } - @objc public var usr: DDRUMResourceEventRUMUser? { - root.swiftModel.usr != nil ? DDRUMResourceEventRUMUser(root: root) : nil + internal var toSwift: RUMErrorEvent.Error.Handling? { + switch self { + case .none: return nil + case .handled: return .handled + case .unhandled: return .unhandled + } } - @objc public var view: DDRUMResourceEventView { - DDRUMResourceEventView(root: root) - } + case none + case handled + case unhandled } @objc -public class DDRUMResourceEventDD: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMErrorEventErrorResource: NSObject { + internal let root: DDRUMErrorEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMErrorEvent) { self.root = root } - @objc public var browserSdkVersion: String? { - root.swiftModel.dd.browserSdkVersion - } - - @objc public var formatVersion: NSNumber { - root.swiftModel.dd.formatVersion as NSNumber - } - - @objc public var session: DDRUMResourceEventDDSession? { - root.swiftModel.dd.session != nil ? DDRUMResourceEventDDSession(root: root) : nil - } - - @objc public var spanId: String? { - root.swiftModel.dd.spanId + @objc public var method: DDRUMErrorEventErrorResourceRUMMethod { + .init(swift: root.swiftModel.error.resource!.method) } - @objc public var traceId: String? { - root.swiftModel.dd.traceId + @objc public var provider: DDRUMErrorEventErrorResourceProvider? { + root.swiftModel.error.resource!.provider != nil ? DDRUMErrorEventErrorResourceProvider(root: root) : nil } -} - -@objc -public class DDRUMResourceEventDDSession: NSObject { - internal let root: DDRUMResourceEvent - internal init(root: DDRUMResourceEvent) { - self.root = root + @objc public var statusCode: NSNumber { + root.swiftModel.error.resource!.statusCode as NSNumber } - @objc public var plan: DDRUMResourceEventDDSessionPlan { - .init(swift: root.swiftModel.dd.session!.plan) + @objc public var url: String { + set { root.swiftModel.error.resource!.url = newValue } + get { root.swiftModel.error.resource!.url } } } @objc -public enum DDRUMResourceEventDDSessionPlan: Int { - internal init(swift: RUMResourceEvent.DD.Session.Plan) { +public enum DDRUMErrorEventErrorResourceRUMMethod: Int { + internal init(swift: RUMMethod) { switch swift { - case .plan1: self = .plan1 - case .plan2: self = .plan2 + case .post: self = .post + case .get: self = .get + case .head: self = .head + case .put: self = .put + case .delete: self = .delete + case .patch: self = .patch } } - internal var toSwift: RUMResourceEvent.DD.Session.Plan { + internal var toSwift: RUMMethod { switch self { - case .plan1: return .plan1 - case .plan2: return .plan2 + case .post: return .post + case .get: return .get + case .head: return .head + case .put: return .put + case .delete: return .delete + case .patch: return .patch } } - case plan1 - case plan2 + case post + case get + case head + case put + case delete + case patch } @objc -public class DDRUMResourceEventAction: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMErrorEventErrorResourceProvider: NSObject { + internal let root: DDRUMErrorEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMErrorEvent) { self.root = root } - @objc public var id: String { - root.swiftModel.action!.id + @objc public var domain: String? { + root.swiftModel.error.resource!.provider!.domain } -} -@objc -public class DDRUMResourceEventApplication: NSObject { - internal let root: DDRUMResourceEvent - - internal init(root: DDRUMResourceEvent) { - self.root = root + @objc public var name: String? { + root.swiftModel.error.resource!.provider!.name } - @objc public var id: String { - root.swiftModel.application.id + @objc public var type: DDRUMErrorEventErrorResourceProviderProviderType { + .init(swift: root.swiftModel.error.resource!.provider!.type) } } @objc -public class DDRUMResourceEventCiTest: NSObject { - internal let root: DDRUMResourceEvent - - internal init(root: DDRUMResourceEvent) { - self.root = root +public enum DDRUMErrorEventErrorResourceProviderProviderType: Int { + internal init(swift: RUMErrorEvent.Error.Resource.Provider.ProviderType?) { + switch swift { + case nil: self = .none + case .ad?: self = .ad + case .advertising?: self = .advertising + case .analytics?: self = .analytics + case .cdn?: self = .cdn + case .content?: self = .content + case .customerSuccess?: self = .customerSuccess + case .firstParty?: self = .firstParty + case .hosting?: self = .hosting + case .marketing?: self = .marketing + case .other?: self = .other + case .social?: self = .social + case .tagManager?: self = .tagManager + case .utility?: self = .utility + case .video?: self = .video + } } - @objc public var testExecutionId: String { - root.swiftModel.ciTest!.testExecutionId + internal var toSwift: RUMErrorEvent.Error.Resource.Provider.ProviderType? { + switch self { + case .none: return nil + case .ad: return .ad + case .advertising: return .advertising + case .analytics: return .analytics + case .cdn: return .cdn + case .content: return .content + case .customerSuccess: return .customerSuccess + case .firstParty: return .firstParty + case .hosting: return .hosting + case .marketing: return .marketing + case .other: return .other + case .social: return .social + case .tagManager: return .tagManager + case .utility: return .utility + case .video: return .video + } } + + case none + case ad + case advertising + case analytics + case cdn + case content + case customerSuccess + case firstParty + case hosting + case marketing + case other + case social + case tagManager + case utility + case video } @objc -public class DDRUMResourceEventRUMConnectivity: NSObject { - internal let root: DDRUMResourceEvent - - internal init(root: DDRUMResourceEvent) { - self.root = root +public enum DDRUMErrorEventErrorSource: Int { + internal init(swift: RUMErrorEvent.Error.Source) { + switch swift { + case .network: self = .network + case .source: self = .source + case .console: self = .console + case .logger: self = .logger + case .agent: self = .agent + case .webview: self = .webview + case .custom: self = .custom + case .report: self = .report + } } - @objc public var cellular: DDRUMResourceEventRUMConnectivityCellular? { - root.swiftModel.connectivity!.cellular != nil ? DDRUMResourceEventRUMConnectivityCellular(root: root) : nil + internal var toSwift: RUMErrorEvent.Error.Source { + switch self { + case .network: return .network + case .source: return .source + case .console: return .console + case .logger: return .logger + case .agent: return .agent + case .webview: return .webview + case .custom: return .custom + case .report: return .report + } } - @objc public var interfaces: [Int] { - root.swiftModel.connectivity!.interfaces.map { DDRUMResourceEventRUMConnectivityInterfaces(swift: $0).rawValue } + case network + case source + case console + case logger + case agent + case webview + case custom + case report +} + +@objc +public enum DDRUMErrorEventErrorSourceType: Int { + internal init(swift: RUMErrorEvent.Error.SourceType?) { + switch swift { + case nil: self = .none + case .android?: self = .android + case .browser?: self = .browser + case .ios?: self = .ios + case .reactNative?: self = .reactNative + case .flutter?: self = .flutter + } } - @objc public var status: DDRUMResourceEventRUMConnectivityStatus { - .init(swift: root.swiftModel.connectivity!.status) + internal var toSwift: RUMErrorEvent.Error.SourceType? { + switch self { + case .none: return nil + case .android: return .android + case .browser: return .browser + case .ios: return .ios + case .reactNative: return .reactNative + case .flutter: return .flutter + } } + + case none + case android + case browser + case ios + case reactNative + case flutter } @objc -public class DDRUMResourceEventRUMConnectivityCellular: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMErrorEventSession: NSObject { + internal let root: DDRUMErrorEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMErrorEvent) { self.root = root } - @objc public var carrierName: String? { - root.swiftModel.connectivity!.cellular!.carrierName + @objc public var hasReplay: NSNumber? { + root.swiftModel.session.hasReplay as NSNumber? } - @objc public var technology: String? { - root.swiftModel.connectivity!.cellular!.technology + @objc public var id: String { + root.swiftModel.session.id + } + + @objc public var type: DDRUMErrorEventSessionSessionType { + .init(swift: root.swiftModel.session.type) } } @objc -public enum DDRUMResourceEventRUMConnectivityInterfaces: Int { - internal init(swift: RUMConnectivity.Interfaces) { +public enum DDRUMErrorEventSessionSessionType: Int { + internal init(swift: RUMErrorEvent.Session.SessionType) { switch swift { - case .bluetooth: self = .bluetooth - case .cellular: self = .cellular - case .ethernet: self = .ethernet - case .wifi: self = .wifi - case .wimax: self = .wimax - case .mixed: self = .mixed - case .other: self = .other - case .unknown: self = .unknown - case .none: self = .none + case .user: self = .user + case .synthetics: self = .synthetics + case .ciTest: self = .ciTest } } - internal var toSwift: RUMConnectivity.Interfaces { + internal var toSwift: RUMErrorEvent.Session.SessionType { switch self { - case .bluetooth: return .bluetooth - case .cellular: return .cellular - case .ethernet: return .ethernet - case .wifi: return .wifi - case .wimax: return .wimax - case .mixed: return .mixed - case .other: return .other - case .unknown: return .unknown - case .none: return .none + case .user: return .user + case .synthetics: return .synthetics + case .ciTest: return .ciTest } } - case bluetooth - case cellular - case ethernet - case wifi - case wimax - case mixed - case other - case unknown - case none + case user + case synthetics + case ciTest } @objc -public enum DDRUMResourceEventRUMConnectivityStatus: Int { - internal init(swift: RUMConnectivity.Status) { +public enum DDRUMErrorEventSource: Int { + internal init(swift: RUMErrorEvent.Source?) { switch swift { - case .connected: self = .connected - case .notConnected: self = .notConnected - case .maybe: self = .maybe + case nil: self = .none + case .android?: self = .android + case .ios?: self = .ios + case .browser?: self = .browser + case .flutter?: self = .flutter + case .reactNative?: self = .reactNative } } - internal var toSwift: RUMConnectivity.Status { + internal var toSwift: RUMErrorEvent.Source? { switch self { - case .connected: return .connected - case .notConnected: return .notConnected - case .maybe: return .maybe + case .none: return nil + case .android: return .android + case .ios: return .ios + case .browser: return .browser + case .flutter: return .flutter + case .reactNative: return .reactNative } } - case connected - case notConnected - case maybe + case none + case android + case ios + case browser + case flutter + case reactNative } @objc -public class DDRUMResourceEventRUMEventAttributes: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMErrorEventSynthetics: NSObject { + internal let root: DDRUMErrorEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMErrorEvent) { self.root = root } - @objc public var contextInfo: [String: Any] { - root.swiftModel.context!.contextInfo.castToObjectiveC() + @objc public var injected: NSNumber? { + root.swiftModel.synthetics!.injected as NSNumber? + } + + @objc public var resultId: String { + root.swiftModel.synthetics!.resultId + } + + @objc public var testId: String { + root.swiftModel.synthetics!.testId } } @objc -public class DDRUMResourceEventResource: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMErrorEventRUMUser: NSObject { + internal let root: DDRUMErrorEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMErrorEvent) { self.root = root } - @objc public var connect: DDRUMResourceEventResourceConnect? { - root.swiftModel.resource.connect != nil ? DDRUMResourceEventResourceConnect(root: root) : nil + @objc public var email: String? { + root.swiftModel.usr!.email } - @objc public var dns: DDRUMResourceEventResourceDNS? { - root.swiftModel.resource.dns != nil ? DDRUMResourceEventResourceDNS(root: root) : nil + @objc public var id: String? { + root.swiftModel.usr!.id } - @objc public var download: DDRUMResourceEventResourceDownload? { - root.swiftModel.resource.download != nil ? DDRUMResourceEventResourceDownload(root: root) : nil + @objc public var name: String? { + root.swiftModel.usr!.name } - @objc public var duration: NSNumber { - root.swiftModel.resource.duration as NSNumber + @objc public var usrInfo: [String: Any] { + root.swiftModel.usr!.usrInfo.castToObjectiveC() } +} - @objc public var firstByte: DDRUMResourceEventResourceFirstByte? { - root.swiftModel.resource.firstByte != nil ? DDRUMResourceEventResourceFirstByte(root: root) : nil +@objc +public class DDRUMErrorEventView: NSObject { + internal let root: DDRUMErrorEvent + + internal init(root: DDRUMErrorEvent) { + self.root = root } - @objc public var id: String? { - root.swiftModel.resource.id + @objc public var id: String { + root.swiftModel.view.id + } + + @objc public var inForeground: NSNumber? { + root.swiftModel.view.inForeground as NSNumber? + } + + @objc public var name: String? { + set { root.swiftModel.view.name = newValue } + get { root.swiftModel.view.name } + } + + @objc public var referrer: String? { + set { root.swiftModel.view.referrer = newValue } + get { root.swiftModel.view.referrer } + } + + @objc public var url: String { + set { root.swiftModel.view.url = newValue } + get { root.swiftModel.view.url } + } +} + +@objc +public class DDRUMLongTaskEvent: NSObject { + internal var swiftModel: RUMLongTaskEvent + internal var root: DDRUMLongTaskEvent { self } + + internal init(swiftModel: RUMLongTaskEvent) { + self.swiftModel = swiftModel + } + + @objc public var dd: DDRUMLongTaskEventDD { + DDRUMLongTaskEventDD(root: root) + } + + @objc public var action: DDRUMLongTaskEventAction? { + root.swiftModel.action != nil ? DDRUMLongTaskEventAction(root: root) : nil + } + + @objc public var application: DDRUMLongTaskEventApplication { + DDRUMLongTaskEventApplication(root: root) + } + + @objc public var ciTest: DDRUMLongTaskEventRUMCITest? { + root.swiftModel.ciTest != nil ? DDRUMLongTaskEventRUMCITest(root: root) : nil + } + + @objc public var connectivity: DDRUMLongTaskEventRUMConnectivity? { + root.swiftModel.connectivity != nil ? DDRUMLongTaskEventRUMConnectivity(root: root) : nil + } + + @objc public var context: DDRUMLongTaskEventRUMEventAttributes? { + root.swiftModel.context != nil ? DDRUMLongTaskEventRUMEventAttributes(root: root) : nil + } + + @objc public var date: NSNumber { + root.swiftModel.date as NSNumber + } + + @objc public var longTask: DDRUMLongTaskEventLongTask { + DDRUMLongTaskEventLongTask(root: root) + } + + @objc public var service: String? { + root.swiftModel.service + } + + @objc public var session: DDRUMLongTaskEventSession { + DDRUMLongTaskEventSession(root: root) + } + + @objc public var source: DDRUMLongTaskEventSource { + .init(swift: root.swiftModel.source) + } + + @objc public var synthetics: DDRUMLongTaskEventSynthetics? { + root.swiftModel.synthetics != nil ? DDRUMLongTaskEventSynthetics(root: root) : nil } - @objc public var method: DDRUMResourceEventResourceRUMMethod { - .init(swift: root.swiftModel.resource.method) + @objc public var type: String { + root.swiftModel.type } - @objc public var provider: DDRUMResourceEventResourceProvider? { - root.swiftModel.resource.provider != nil ? DDRUMResourceEventResourceProvider(root: root) : nil + @objc public var usr: DDRUMLongTaskEventRUMUser? { + root.swiftModel.usr != nil ? DDRUMLongTaskEventRUMUser(root: root) : nil } - @objc public var redirect: DDRUMResourceEventResourceRedirect? { - root.swiftModel.resource.redirect != nil ? DDRUMResourceEventResourceRedirect(root: root) : nil + @objc public var view: DDRUMLongTaskEventView { + DDRUMLongTaskEventView(root: root) } +} - @objc public var size: NSNumber? { - root.swiftModel.resource.size as NSNumber? - } +@objc +public class DDRUMLongTaskEventDD: NSObject { + internal let root: DDRUMLongTaskEvent - @objc public var ssl: DDRUMResourceEventResourceSSL? { - root.swiftModel.resource.ssl != nil ? DDRUMResourceEventResourceSSL(root: root) : nil + internal init(root: DDRUMLongTaskEvent) { + self.root = root } - @objc public var statusCode: NSNumber? { - root.swiftModel.resource.statusCode as NSNumber? + @objc public var browserSdkVersion: String? { + root.swiftModel.dd.browserSdkVersion } - @objc public var type: DDRUMResourceEventResourceResourceType { - .init(swift: root.swiftModel.resource.type) + @objc public var formatVersion: NSNumber { + root.swiftModel.dd.formatVersion as NSNumber } - @objc public var url: String { - set { root.swiftModel.resource.url = newValue } - get { root.swiftModel.resource.url } + @objc public var session: DDRUMLongTaskEventDDSession? { + root.swiftModel.dd.session != nil ? DDRUMLongTaskEventDDSession(root: root) : nil } } @objc -public class DDRUMResourceEventResourceConnect: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMLongTaskEventDDSession: NSObject { + internal let root: DDRUMLongTaskEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMLongTaskEvent) { self.root = root } - @objc public var duration: NSNumber { - root.swiftModel.resource.connect!.duration as NSNumber + @objc public var plan: DDRUMLongTaskEventDDSessionPlan { + .init(swift: root.swiftModel.dd.session!.plan) } +} - @objc public var start: NSNumber { - root.swiftModel.resource.connect!.start as NSNumber +@objc +public enum DDRUMLongTaskEventDDSessionPlan: Int { + internal init(swift: RUMLongTaskEvent.DD.Session.Plan) { + switch swift { + case .plan1: self = .plan1 + case .plan2: self = .plan2 + } } + + internal var toSwift: RUMLongTaskEvent.DD.Session.Plan { + switch self { + case .plan1: return .plan1 + case .plan2: return .plan2 + } + } + + case plan1 + case plan2 } @objc -public class DDRUMResourceEventResourceDNS: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMLongTaskEventAction: NSObject { + internal let root: DDRUMLongTaskEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMLongTaskEvent) { self.root = root } - @objc public var duration: NSNumber { - root.swiftModel.resource.dns!.duration as NSNumber - } - - @objc public var start: NSNumber { - root.swiftModel.resource.dns!.start as NSNumber + @objc public var id: String { + root.swiftModel.action!.id } } @objc -public class DDRUMResourceEventResourceDownload: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMLongTaskEventApplication: NSObject { + internal let root: DDRUMLongTaskEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMLongTaskEvent) { self.root = root } - @objc public var duration: NSNumber { - root.swiftModel.resource.download!.duration as NSNumber - } - - @objc public var start: NSNumber { - root.swiftModel.resource.download!.start as NSNumber + @objc public var id: String { + root.swiftModel.application.id } } @objc -public class DDRUMResourceEventResourceFirstByte: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMLongTaskEventRUMCITest: NSObject { + internal let root: DDRUMLongTaskEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMLongTaskEvent) { self.root = root } - @objc public var duration: NSNumber { - root.swiftModel.resource.firstByte!.duration as NSNumber - } - - @objc public var start: NSNumber { - root.swiftModel.resource.firstByte!.start as NSNumber + @objc public var testExecutionId: String { + root.swiftModel.ciTest!.testExecutionId } } @objc -public enum DDRUMResourceEventResourceRUMMethod: Int { - internal init(swift: RUMMethod?) { - switch swift { - case nil: self = .none - case .post?: self = .post - case .get?: self = .get - case .head?: self = .head - case .put?: self = .put - case .delete?: self = .delete - case .patch?: self = .patch - } +public class DDRUMLongTaskEventRUMConnectivity: NSObject { + internal let root: DDRUMLongTaskEvent + + internal init(root: DDRUMLongTaskEvent) { + self.root = root } - internal var toSwift: RUMMethod? { - switch self { - case .none: return nil - case .post: return .post - case .get: return .get - case .head: return .head - case .put: return .put - case .delete: return .delete - case .patch: return .patch - } + @objc public var cellular: DDRUMLongTaskEventRUMConnectivityCellular? { + root.swiftModel.connectivity!.cellular != nil ? DDRUMLongTaskEventRUMConnectivityCellular(root: root) : nil } - case none - case post - case get - case head - case put - case delete - case patch + @objc public var interfaces: [Int] { + root.swiftModel.connectivity!.interfaces.map { DDRUMLongTaskEventRUMConnectivityInterfaces(swift: $0).rawValue } + } + + @objc public var status: DDRUMLongTaskEventRUMConnectivityStatus { + .init(swift: root.swiftModel.connectivity!.status) + } } @objc -public class DDRUMResourceEventResourceProvider: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMLongTaskEventRUMConnectivityCellular: NSObject { + internal let root: DDRUMLongTaskEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMLongTaskEvent) { self.root = root } - @objc public var domain: String? { - root.swiftModel.resource.provider!.domain - } - - @objc public var name: String? { - root.swiftModel.resource.provider!.name + @objc public var carrierName: String? { + root.swiftModel.connectivity!.cellular!.carrierName } - @objc public var type: DDRUMResourceEventResourceProviderProviderType { - .init(swift: root.swiftModel.resource.provider!.type) + @objc public var technology: String? { + root.swiftModel.connectivity!.cellular!.technology } } @objc -public enum DDRUMResourceEventResourceProviderProviderType: Int { - internal init(swift: RUMResourceEvent.Resource.Provider.ProviderType?) { +public enum DDRUMLongTaskEventRUMConnectivityInterfaces: Int { + internal init(swift: RUMConnectivity.Interfaces) { switch swift { - case nil: self = .none - case .ad?: self = .ad - case .advertising?: self = .advertising - case .analytics?: self = .analytics - case .cdn?: self = .cdn - case .content?: self = .content - case .customerSuccess?: self = .customerSuccess - case .firstParty?: self = .firstParty - case .hosting?: self = .hosting - case .marketing?: self = .marketing - case .other?: self = .other - case .social?: self = .social - case .tagManager?: self = .tagManager - case .utility?: self = .utility - case .video?: self = .video + case .bluetooth: self = .bluetooth + case .cellular: self = .cellular + case .ethernet: self = .ethernet + case .wifi: self = .wifi + case .wimax: self = .wimax + case .mixed: self = .mixed + case .other: self = .other + case .unknown: self = .unknown + case .none: self = .none } } - internal var toSwift: RUMResourceEvent.Resource.Provider.ProviderType? { + internal var toSwift: RUMConnectivity.Interfaces { switch self { - case .none: return nil - case .ad: return .ad - case .advertising: return .advertising - case .analytics: return .analytics - case .cdn: return .cdn - case .content: return .content - case .customerSuccess: return .customerSuccess - case .firstParty: return .firstParty - case .hosting: return .hosting - case .marketing: return .marketing + case .bluetooth: return .bluetooth + case .cellular: return .cellular + case .ethernet: return .ethernet + case .wifi: return .wifi + case .wimax: return .wimax + case .mixed: return .mixed case .other: return .other - case .social: return .social - case .tagManager: return .tagManager - case .utility: return .utility - case .video: return .video + case .unknown: return .unknown + case .none: return .none } } - case none - case ad - case advertising - case analytics - case cdn - case content - case customerSuccess - case firstParty - case hosting - case marketing + case bluetooth + case cellular + case ethernet + case wifi + case wimax + case mixed case other - case social - case tagManager - case utility - case video + case unknown + case none +} + +@objc +public enum DDRUMLongTaskEventRUMConnectivityStatus: Int { + internal init(swift: RUMConnectivity.Status) { + switch swift { + case .connected: self = .connected + case .notConnected: self = .notConnected + case .maybe: self = .maybe + } + } + + internal var toSwift: RUMConnectivity.Status { + switch self { + case .connected: return .connected + case .notConnected: return .notConnected + case .maybe: return .maybe + } + } + + case connected + case notConnected + case maybe } @objc -public class DDRUMResourceEventResourceRedirect: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMLongTaskEventRUMEventAttributes: NSObject { + internal let root: DDRUMLongTaskEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMLongTaskEvent) { self.root = root } - @objc public var duration: NSNumber { - root.swiftModel.resource.redirect!.duration as NSNumber - } - - @objc public var start: NSNumber { - root.swiftModel.resource.redirect!.start as NSNumber + @objc public var contextInfo: [String: Any] { + root.swiftModel.context!.contextInfo.castToObjectiveC() } } @objc -public class DDRUMResourceEventResourceSSL: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMLongTaskEventLongTask: NSObject { + internal let root: DDRUMLongTaskEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMLongTaskEvent) { self.root = root } @objc public var duration: NSNumber { - root.swiftModel.resource.ssl!.duration as NSNumber - } - - @objc public var start: NSNumber { - root.swiftModel.resource.ssl!.start as NSNumber + root.swiftModel.longTask.duration as NSNumber } -} -@objc -public enum DDRUMResourceEventResourceResourceType: Int { - internal init(swift: RUMResourceEvent.Resource.ResourceType) { - switch swift { - case .document: self = .document - case .xhr: self = .xhr - case .beacon: self = .beacon - case .fetch: self = .fetch - case .css: self = .css - case .js: self = .js - case .image: self = .image - case .font: self = .font - case .media: self = .media - case .other: self = .other - case .native: self = .native - } + @objc public var id: String? { + root.swiftModel.longTask.id } - internal var toSwift: RUMResourceEvent.Resource.ResourceType { - switch self { - case .document: return .document - case .xhr: return .xhr - case .beacon: return .beacon - case .fetch: return .fetch - case .css: return .css - case .js: return .js - case .image: return .image - case .font: return .font - case .media: return .media - case .other: return .other - case .native: return .native - } + @objc public var isFrozenFrame: NSNumber? { + root.swiftModel.longTask.isFrozenFrame as NSNumber? } - - case document - case xhr - case beacon - case fetch - case css - case js - case image - case font - case media - case other - case native } @objc -public class DDRUMResourceEventSession: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMLongTaskEventSession: NSObject { + internal let root: DDRUMLongTaskEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMLongTaskEvent) { self.root = root } @@ -1303,14 +1597,14 @@ public class DDRUMResourceEventSession: NSObject { root.swiftModel.session.id } - @objc public var type: DDRUMResourceEventSessionSessionType { + @objc public var type: DDRUMLongTaskEventSessionSessionType { .init(swift: root.swiftModel.session.type) } } @objc -public enum DDRUMResourceEventSessionSessionType: Int { - internal init(swift: RUMResourceEvent.Session.SessionType) { +public enum DDRUMLongTaskEventSessionSessionType: Int { + internal init(swift: RUMLongTaskEvent.Session.SessionType) { switch swift { case .user: self = .user case .synthetics: self = .synthetics @@ -1318,7 +1612,7 @@ public enum DDRUMResourceEventSessionSessionType: Int { } } - internal var toSwift: RUMResourceEvent.Session.SessionType { + internal var toSwift: RUMLongTaskEvent.Session.SessionType { switch self { case .user: return .user case .synthetics: return .synthetics @@ -1332,8 +1626,8 @@ public enum DDRUMResourceEventSessionSessionType: Int { } @objc -public enum DDRUMResourceEventSource: Int { - internal init(swift: RUMResourceEvent.Source?) { +public enum DDRUMLongTaskEventSource: Int { + internal init(swift: RUMLongTaskEvent.Source?) { switch swift { case nil: self = .none case .android?: self = .android @@ -1344,7 +1638,7 @@ public enum DDRUMResourceEventSource: Int { } } - internal var toSwift: RUMResourceEvent.Source? { + internal var toSwift: RUMLongTaskEvent.Source? { switch self { case .none: return nil case .android: return .android @@ -1364,10 +1658,10 @@ public enum DDRUMResourceEventSource: Int { } @objc -public class DDRUMResourceEventSynthetics: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMLongTaskEventSynthetics: NSObject { + internal let root: DDRUMLongTaskEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMLongTaskEvent) { self.root = root } @@ -1379,38 +1673,198 @@ public class DDRUMResourceEventSynthetics: NSObject { root.swiftModel.synthetics!.resultId } - @objc public var testId: String { - root.swiftModel.synthetics!.testId + @objc public var testId: String { + root.swiftModel.synthetics!.testId + } +} + +@objc +public class DDRUMLongTaskEventRUMUser: NSObject { + internal let root: DDRUMLongTaskEvent + + internal init(root: DDRUMLongTaskEvent) { + self.root = root + } + + @objc public var email: String? { + root.swiftModel.usr!.email + } + + @objc public var id: String? { + root.swiftModel.usr!.id + } + + @objc public var name: String? { + root.swiftModel.usr!.name + } + + @objc public var usrInfo: [String: Any] { + root.swiftModel.usr!.usrInfo.castToObjectiveC() + } +} + +@objc +public class DDRUMLongTaskEventView: NSObject { + internal let root: DDRUMLongTaskEvent + + internal init(root: DDRUMLongTaskEvent) { + self.root = root + } + + @objc public var id: String { + root.swiftModel.view.id + } + + @objc public var name: String? { + set { root.swiftModel.view.name = newValue } + get { root.swiftModel.view.name } + } + + @objc public var referrer: String? { + set { root.swiftModel.view.referrer = newValue } + get { root.swiftModel.view.referrer } + } + + @objc public var url: String { + set { root.swiftModel.view.url = newValue } + get { root.swiftModel.view.url } + } +} + +@objc +public class DDRUMResourceEvent: NSObject { + internal var swiftModel: RUMResourceEvent + internal var root: DDRUMResourceEvent { self } + + internal init(swiftModel: RUMResourceEvent) { + self.swiftModel = swiftModel + } + + @objc public var dd: DDRUMResourceEventDD { + DDRUMResourceEventDD(root: root) + } + + @objc public var action: DDRUMResourceEventAction? { + root.swiftModel.action != nil ? DDRUMResourceEventAction(root: root) : nil + } + + @objc public var application: DDRUMResourceEventApplication { + DDRUMResourceEventApplication(root: root) + } + + @objc public var ciTest: DDRUMResourceEventRUMCITest? { + root.swiftModel.ciTest != nil ? DDRUMResourceEventRUMCITest(root: root) : nil + } + + @objc public var connectivity: DDRUMResourceEventRUMConnectivity? { + root.swiftModel.connectivity != nil ? DDRUMResourceEventRUMConnectivity(root: root) : nil + } + + @objc public var context: DDRUMResourceEventRUMEventAttributes? { + root.swiftModel.context != nil ? DDRUMResourceEventRUMEventAttributes(root: root) : nil + } + + @objc public var date: NSNumber { + root.swiftModel.date as NSNumber + } + + @objc public var resource: DDRUMResourceEventResource { + DDRUMResourceEventResource(root: root) + } + + @objc public var service: String? { + root.swiftModel.service + } + + @objc public var session: DDRUMResourceEventSession { + DDRUMResourceEventSession(root: root) + } + + @objc public var source: DDRUMResourceEventSource { + .init(swift: root.swiftModel.source) + } + + @objc public var synthetics: DDRUMResourceEventSynthetics? { + root.swiftModel.synthetics != nil ? DDRUMResourceEventSynthetics(root: root) : nil + } + + @objc public var type: String { + root.swiftModel.type + } + + @objc public var usr: DDRUMResourceEventRUMUser? { + root.swiftModel.usr != nil ? DDRUMResourceEventRUMUser(root: root) : nil + } + + @objc public var view: DDRUMResourceEventView { + DDRUMResourceEventView(root: root) + } +} + +@objc +public class DDRUMResourceEventDD: NSObject { + internal let root: DDRUMResourceEvent + + internal init(root: DDRUMResourceEvent) { + self.root = root + } + + @objc public var browserSdkVersion: String? { + root.swiftModel.dd.browserSdkVersion + } + + @objc public var formatVersion: NSNumber { + root.swiftModel.dd.formatVersion as NSNumber + } + + @objc public var session: DDRUMResourceEventDDSession? { + root.swiftModel.dd.session != nil ? DDRUMResourceEventDDSession(root: root) : nil + } + + @objc public var spanId: String? { + root.swiftModel.dd.spanId + } + + @objc public var traceId: String? { + root.swiftModel.dd.traceId } } @objc -public class DDRUMResourceEventRUMUser: NSObject { +public class DDRUMResourceEventDDSession: NSObject { internal let root: DDRUMResourceEvent internal init(root: DDRUMResourceEvent) { self.root = root } - @objc public var email: String? { - root.swiftModel.usr!.email + @objc public var plan: DDRUMResourceEventDDSessionPlan { + .init(swift: root.swiftModel.dd.session!.plan) } +} - @objc public var id: String? { - root.swiftModel.usr!.id +@objc +public enum DDRUMResourceEventDDSessionPlan: Int { + internal init(swift: RUMResourceEvent.DD.Session.Plan) { + switch swift { + case .plan1: self = .plan1 + case .plan2: self = .plan2 + } } - @objc public var name: String? { - root.swiftModel.usr!.name + internal var toSwift: RUMResourceEvent.DD.Session.Plan { + switch self { + case .plan1: return .plan1 + case .plan2: return .plan2 + } } - @objc public var usrInfo: [String: Any] { - root.swiftModel.usr!.usrInfo.castToObjectiveC() - } + case plan1 + case plan2 } @objc -public class DDRUMResourceEventView: NSObject { +public class DDRUMResourceEventAction: NSObject { internal let root: DDRUMResourceEvent internal init(root: DDRUMResourceEvent) { @@ -1418,433 +1872,486 @@ public class DDRUMResourceEventView: NSObject { } @objc public var id: String { - root.swiftModel.view.id + root.swiftModel.action!.id } +} - @objc public var name: String? { - set { root.swiftModel.view.name = newValue } - get { root.swiftModel.view.name } - } +@objc +public class DDRUMResourceEventApplication: NSObject { + internal let root: DDRUMResourceEvent - @objc public var referrer: String? { - set { root.swiftModel.view.referrer = newValue } - get { root.swiftModel.view.referrer } + internal init(root: DDRUMResourceEvent) { + self.root = root } - @objc public var url: String { - set { root.swiftModel.view.url = newValue } - get { root.swiftModel.view.url } + @objc public var id: String { + root.swiftModel.application.id } } @objc -public class DDRUMActionEvent: NSObject { - internal var swiftModel: RUMActionEvent - internal var root: DDRUMActionEvent { self } - - internal init(swiftModel: RUMActionEvent) { - self.swiftModel = swiftModel - } +public class DDRUMResourceEventRUMCITest: NSObject { + internal let root: DDRUMResourceEvent - @objc public var dd: DDRUMActionEventDD { - DDRUMActionEventDD(root: root) + internal init(root: DDRUMResourceEvent) { + self.root = root } - @objc public var action: DDRUMActionEventAction { - DDRUMActionEventAction(root: root) + @objc public var testExecutionId: String { + root.swiftModel.ciTest!.testExecutionId } +} - @objc public var application: DDRUMActionEventApplication { - DDRUMActionEventApplication(root: root) - } +@objc +public class DDRUMResourceEventRUMConnectivity: NSObject { + internal let root: DDRUMResourceEvent - @objc public var ciTest: DDRUMActionEventCiTest? { - root.swiftModel.ciTest != nil ? DDRUMActionEventCiTest(root: root) : nil + internal init(root: DDRUMResourceEvent) { + self.root = root } - @objc public var connectivity: DDRUMActionEventRUMConnectivity? { - root.swiftModel.connectivity != nil ? DDRUMActionEventRUMConnectivity(root: root) : nil + @objc public var cellular: DDRUMResourceEventRUMConnectivityCellular? { + root.swiftModel.connectivity!.cellular != nil ? DDRUMResourceEventRUMConnectivityCellular(root: root) : nil } - @objc public var context: DDRUMActionEventRUMEventAttributes? { - root.swiftModel.context != nil ? DDRUMActionEventRUMEventAttributes(root: root) : nil + @objc public var interfaces: [Int] { + root.swiftModel.connectivity!.interfaces.map { DDRUMResourceEventRUMConnectivityInterfaces(swift: $0).rawValue } } - @objc public var date: NSNumber { - root.swiftModel.date as NSNumber + @objc public var status: DDRUMResourceEventRUMConnectivityStatus { + .init(swift: root.swiftModel.connectivity!.status) } +} - @objc public var service: String? { - root.swiftModel.service - } +@objc +public class DDRUMResourceEventRUMConnectivityCellular: NSObject { + internal let root: DDRUMResourceEvent - @objc public var session: DDRUMActionEventSession { - DDRUMActionEventSession(root: root) + internal init(root: DDRUMResourceEvent) { + self.root = root } - @objc public var source: DDRUMActionEventSource { - .init(swift: root.swiftModel.source) + @objc public var carrierName: String? { + root.swiftModel.connectivity!.cellular!.carrierName } - @objc public var synthetics: DDRUMActionEventSynthetics? { - root.swiftModel.synthetics != nil ? DDRUMActionEventSynthetics(root: root) : nil + @objc public var technology: String? { + root.swiftModel.connectivity!.cellular!.technology } +} - @objc public var type: String { - root.swiftModel.type +@objc +public enum DDRUMResourceEventRUMConnectivityInterfaces: Int { + internal init(swift: RUMConnectivity.Interfaces) { + switch swift { + case .bluetooth: self = .bluetooth + case .cellular: self = .cellular + case .ethernet: self = .ethernet + case .wifi: self = .wifi + case .wimax: self = .wimax + case .mixed: self = .mixed + case .other: self = .other + case .unknown: self = .unknown + case .none: self = .none + } } - @objc public var usr: DDRUMActionEventRUMUser? { - root.swiftModel.usr != nil ? DDRUMActionEventRUMUser(root: root) : nil + internal var toSwift: RUMConnectivity.Interfaces { + switch self { + case .bluetooth: return .bluetooth + case .cellular: return .cellular + case .ethernet: return .ethernet + case .wifi: return .wifi + case .wimax: return .wimax + case .mixed: return .mixed + case .other: return .other + case .unknown: return .unknown + case .none: return .none + } } - @objc public var view: DDRUMActionEventView { - DDRUMActionEventView(root: root) - } + case bluetooth + case cellular + case ethernet + case wifi + case wimax + case mixed + case other + case unknown + case none } @objc -public class DDRUMActionEventDD: NSObject { - internal let root: DDRUMActionEvent - - internal init(root: DDRUMActionEvent) { - self.root = root - } - - @objc public var browserSdkVersion: String? { - root.swiftModel.dd.browserSdkVersion +public enum DDRUMResourceEventRUMConnectivityStatus: Int { + internal init(swift: RUMConnectivity.Status) { + switch swift { + case .connected: self = .connected + case .notConnected: self = .notConnected + case .maybe: self = .maybe + } } - @objc public var formatVersion: NSNumber { - root.swiftModel.dd.formatVersion as NSNumber + internal var toSwift: RUMConnectivity.Status { + switch self { + case .connected: return .connected + case .notConnected: return .notConnected + case .maybe: return .maybe + } } - @objc public var session: DDRUMActionEventDDSession? { - root.swiftModel.dd.session != nil ? DDRUMActionEventDDSession(root: root) : nil - } + case connected + case notConnected + case maybe } @objc -public class DDRUMActionEventDDSession: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventRUMEventAttributes: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } - @objc public var plan: DDRUMActionEventDDSessionPlan { - .init(swift: root.swiftModel.dd.session!.plan) + @objc public var contextInfo: [String: Any] { + root.swiftModel.context!.contextInfo.castToObjectiveC() } } @objc -public enum DDRUMActionEventDDSessionPlan: Int { - internal init(swift: RUMActionEvent.DD.Session.Plan) { - switch swift { - case .plan1: self = .plan1 - case .plan2: self = .plan2 - } - } +public class DDRUMResourceEventResource: NSObject { + internal let root: DDRUMResourceEvent - internal var toSwift: RUMActionEvent.DD.Session.Plan { - switch self { - case .plan1: return .plan1 - case .plan2: return .plan2 - } + internal init(root: DDRUMResourceEvent) { + self.root = root } - case plan1 - case plan2 -} + @objc public var connect: DDRUMResourceEventResourceConnect? { + root.swiftModel.resource.connect != nil ? DDRUMResourceEventResourceConnect(root: root) : nil + } -@objc -public class DDRUMActionEventAction: NSObject { - internal let root: DDRUMActionEvent + @objc public var dns: DDRUMResourceEventResourceDNS? { + root.swiftModel.resource.dns != nil ? DDRUMResourceEventResourceDNS(root: root) : nil + } - internal init(root: DDRUMActionEvent) { - self.root = root + @objc public var download: DDRUMResourceEventResourceDownload? { + root.swiftModel.resource.download != nil ? DDRUMResourceEventResourceDownload(root: root) : nil } - @objc public var crash: DDRUMActionEventActionCrash? { - root.swiftModel.action.crash != nil ? DDRUMActionEventActionCrash(root: root) : nil + @objc public var duration: NSNumber { + root.swiftModel.resource.duration as NSNumber } - @objc public var error: DDRUMActionEventActionError? { - root.swiftModel.action.error != nil ? DDRUMActionEventActionError(root: root) : nil + @objc public var firstByte: DDRUMResourceEventResourceFirstByte? { + root.swiftModel.resource.firstByte != nil ? DDRUMResourceEventResourceFirstByte(root: root) : nil } @objc public var id: String? { - root.swiftModel.action.id + root.swiftModel.resource.id } - @objc public var loadingTime: NSNumber? { - root.swiftModel.action.loadingTime as NSNumber? + @objc public var method: DDRUMResourceEventResourceRUMMethod { + .init(swift: root.swiftModel.resource.method) } - @objc public var longTask: DDRUMActionEventActionLongTask? { - root.swiftModel.action.longTask != nil ? DDRUMActionEventActionLongTask(root: root) : nil + @objc public var provider: DDRUMResourceEventResourceProvider? { + root.swiftModel.resource.provider != nil ? DDRUMResourceEventResourceProvider(root: root) : nil } - @objc public var resource: DDRUMActionEventActionResource? { - root.swiftModel.action.resource != nil ? DDRUMActionEventActionResource(root: root) : nil + @objc public var redirect: DDRUMResourceEventResourceRedirect? { + root.swiftModel.resource.redirect != nil ? DDRUMResourceEventResourceRedirect(root: root) : nil } - @objc public var target: DDRUMActionEventActionTarget? { - root.swiftModel.action.target != nil ? DDRUMActionEventActionTarget(root: root) : nil + @objc public var size: NSNumber? { + root.swiftModel.resource.size as NSNumber? + } + + @objc public var ssl: DDRUMResourceEventResourceSSL? { + root.swiftModel.resource.ssl != nil ? DDRUMResourceEventResourceSSL(root: root) : nil } - @objc public var type: DDRUMActionEventActionActionType { - .init(swift: root.swiftModel.action.type) + @objc public var statusCode: NSNumber? { + root.swiftModel.resource.statusCode as NSNumber? } -} - -@objc -public class DDRUMActionEventActionCrash: NSObject { - internal let root: DDRUMActionEvent - internal init(root: DDRUMActionEvent) { - self.root = root + @objc public var type: DDRUMResourceEventResourceResourceType { + .init(swift: root.swiftModel.resource.type) } - @objc public var count: NSNumber { - root.swiftModel.action.crash!.count as NSNumber + @objc public var url: String { + set { root.swiftModel.resource.url = newValue } + get { root.swiftModel.resource.url } } } @objc -public class DDRUMActionEventActionError: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventResourceConnect: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } - @objc public var count: NSNumber { - root.swiftModel.action.error!.count as NSNumber + @objc public var duration: NSNumber { + root.swiftModel.resource.connect!.duration as NSNumber + } + + @objc public var start: NSNumber { + root.swiftModel.resource.connect!.start as NSNumber } } @objc -public class DDRUMActionEventActionLongTask: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventResourceDNS: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } - @objc public var count: NSNumber { - root.swiftModel.action.longTask!.count as NSNumber + @objc public var duration: NSNumber { + root.swiftModel.resource.dns!.duration as NSNumber + } + + @objc public var start: NSNumber { + root.swiftModel.resource.dns!.start as NSNumber } } @objc -public class DDRUMActionEventActionResource: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventResourceDownload: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } - @objc public var count: NSNumber { - root.swiftModel.action.resource!.count as NSNumber + @objc public var duration: NSNumber { + root.swiftModel.resource.download!.duration as NSNumber + } + + @objc public var start: NSNumber { + root.swiftModel.resource.download!.start as NSNumber } } @objc -public class DDRUMActionEventActionTarget: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventResourceFirstByte: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } - @objc public var name: String { - set { root.swiftModel.action.target!.name = newValue } - get { root.swiftModel.action.target!.name } + @objc public var duration: NSNumber { + root.swiftModel.resource.firstByte!.duration as NSNumber + } + + @objc public var start: NSNumber { + root.swiftModel.resource.firstByte!.start as NSNumber } } @objc -public enum DDRUMActionEventActionActionType: Int { - internal init(swift: RUMActionEvent.Action.ActionType) { +public enum DDRUMResourceEventResourceRUMMethod: Int { + internal init(swift: RUMMethod?) { switch swift { - case .custom: self = .custom - case .click: self = .click - case .tap: self = .tap - case .scroll: self = .scroll - case .swipe: self = .swipe - case .applicationStart: self = .applicationStart - case .back: self = .back + case nil: self = .none + case .post?: self = .post + case .get?: self = .get + case .head?: self = .head + case .put?: self = .put + case .delete?: self = .delete + case .patch?: self = .patch } } - internal var toSwift: RUMActionEvent.Action.ActionType { + internal var toSwift: RUMMethod? { switch self { - case .custom: return .custom - case .click: return .click - case .tap: return .tap - case .scroll: return .scroll - case .swipe: return .swipe - case .applicationStart: return .applicationStart - case .back: return .back + case .none: return nil + case .post: return .post + case .get: return .get + case .head: return .head + case .put: return .put + case .delete: return .delete + case .patch: return .patch } } - case custom - case click - case tap - case scroll - case swipe - case applicationStart - case back + case none + case post + case get + case head + case put + case delete + case patch } @objc -public class DDRUMActionEventApplication: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventResourceProvider: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } - @objc public var id: String { - root.swiftModel.application.id + @objc public var domain: String? { + root.swiftModel.resource.provider!.domain } -} - -@objc -public class DDRUMActionEventCiTest: NSObject { - internal let root: DDRUMActionEvent - internal init(root: DDRUMActionEvent) { - self.root = root + @objc public var name: String? { + root.swiftModel.resource.provider!.name } - @objc public var testExecutionId: String { - root.swiftModel.ciTest!.testExecutionId + @objc public var type: DDRUMResourceEventResourceProviderProviderType { + .init(swift: root.swiftModel.resource.provider!.type) } } @objc -public class DDRUMActionEventRUMConnectivity: NSObject { - internal let root: DDRUMActionEvent - - internal init(root: DDRUMActionEvent) { - self.root = root - } - - @objc public var cellular: DDRUMActionEventRUMConnectivityCellular? { - root.swiftModel.connectivity!.cellular != nil ? DDRUMActionEventRUMConnectivityCellular(root: root) : nil +public enum DDRUMResourceEventResourceProviderProviderType: Int { + internal init(swift: RUMResourceEvent.Resource.Provider.ProviderType?) { + switch swift { + case nil: self = .none + case .ad?: self = .ad + case .advertising?: self = .advertising + case .analytics?: self = .analytics + case .cdn?: self = .cdn + case .content?: self = .content + case .customerSuccess?: self = .customerSuccess + case .firstParty?: self = .firstParty + case .hosting?: self = .hosting + case .marketing?: self = .marketing + case .other?: self = .other + case .social?: self = .social + case .tagManager?: self = .tagManager + case .utility?: self = .utility + case .video?: self = .video + } } - @objc public var interfaces: [Int] { - root.swiftModel.connectivity!.interfaces.map { DDRUMActionEventRUMConnectivityInterfaces(swift: $0).rawValue } + internal var toSwift: RUMResourceEvent.Resource.Provider.ProviderType? { + switch self { + case .none: return nil + case .ad: return .ad + case .advertising: return .advertising + case .analytics: return .analytics + case .cdn: return .cdn + case .content: return .content + case .customerSuccess: return .customerSuccess + case .firstParty: return .firstParty + case .hosting: return .hosting + case .marketing: return .marketing + case .other: return .other + case .social: return .social + case .tagManager: return .tagManager + case .utility: return .utility + case .video: return .video + } } - @objc public var status: DDRUMActionEventRUMConnectivityStatus { - .init(swift: root.swiftModel.connectivity!.status) - } + case none + case ad + case advertising + case analytics + case cdn + case content + case customerSuccess + case firstParty + case hosting + case marketing + case other + case social + case tagManager + case utility + case video } @objc -public class DDRUMActionEventRUMConnectivityCellular: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventResourceRedirect: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } - @objc public var carrierName: String? { - root.swiftModel.connectivity!.cellular!.carrierName - } - - @objc public var technology: String? { - root.swiftModel.connectivity!.cellular!.technology - } -} - -@objc -public enum DDRUMActionEventRUMConnectivityInterfaces: Int { - internal init(swift: RUMConnectivity.Interfaces) { - switch swift { - case .bluetooth: self = .bluetooth - case .cellular: self = .cellular - case .ethernet: self = .ethernet - case .wifi: self = .wifi - case .wimax: self = .wimax - case .mixed: self = .mixed - case .other: self = .other - case .unknown: self = .unknown - case .none: self = .none - } - } - - internal var toSwift: RUMConnectivity.Interfaces { - switch self { - case .bluetooth: return .bluetooth - case .cellular: return .cellular - case .ethernet: return .ethernet - case .wifi: return .wifi - case .wimax: return .wimax - case .mixed: return .mixed - case .other: return .other - case .unknown: return .unknown - case .none: return .none - } + @objc public var duration: NSNumber { + root.swiftModel.resource.redirect!.duration as NSNumber } - case bluetooth - case cellular - case ethernet - case wifi - case wimax - case mixed - case other - case unknown - case none + @objc public var start: NSNumber { + root.swiftModel.resource.redirect!.start as NSNumber + } } @objc -public enum DDRUMActionEventRUMConnectivityStatus: Int { - internal init(swift: RUMConnectivity.Status) { - switch swift { - case .connected: self = .connected - case .notConnected: self = .notConnected - case .maybe: self = .maybe - } +public class DDRUMResourceEventResourceSSL: NSObject { + internal let root: DDRUMResourceEvent + + internal init(root: DDRUMResourceEvent) { + self.root = root } - internal var toSwift: RUMConnectivity.Status { - switch self { - case .connected: return .connected - case .notConnected: return .notConnected - case .maybe: return .maybe - } + @objc public var duration: NSNumber { + root.swiftModel.resource.ssl!.duration as NSNumber } - case connected - case notConnected - case maybe + @objc public var start: NSNumber { + root.swiftModel.resource.ssl!.start as NSNumber + } } @objc -public class DDRUMActionEventRUMEventAttributes: NSObject { - internal let root: DDRUMActionEvent - - internal init(root: DDRUMActionEvent) { - self.root = root +public enum DDRUMResourceEventResourceResourceType: Int { + internal init(swift: RUMResourceEvent.Resource.ResourceType) { + switch swift { + case .document: self = .document + case .xhr: self = .xhr + case .beacon: self = .beacon + case .fetch: self = .fetch + case .css: self = .css + case .js: self = .js + case .image: self = .image + case .font: self = .font + case .media: self = .media + case .other: self = .other + case .native: self = .native + } } - @objc public var contextInfo: [String: Any] { - root.swiftModel.context!.contextInfo.castToObjectiveC() + internal var toSwift: RUMResourceEvent.Resource.ResourceType { + switch self { + case .document: return .document + case .xhr: return .xhr + case .beacon: return .beacon + case .fetch: return .fetch + case .css: return .css + case .js: return .js + case .image: return .image + case .font: return .font + case .media: return .media + case .other: return .other + case .native: return .native + } } + + case document + case xhr + case beacon + case fetch + case css + case js + case image + case font + case media + case other + case native } @objc -public class DDRUMActionEventSession: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventSession: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } @@ -1856,14 +2363,14 @@ public class DDRUMActionEventSession: NSObject { root.swiftModel.session.id } - @objc public var type: DDRUMActionEventSessionSessionType { + @objc public var type: DDRUMResourceEventSessionSessionType { .init(swift: root.swiftModel.session.type) } } @objc -public enum DDRUMActionEventSessionSessionType: Int { - internal init(swift: RUMActionEvent.Session.SessionType) { +public enum DDRUMResourceEventSessionSessionType: Int { + internal init(swift: RUMResourceEvent.Session.SessionType) { switch swift { case .user: self = .user case .synthetics: self = .synthetics @@ -1871,7 +2378,7 @@ public enum DDRUMActionEventSessionSessionType: Int { } } - internal var toSwift: RUMActionEvent.Session.SessionType { + internal var toSwift: RUMResourceEvent.Session.SessionType { switch self { case .user: return .user case .synthetics: return .synthetics @@ -1885,8 +2392,8 @@ public enum DDRUMActionEventSessionSessionType: Int { } @objc -public enum DDRUMActionEventSource: Int { - internal init(swift: RUMActionEvent.Source?) { +public enum DDRUMResourceEventSource: Int { + internal init(swift: RUMResourceEvent.Source?) { switch swift { case nil: self = .none case .android?: self = .android @@ -1897,7 +2404,7 @@ public enum DDRUMActionEventSource: Int { } } - internal var toSwift: RUMActionEvent.Source? { + internal var toSwift: RUMResourceEvent.Source? { switch self { case .none: return nil case .android: return .android @@ -1917,645 +2424,345 @@ public enum DDRUMActionEventSource: Int { } @objc -public class DDRUMActionEventSynthetics: NSObject { - internal let root: DDRUMActionEvent - - internal init(root: DDRUMActionEvent) { - self.root = root - } - - @objc public var injected: NSNumber? { - root.swiftModel.synthetics!.injected as NSNumber? - } - - @objc public var resultId: String { - root.swiftModel.synthetics!.resultId - } - - @objc public var testId: String { - root.swiftModel.synthetics!.testId - } -} - -@objc -public class DDRUMActionEventRUMUser: NSObject { - internal let root: DDRUMActionEvent - - internal init(root: DDRUMActionEvent) { - self.root = root - } - - @objc public var email: String? { - root.swiftModel.usr!.email - } - - @objc public var id: String? { - root.swiftModel.usr!.id - } - - @objc public var name: String? { - root.swiftModel.usr!.name - } - - @objc public var usrInfo: [String: Any] { - root.swiftModel.usr!.usrInfo.castToObjectiveC() - } -} - -@objc -public class DDRUMActionEventView: NSObject { - internal let root: DDRUMActionEvent - - internal init(root: DDRUMActionEvent) { - self.root = root - } - - @objc public var id: String { - root.swiftModel.view.id - } - - @objc public var inForeground: NSNumber? { - root.swiftModel.view.inForeground as NSNumber? - } - - @objc public var name: String? { - set { root.swiftModel.view.name = newValue } - get { root.swiftModel.view.name } - } - - @objc public var referrer: String? { - set { root.swiftModel.view.referrer = newValue } - get { root.swiftModel.view.referrer } - } - - @objc public var url: String { - set { root.swiftModel.view.url = newValue } - get { root.swiftModel.view.url } - } -} - -@objc -public class DDRUMErrorEvent: NSObject { - internal var swiftModel: RUMErrorEvent - internal var root: DDRUMErrorEvent { self } - - internal init(swiftModel: RUMErrorEvent) { - self.swiftModel = swiftModel - } - - @objc public var dd: DDRUMErrorEventDD { - DDRUMErrorEventDD(root: root) - } - - @objc public var action: DDRUMErrorEventAction? { - root.swiftModel.action != nil ? DDRUMErrorEventAction(root: root) : nil - } - - @objc public var application: DDRUMErrorEventApplication { - DDRUMErrorEventApplication(root: root) - } - - @objc public var ciTest: DDRUMErrorEventCiTest? { - root.swiftModel.ciTest != nil ? DDRUMErrorEventCiTest(root: root) : nil - } - - @objc public var connectivity: DDRUMErrorEventRUMConnectivity? { - root.swiftModel.connectivity != nil ? DDRUMErrorEventRUMConnectivity(root: root) : nil - } - - @objc public var context: DDRUMErrorEventRUMEventAttributes? { - root.swiftModel.context != nil ? DDRUMErrorEventRUMEventAttributes(root: root) : nil - } - - @objc public var date: NSNumber { - root.swiftModel.date as NSNumber - } - - @objc public var error: DDRUMErrorEventError { - DDRUMErrorEventError(root: root) - } - - @objc public var service: String? { - root.swiftModel.service - } - - @objc public var session: DDRUMErrorEventSession { - DDRUMErrorEventSession(root: root) - } - - @objc public var source: DDRUMErrorEventSource { - .init(swift: root.swiftModel.source) - } - - @objc public var synthetics: DDRUMErrorEventSynthetics? { - root.swiftModel.synthetics != nil ? DDRUMErrorEventSynthetics(root: root) : nil - } - - @objc public var type: String { - root.swiftModel.type - } - - @objc public var usr: DDRUMErrorEventRUMUser? { - root.swiftModel.usr != nil ? DDRUMErrorEventRUMUser(root: root) : nil - } - - @objc public var view: DDRUMErrorEventView { - DDRUMErrorEventView(root: root) - } -} - -@objc -public class DDRUMErrorEventDD: NSObject { - internal let root: DDRUMErrorEvent +public class DDRUMResourceEventSynthetics: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMErrorEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } - @objc public var browserSdkVersion: String? { - root.swiftModel.dd.browserSdkVersion + @objc public var injected: NSNumber? { + root.swiftModel.synthetics!.injected as NSNumber? } - @objc public var formatVersion: NSNumber { - root.swiftModel.dd.formatVersion as NSNumber + @objc public var resultId: String { + root.swiftModel.synthetics!.resultId } - @objc public var session: DDRUMErrorEventDDSession? { - root.swiftModel.dd.session != nil ? DDRUMErrorEventDDSession(root: root) : nil + @objc public var testId: String { + root.swiftModel.synthetics!.testId } } @objc -public class DDRUMErrorEventDDSession: NSObject { - internal let root: DDRUMErrorEvent +public class DDRUMResourceEventRUMUser: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMErrorEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } - @objc public var plan: DDRUMErrorEventDDSessionPlan { - .init(swift: root.swiftModel.dd.session!.plan) - } -} - -@objc -public enum DDRUMErrorEventDDSessionPlan: Int { - internal init(swift: RUMErrorEvent.DD.Session.Plan) { - switch swift { - case .plan1: self = .plan1 - case .plan2: self = .plan2 - } + @objc public var email: String? { + root.swiftModel.usr!.email } - internal var toSwift: RUMErrorEvent.DD.Session.Plan { - switch self { - case .plan1: return .plan1 - case .plan2: return .plan2 - } + @objc public var id: String? { + root.swiftModel.usr!.id } - case plan1 - case plan2 -} - -@objc -public class DDRUMErrorEventAction: NSObject { - internal let root: DDRUMErrorEvent - - internal init(root: DDRUMErrorEvent) { - self.root = root + @objc public var name: String? { + root.swiftModel.usr!.name } - @objc public var id: String { - root.swiftModel.action!.id + @objc public var usrInfo: [String: Any] { + root.swiftModel.usr!.usrInfo.castToObjectiveC() } } @objc -public class DDRUMErrorEventApplication: NSObject { - internal let root: DDRUMErrorEvent +public class DDRUMResourceEventView: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMErrorEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } @objc public var id: String { - root.swiftModel.application.id + root.swiftModel.view.id } -} -@objc -public class DDRUMErrorEventCiTest: NSObject { - internal let root: DDRUMErrorEvent + @objc public var name: String? { + set { root.swiftModel.view.name = newValue } + get { root.swiftModel.view.name } + } - internal init(root: DDRUMErrorEvent) { - self.root = root + @objc public var referrer: String? { + set { root.swiftModel.view.referrer = newValue } + get { root.swiftModel.view.referrer } } - @objc public var testExecutionId: String { - root.swiftModel.ciTest!.testExecutionId + @objc public var url: String { + set { root.swiftModel.view.url = newValue } + get { root.swiftModel.view.url } } } @objc -public class DDRUMErrorEventRUMConnectivity: NSObject { - internal let root: DDRUMErrorEvent +public class DDRUMViewEvent: NSObject { + internal var swiftModel: RUMViewEvent + internal var root: DDRUMViewEvent { self } - internal init(root: DDRUMErrorEvent) { - self.root = root + internal init(swiftModel: RUMViewEvent) { + self.swiftModel = swiftModel } - @objc public var cellular: DDRUMErrorEventRUMConnectivityCellular? { - root.swiftModel.connectivity!.cellular != nil ? DDRUMErrorEventRUMConnectivityCellular(root: root) : nil + @objc public var dd: DDRUMViewEventDD { + DDRUMViewEventDD(root: root) } - @objc public var interfaces: [Int] { - root.swiftModel.connectivity!.interfaces.map { DDRUMErrorEventRUMConnectivityInterfaces(swift: $0).rawValue } + @objc public var application: DDRUMViewEventApplication { + DDRUMViewEventApplication(root: root) } - @objc public var status: DDRUMErrorEventRUMConnectivityStatus { - .init(swift: root.swiftModel.connectivity!.status) + @objc public var ciTest: DDRUMViewEventRUMCITest? { + root.swiftModel.ciTest != nil ? DDRUMViewEventRUMCITest(root: root) : nil } -} - -@objc -public class DDRUMErrorEventRUMConnectivityCellular: NSObject { - internal let root: DDRUMErrorEvent - internal init(root: DDRUMErrorEvent) { - self.root = root + @objc public var connectivity: DDRUMViewEventRUMConnectivity? { + root.swiftModel.connectivity != nil ? DDRUMViewEventRUMConnectivity(root: root) : nil } - @objc public var carrierName: String? { - root.swiftModel.connectivity!.cellular!.carrierName + @objc public var context: DDRUMViewEventRUMEventAttributes? { + root.swiftModel.context != nil ? DDRUMViewEventRUMEventAttributes(root: root) : nil } - @objc public var technology: String? { - root.swiftModel.connectivity!.cellular!.technology + @objc public var date: NSNumber { + root.swiftModel.date as NSNumber } -} -@objc -public enum DDRUMErrorEventRUMConnectivityInterfaces: Int { - internal init(swift: RUMConnectivity.Interfaces) { - switch swift { - case .bluetooth: self = .bluetooth - case .cellular: self = .cellular - case .ethernet: self = .ethernet - case .wifi: self = .wifi - case .wimax: self = .wimax - case .mixed: self = .mixed - case .other: self = .other - case .unknown: self = .unknown - case .none: self = .none - } + @objc public var service: String? { + root.swiftModel.service } - internal var toSwift: RUMConnectivity.Interfaces { - switch self { - case .bluetooth: return .bluetooth - case .cellular: return .cellular - case .ethernet: return .ethernet - case .wifi: return .wifi - case .wimax: return .wimax - case .mixed: return .mixed - case .other: return .other - case .unknown: return .unknown - case .none: return .none - } + @objc public var session: DDRUMViewEventSession { + DDRUMViewEventSession(root: root) } - case bluetooth - case cellular - case ethernet - case wifi - case wimax - case mixed - case other - case unknown - case none -} - -@objc -public enum DDRUMErrorEventRUMConnectivityStatus: Int { - internal init(swift: RUMConnectivity.Status) { - switch swift { - case .connected: self = .connected - case .notConnected: self = .notConnected - case .maybe: self = .maybe - } + @objc public var source: DDRUMViewEventSource { + .init(swift: root.swiftModel.source) } - internal var toSwift: RUMConnectivity.Status { - switch self { - case .connected: return .connected - case .notConnected: return .notConnected - case .maybe: return .maybe - } + @objc public var synthetics: DDRUMViewEventSynthetics? { + root.swiftModel.synthetics != nil ? DDRUMViewEventSynthetics(root: root) : nil } - case connected - case notConnected - case maybe -} - -@objc -public class DDRUMErrorEventRUMEventAttributes: NSObject { - internal let root: DDRUMErrorEvent + @objc public var type: String { + root.swiftModel.type + } - internal init(root: DDRUMErrorEvent) { - self.root = root + @objc public var usr: DDRUMViewEventRUMUser? { + root.swiftModel.usr != nil ? DDRUMViewEventRUMUser(root: root) : nil } - @objc public var contextInfo: [String: Any] { - root.swiftModel.context!.contextInfo.castToObjectiveC() + @objc public var view: DDRUMViewEventView { + DDRUMViewEventView(root: root) } } @objc -public class DDRUMErrorEventError: NSObject { - internal let root: DDRUMErrorEvent +public class DDRUMViewEventDD: NSObject { + internal let root: DDRUMViewEvent - internal init(root: DDRUMErrorEvent) { + internal init(root: DDRUMViewEvent) { self.root = root } - @objc public var handling: DDRUMErrorEventErrorHandling { - .init(swift: root.swiftModel.error.handling) - } - - @objc public var handlingStack: String? { - root.swiftModel.error.handlingStack - } - - @objc public var id: String? { - root.swiftModel.error.id - } - - @objc public var isCrash: NSNumber? { - root.swiftModel.error.isCrash as NSNumber? + @objc public var browserSdkVersion: String? { + root.swiftModel.dd.browserSdkVersion } - @objc public var message: String { - set { root.swiftModel.error.message = newValue } - get { root.swiftModel.error.message } + @objc public var documentVersion: NSNumber { + root.swiftModel.dd.documentVersion as NSNumber } - @objc public var resource: DDRUMErrorEventErrorResource? { - root.swiftModel.error.resource != nil ? DDRUMErrorEventErrorResource(root: root) : nil + @objc public var formatVersion: NSNumber { + root.swiftModel.dd.formatVersion as NSNumber } - @objc public var source: DDRUMErrorEventErrorSource { - .init(swift: root.swiftModel.error.source) + @objc public var session: DDRUMViewEventDDSession? { + root.swiftModel.dd.session != nil ? DDRUMViewEventDDSession(root: root) : nil } +} - @objc public var sourceType: DDRUMErrorEventErrorSourceType { - .init(swift: root.swiftModel.error.sourceType) - } +@objc +public class DDRUMViewEventDDSession: NSObject { + internal let root: DDRUMViewEvent - @objc public var stack: String? { - set { root.swiftModel.error.stack = newValue } - get { root.swiftModel.error.stack } + internal init(root: DDRUMViewEvent) { + self.root = root } - @objc public var type: String? { - root.swiftModel.error.type + @objc public var plan: DDRUMViewEventDDSessionPlan { + .init(swift: root.swiftModel.dd.session!.plan) } } @objc -public enum DDRUMErrorEventErrorHandling: Int { - internal init(swift: RUMErrorEvent.Error.Handling?) { - switch swift { - case nil: self = .none - case .handled?: self = .handled - case .unhandled?: self = .unhandled +public enum DDRUMViewEventDDSessionPlan: Int { + internal init(swift: RUMViewEvent.DD.Session.Plan) { + switch swift { + case .plan1: self = .plan1 + case .plan2: self = .plan2 } } - internal var toSwift: RUMErrorEvent.Error.Handling? { + internal var toSwift: RUMViewEvent.DD.Session.Plan { switch self { - case .none: return nil - case .handled: return .handled - case .unhandled: return .unhandled + case .plan1: return .plan1 + case .plan2: return .plan2 } } - case none - case handled - case unhandled + case plan1 + case plan2 } @objc -public class DDRUMErrorEventErrorResource: NSObject { - internal let root: DDRUMErrorEvent +public class DDRUMViewEventApplication: NSObject { + internal let root: DDRUMViewEvent - internal init(root: DDRUMErrorEvent) { + internal init(root: DDRUMViewEvent) { self.root = root } - @objc public var method: DDRUMErrorEventErrorResourceRUMMethod { - .init(swift: root.swiftModel.error.resource!.method) + @objc public var id: String { + root.swiftModel.application.id } +} - @objc public var provider: DDRUMErrorEventErrorResourceProvider? { - root.swiftModel.error.resource!.provider != nil ? DDRUMErrorEventErrorResourceProvider(root: root) : nil - } +@objc +public class DDRUMViewEventRUMCITest: NSObject { + internal let root: DDRUMViewEvent - @objc public var statusCode: NSNumber { - root.swiftModel.error.resource!.statusCode as NSNumber + internal init(root: DDRUMViewEvent) { + self.root = root } - @objc public var url: String { - set { root.swiftModel.error.resource!.url = newValue } - get { root.swiftModel.error.resource!.url } + @objc public var testExecutionId: String { + root.swiftModel.ciTest!.testExecutionId } } @objc -public enum DDRUMErrorEventErrorResourceRUMMethod: Int { - internal init(swift: RUMMethod) { - switch swift { - case .post: self = .post - case .get: self = .get - case .head: self = .head - case .put: self = .put - case .delete: self = .delete - case .patch: self = .patch - } +public class DDRUMViewEventRUMConnectivity: NSObject { + internal let root: DDRUMViewEvent + + internal init(root: DDRUMViewEvent) { + self.root = root } - internal var toSwift: RUMMethod { - switch self { - case .post: return .post - case .get: return .get - case .head: return .head - case .put: return .put - case .delete: return .delete - case .patch: return .patch - } + @objc public var cellular: DDRUMViewEventRUMConnectivityCellular? { + root.swiftModel.connectivity!.cellular != nil ? DDRUMViewEventRUMConnectivityCellular(root: root) : nil } - case post - case get - case head - case put - case delete - case patch + @objc public var interfaces: [Int] { + root.swiftModel.connectivity!.interfaces.map { DDRUMViewEventRUMConnectivityInterfaces(swift: $0).rawValue } + } + + @objc public var status: DDRUMViewEventRUMConnectivityStatus { + .init(swift: root.swiftModel.connectivity!.status) + } } @objc -public class DDRUMErrorEventErrorResourceProvider: NSObject { - internal let root: DDRUMErrorEvent +public class DDRUMViewEventRUMConnectivityCellular: NSObject { + internal let root: DDRUMViewEvent - internal init(root: DDRUMErrorEvent) { + internal init(root: DDRUMViewEvent) { self.root = root } - @objc public var domain: String? { - root.swiftModel.error.resource!.provider!.domain - } - - @objc public var name: String? { - root.swiftModel.error.resource!.provider!.name + @objc public var carrierName: String? { + root.swiftModel.connectivity!.cellular!.carrierName } - @objc public var type: DDRUMErrorEventErrorResourceProviderProviderType { - .init(swift: root.swiftModel.error.resource!.provider!.type) + @objc public var technology: String? { + root.swiftModel.connectivity!.cellular!.technology } } @objc -public enum DDRUMErrorEventErrorResourceProviderProviderType: Int { - internal init(swift: RUMErrorEvent.Error.Resource.Provider.ProviderType?) { +public enum DDRUMViewEventRUMConnectivityInterfaces: Int { + internal init(swift: RUMConnectivity.Interfaces) { switch swift { - case nil: self = .none - case .ad?: self = .ad - case .advertising?: self = .advertising - case .analytics?: self = .analytics - case .cdn?: self = .cdn - case .content?: self = .content - case .customerSuccess?: self = .customerSuccess - case .firstParty?: self = .firstParty - case .hosting?: self = .hosting - case .marketing?: self = .marketing - case .other?: self = .other - case .social?: self = .social - case .tagManager?: self = .tagManager - case .utility?: self = .utility - case .video?: self = .video + case .bluetooth: self = .bluetooth + case .cellular: self = .cellular + case .ethernet: self = .ethernet + case .wifi: self = .wifi + case .wimax: self = .wimax + case .mixed: self = .mixed + case .other: self = .other + case .unknown: self = .unknown + case .none: self = .none } } - internal var toSwift: RUMErrorEvent.Error.Resource.Provider.ProviderType? { + internal var toSwift: RUMConnectivity.Interfaces { switch self { - case .none: return nil - case .ad: return .ad - case .advertising: return .advertising - case .analytics: return .analytics - case .cdn: return .cdn - case .content: return .content - case .customerSuccess: return .customerSuccess - case .firstParty: return .firstParty - case .hosting: return .hosting - case .marketing: return .marketing + case .bluetooth: return .bluetooth + case .cellular: return .cellular + case .ethernet: return .ethernet + case .wifi: return .wifi + case .wimax: return .wimax + case .mixed: return .mixed case .other: return .other - case .social: return .social - case .tagManager: return .tagManager - case .utility: return .utility - case .video: return .video + case .unknown: return .unknown + case .none: return .none } } - case none - case ad - case advertising - case analytics - case cdn - case content - case customerSuccess - case firstParty - case hosting - case marketing + case bluetooth + case cellular + case ethernet + case wifi + case wimax + case mixed case other - case social - case tagManager - case utility - case video + case unknown + case none } @objc -public enum DDRUMErrorEventErrorSource: Int { - internal init(swift: RUMErrorEvent.Error.Source) { +public enum DDRUMViewEventRUMConnectivityStatus: Int { + internal init(swift: RUMConnectivity.Status) { switch swift { - case .network: self = .network - case .source: self = .source - case .console: self = .console - case .logger: self = .logger - case .agent: self = .agent - case .webview: self = .webview - case .custom: self = .custom + case .connected: self = .connected + case .notConnected: self = .notConnected + case .maybe: self = .maybe } } - internal var toSwift: RUMErrorEvent.Error.Source { + internal var toSwift: RUMConnectivity.Status { switch self { - case .network: return .network - case .source: return .source - case .console: return .console - case .logger: return .logger - case .agent: return .agent - case .webview: return .webview - case .custom: return .custom + case .connected: return .connected + case .notConnected: return .notConnected + case .maybe: return .maybe } } - case network - case source - case console - case logger - case agent - case webview - case custom + case connected + case notConnected + case maybe } @objc -public enum DDRUMErrorEventErrorSourceType: Int { - internal init(swift: RUMErrorEvent.Error.SourceType?) { - switch swift { - case nil: self = .none - case .android?: self = .android - case .browser?: self = .browser - case .ios?: self = .ios - case .reactNative?: self = .reactNative - case .flutter?: self = .flutter - } - } +public class DDRUMViewEventRUMEventAttributes: NSObject { + internal let root: DDRUMViewEvent - internal var toSwift: RUMErrorEvent.Error.SourceType? { - switch self { - case .none: return nil - case .android: return .android - case .browser: return .browser - case .ios: return .ios - case .reactNative: return .reactNative - case .flutter: return .flutter - } + internal init(root: DDRUMViewEvent) { + self.root = root } - case none - case android - case browser - case ios - case reactNative - case flutter + @objc public var contextInfo: [String: Any] { + root.swiftModel.context!.contextInfo.castToObjectiveC() + } } @objc -public class DDRUMErrorEventSession: NSObject { - internal let root: DDRUMErrorEvent +public class DDRUMViewEventSession: NSObject { + internal let root: DDRUMViewEvent - internal init(root: DDRUMErrorEvent) { + internal init(root: DDRUMViewEvent) { self.root = root } @@ -2567,14 +2774,14 @@ public class DDRUMErrorEventSession: NSObject { root.swiftModel.session.id } - @objc public var type: DDRUMErrorEventSessionSessionType { + @objc public var type: DDRUMViewEventSessionSessionType { .init(swift: root.swiftModel.session.type) } } @objc -public enum DDRUMErrorEventSessionSessionType: Int { - internal init(swift: RUMErrorEvent.Session.SessionType) { +public enum DDRUMViewEventSessionSessionType: Int { + internal init(swift: RUMViewEvent.Session.SessionType) { switch swift { case .user: self = .user case .synthetics: self = .synthetics @@ -2582,7 +2789,7 @@ public enum DDRUMErrorEventSessionSessionType: Int { } } - internal var toSwift: RUMErrorEvent.Session.SessionType { + internal var toSwift: RUMViewEvent.Session.SessionType { switch self { case .user: return .user case .synthetics: return .synthetics @@ -2596,8 +2803,8 @@ public enum DDRUMErrorEventSessionSessionType: Int { } @objc -public enum DDRUMErrorEventSource: Int { - internal init(swift: RUMErrorEvent.Source?) { +public enum DDRUMViewEventSource: Int { + internal init(swift: RUMViewEvent.Source?) { switch swift { case nil: self = .none case .android?: self = .android @@ -2608,7 +2815,7 @@ public enum DDRUMErrorEventSource: Int { } } - internal var toSwift: RUMErrorEvent.Source? { + internal var toSwift: RUMViewEvent.Source? { switch self { case .none: return nil case .android: return .android @@ -2628,10 +2835,10 @@ public enum DDRUMErrorEventSource: Int { } @objc -public class DDRUMErrorEventSynthetics: NSObject { - internal let root: DDRUMErrorEvent +public class DDRUMViewEventSynthetics: NSObject { + internal let root: DDRUMViewEvent - internal init(root: DDRUMErrorEvent) { + internal init(root: DDRUMViewEvent) { self.root = root } @@ -2649,10 +2856,10 @@ public class DDRUMErrorEventSynthetics: NSObject { } @objc -public class DDRUMErrorEventRUMUser: NSObject { - internal let root: DDRUMErrorEvent +public class DDRUMViewEventRUMUser: NSObject { + internal let root: DDRUMViewEvent - internal init(root: DDRUMErrorEvent) { + internal init(root: DDRUMViewEvent) { self.root = root } @@ -2674,486 +2881,533 @@ public class DDRUMErrorEventRUMUser: NSObject { } @objc -public class DDRUMErrorEventView: NSObject { - internal let root: DDRUMErrorEvent +public class DDRUMViewEventView: NSObject { + internal let root: DDRUMViewEvent - internal init(root: DDRUMErrorEvent) { + internal init(root: DDRUMViewEvent) { self.root = root } + @objc public var action: DDRUMViewEventViewAction { + DDRUMViewEventViewAction(root: root) + } + + @objc public var cpuTicksCount: NSNumber? { + root.swiftModel.view.cpuTicksCount as NSNumber? + } + + @objc public var cpuTicksPerSecond: NSNumber? { + root.swiftModel.view.cpuTicksPerSecond as NSNumber? + } + + @objc public var crash: DDRUMViewEventViewCrash? { + root.swiftModel.view.crash != nil ? DDRUMViewEventViewCrash(root: root) : nil + } + + @objc public var cumulativeLayoutShift: NSNumber? { + root.swiftModel.view.cumulativeLayoutShift as NSNumber? + } + + @objc public var customTimings: [String: NSNumber]? { + root.swiftModel.view.customTimings as [String: NSNumber]? + } + + @objc public var domComplete: NSNumber? { + root.swiftModel.view.domComplete as NSNumber? + } + + @objc public var domContentLoaded: NSNumber? { + root.swiftModel.view.domContentLoaded as NSNumber? + } + + @objc public var domInteractive: NSNumber? { + root.swiftModel.view.domInteractive as NSNumber? + } + + @objc public var error: DDRUMViewEventViewError { + DDRUMViewEventViewError(root: root) + } + + @objc public var firstContentfulPaint: NSNumber? { + root.swiftModel.view.firstContentfulPaint as NSNumber? + } + + @objc public var firstInputDelay: NSNumber? { + root.swiftModel.view.firstInputDelay as NSNumber? + } + + @objc public var firstInputTime: NSNumber? { + root.swiftModel.view.firstInputTime as NSNumber? + } + + @objc public var frozenFrame: DDRUMViewEventViewFrozenFrame? { + root.swiftModel.view.frozenFrame != nil ? DDRUMViewEventViewFrozenFrame(root: root) : nil + } + @objc public var id: String { root.swiftModel.view.id } - @objc public var inForeground: NSNumber? { - root.swiftModel.view.inForeground as NSNumber? + @objc public var inForegroundPeriods: [DDRUMViewEventViewInForegroundPeriods]? { + root.swiftModel.view.inForegroundPeriods?.map { DDRUMViewEventViewInForegroundPeriods(swiftModel: $0) } } - @objc public var name: String? { - set { root.swiftModel.view.name = newValue } - get { root.swiftModel.view.name } + @objc public var isActive: NSNumber? { + root.swiftModel.view.isActive as NSNumber? } - @objc public var referrer: String? { - set { root.swiftModel.view.referrer = newValue } - get { root.swiftModel.view.referrer } + @objc public var isSlowRendered: NSNumber? { + root.swiftModel.view.isSlowRendered as NSNumber? } - @objc public var url: String { - set { root.swiftModel.view.url = newValue } - get { root.swiftModel.view.url } + @objc public var largestContentfulPaint: NSNumber? { + root.swiftModel.view.largestContentfulPaint as NSNumber? } -} -@objc -public class DDRUMLongTaskEvent: NSObject { - internal var swiftModel: RUMLongTaskEvent - internal var root: DDRUMLongTaskEvent { self } + @objc public var loadEvent: NSNumber? { + root.swiftModel.view.loadEvent as NSNumber? + } - internal init(swiftModel: RUMLongTaskEvent) { - self.swiftModel = swiftModel + @objc public var loadingTime: NSNumber? { + root.swiftModel.view.loadingTime as NSNumber? } - @objc public var dd: DDRUMLongTaskEventDD { - DDRUMLongTaskEventDD(root: root) + @objc public var loadingType: DDRUMViewEventViewLoadingType { + .init(swift: root.swiftModel.view.loadingType) } - @objc public var action: DDRUMLongTaskEventAction? { - root.swiftModel.action != nil ? DDRUMLongTaskEventAction(root: root) : nil + @objc public var longTask: DDRUMViewEventViewLongTask? { + root.swiftModel.view.longTask != nil ? DDRUMViewEventViewLongTask(root: root) : nil } - @objc public var application: DDRUMLongTaskEventApplication { - DDRUMLongTaskEventApplication(root: root) + @objc public var memoryAverage: NSNumber? { + root.swiftModel.view.memoryAverage as NSNumber? } - @objc public var ciTest: DDRUMLongTaskEventCiTest? { - root.swiftModel.ciTest != nil ? DDRUMLongTaskEventCiTest(root: root) : nil + @objc public var memoryMax: NSNumber? { + root.swiftModel.view.memoryMax as NSNumber? } - @objc public var connectivity: DDRUMLongTaskEventRUMConnectivity? { - root.swiftModel.connectivity != nil ? DDRUMLongTaskEventRUMConnectivity(root: root) : nil + @objc public var name: String? { + set { root.swiftModel.view.name = newValue } + get { root.swiftModel.view.name } } - @objc public var context: DDRUMLongTaskEventRUMEventAttributes? { - root.swiftModel.context != nil ? DDRUMLongTaskEventRUMEventAttributes(root: root) : nil + @objc public var referrer: String? { + set { root.swiftModel.view.referrer = newValue } + get { root.swiftModel.view.referrer } } - @objc public var date: NSNumber { - root.swiftModel.date as NSNumber + @objc public var refreshRateAverage: NSNumber? { + root.swiftModel.view.refreshRateAverage as NSNumber? } - @objc public var longTask: DDRUMLongTaskEventLongTask { - DDRUMLongTaskEventLongTask(root: root) + @objc public var refreshRateMin: NSNumber? { + root.swiftModel.view.refreshRateMin as NSNumber? } - @objc public var service: String? { - root.swiftModel.service + @objc public var resource: DDRUMViewEventViewResource { + DDRUMViewEventViewResource(root: root) } - @objc public var session: DDRUMLongTaskEventSession { - DDRUMLongTaskEventSession(root: root) + @objc public var timeSpent: NSNumber { + root.swiftModel.view.timeSpent as NSNumber } - @objc public var source: DDRUMLongTaskEventSource { - .init(swift: root.swiftModel.source) + @objc public var url: String { + set { root.swiftModel.view.url = newValue } + get { root.swiftModel.view.url } } +} - @objc public var synthetics: DDRUMLongTaskEventSynthetics? { - root.swiftModel.synthetics != nil ? DDRUMLongTaskEventSynthetics(root: root) : nil +@objc +public class DDRUMViewEventViewAction: NSObject { + internal let root: DDRUMViewEvent + + internal init(root: DDRUMViewEvent) { + self.root = root } - @objc public var type: String { - root.swiftModel.type + @objc public var count: NSNumber { + root.swiftModel.view.action.count as NSNumber } +} - @objc public var usr: DDRUMLongTaskEventRUMUser? { - root.swiftModel.usr != nil ? DDRUMLongTaskEventRUMUser(root: root) : nil +@objc +public class DDRUMViewEventViewCrash: NSObject { + internal let root: DDRUMViewEvent + + internal init(root: DDRUMViewEvent) { + self.root = root } - @objc public var view: DDRUMLongTaskEventView { - DDRUMLongTaskEventView(root: root) + @objc public var count: NSNumber { + root.swiftModel.view.crash!.count as NSNumber } } @objc -public class DDRUMLongTaskEventDD: NSObject { - internal let root: DDRUMLongTaskEvent +public class DDRUMViewEventViewError: NSObject { + internal let root: DDRUMViewEvent - internal init(root: DDRUMLongTaskEvent) { + internal init(root: DDRUMViewEvent) { self.root = root } - @objc public var browserSdkVersion: String? { - root.swiftModel.dd.browserSdkVersion + @objc public var count: NSNumber { + root.swiftModel.view.error.count as NSNumber } +} - @objc public var formatVersion: NSNumber { - root.swiftModel.dd.formatVersion as NSNumber +@objc +public class DDRUMViewEventViewFrozenFrame: NSObject { + internal let root: DDRUMViewEvent + + internal init(root: DDRUMViewEvent) { + self.root = root } - @objc public var session: DDRUMLongTaskEventDDSession? { - root.swiftModel.dd.session != nil ? DDRUMLongTaskEventDDSession(root: root) : nil + @objc public var count: NSNumber { + root.swiftModel.view.frozenFrame!.count as NSNumber } } @objc -public class DDRUMLongTaskEventDDSession: NSObject { - internal let root: DDRUMLongTaskEvent +public class DDRUMViewEventViewInForegroundPeriods: NSObject { + internal let swiftModel: RUMViewEvent.View.InForegroundPeriods + internal var root: DDRUMViewEventViewInForegroundPeriods { self } - internal init(root: DDRUMLongTaskEvent) { - self.root = root + internal init(swiftModel: RUMViewEvent.View.InForegroundPeriods) { + self.swiftModel = swiftModel } - @objc public var plan: DDRUMLongTaskEventDDSessionPlan { - .init(swift: root.swiftModel.dd.session!.plan) + @objc public var duration: NSNumber { + root.swiftModel.duration as NSNumber + } + + @objc public var start: NSNumber { + root.swiftModel.start as NSNumber } } @objc -public enum DDRUMLongTaskEventDDSessionPlan: Int { - internal init(swift: RUMLongTaskEvent.DD.Session.Plan) { +public enum DDRUMViewEventViewLoadingType: Int { + internal init(swift: RUMViewEvent.View.LoadingType?) { switch swift { - case .plan1: self = .plan1 - case .plan2: self = .plan2 + case nil: self = .none + case .initialLoad?: self = .initialLoad + case .routeChange?: self = .routeChange + case .activityDisplay?: self = .activityDisplay + case .activityRedisplay?: self = .activityRedisplay + case .fragmentDisplay?: self = .fragmentDisplay + case .fragmentRedisplay?: self = .fragmentRedisplay + case .viewControllerDisplay?: self = .viewControllerDisplay + case .viewControllerRedisplay?: self = .viewControllerRedisplay } } - internal var toSwift: RUMLongTaskEvent.DD.Session.Plan { + internal var toSwift: RUMViewEvent.View.LoadingType? { switch self { - case .plan1: return .plan1 - case .plan2: return .plan2 + case .none: return nil + case .initialLoad: return .initialLoad + case .routeChange: return .routeChange + case .activityDisplay: return .activityDisplay + case .activityRedisplay: return .activityRedisplay + case .fragmentDisplay: return .fragmentDisplay + case .fragmentRedisplay: return .fragmentRedisplay + case .viewControllerDisplay: return .viewControllerDisplay + case .viewControllerRedisplay: return .viewControllerRedisplay } } - case plan1 - case plan2 + case none + case initialLoad + case routeChange + case activityDisplay + case activityRedisplay + case fragmentDisplay + case fragmentRedisplay + case viewControllerDisplay + case viewControllerRedisplay } @objc -public class DDRUMLongTaskEventAction: NSObject { - internal let root: DDRUMLongTaskEvent +public class DDRUMViewEventViewLongTask: NSObject { + internal let root: DDRUMViewEvent - internal init(root: DDRUMLongTaskEvent) { + internal init(root: DDRUMViewEvent) { self.root = root } - @objc public var id: String { - root.swiftModel.action!.id + @objc public var count: NSNumber { + root.swiftModel.view.longTask!.count as NSNumber } } @objc -public class DDRUMLongTaskEventApplication: NSObject { - internal let root: DDRUMLongTaskEvent +public class DDRUMViewEventViewResource: NSObject { + internal let root: DDRUMViewEvent - internal init(root: DDRUMLongTaskEvent) { + internal init(root: DDRUMViewEvent) { self.root = root } - @objc public var id: String { - root.swiftModel.application.id + @objc public var count: NSNumber { + root.swiftModel.view.resource.count as NSNumber } } @objc -public class DDRUMLongTaskEventCiTest: NSObject { - internal let root: DDRUMLongTaskEvent +public class DDTelemetryErrorEvent: NSObject { + internal var swiftModel: TelemetryErrorEvent + internal var root: DDTelemetryErrorEvent { self } - internal init(root: DDRUMLongTaskEvent) { - self.root = root + internal init(swiftModel: TelemetryErrorEvent) { + self.swiftModel = swiftModel } - @objc public var testExecutionId: String { - root.swiftModel.ciTest!.testExecutionId + @objc public var dd: DDTelemetryErrorEventDD { + DDTelemetryErrorEventDD(root: root) } -} -@objc -public class DDRUMLongTaskEventRUMConnectivity: NSObject { - internal let root: DDRUMLongTaskEvent + @objc public var action: DDTelemetryErrorEventAction? { + root.swiftModel.action != nil ? DDTelemetryErrorEventAction(root: root) : nil + } - internal init(root: DDRUMLongTaskEvent) { - self.root = root + @objc public var application: DDTelemetryErrorEventApplication? { + root.swiftModel.application != nil ? DDTelemetryErrorEventApplication(root: root) : nil } - @objc public var cellular: DDRUMLongTaskEventRUMConnectivityCellular? { - root.swiftModel.connectivity!.cellular != nil ? DDRUMLongTaskEventRUMConnectivityCellular(root: root) : nil + @objc public var date: NSNumber { + root.swiftModel.date as NSNumber } - @objc public var interfaces: [Int] { - root.swiftModel.connectivity!.interfaces.map { DDRUMLongTaskEventRUMConnectivityInterfaces(swift: $0).rawValue } + @objc public var error: DDTelemetryErrorEventError? { + root.swiftModel.error != nil ? DDTelemetryErrorEventError(root: root) : nil } - @objc public var status: DDRUMLongTaskEventRUMConnectivityStatus { - .init(swift: root.swiftModel.connectivity!.status) + @objc public var message: String { + root.swiftModel.message } -} -@objc -public class DDRUMLongTaskEventRUMConnectivityCellular: NSObject { - internal let root: DDRUMLongTaskEvent + @objc public var service: String { + root.swiftModel.service + } - internal init(root: DDRUMLongTaskEvent) { - self.root = root + @objc public var session: DDTelemetryErrorEventSession? { + root.swiftModel.session != nil ? DDTelemetryErrorEventSession(root: root) : nil } - @objc public var carrierName: String? { - root.swiftModel.connectivity!.cellular!.carrierName + @objc public var status: String { + root.swiftModel.status } - @objc public var technology: String? { - root.swiftModel.connectivity!.cellular!.technology + @objc public var version: String { + root.swiftModel.version + } + + @objc public var view: DDTelemetryErrorEventView? { + root.swiftModel.view != nil ? DDTelemetryErrorEventView(root: root) : nil } } @objc -public enum DDRUMLongTaskEventRUMConnectivityInterfaces: Int { - internal init(swift: RUMConnectivity.Interfaces) { - switch swift { - case .bluetooth: self = .bluetooth - case .cellular: self = .cellular - case .ethernet: self = .ethernet - case .wifi: self = .wifi - case .wimax: self = .wimax - case .mixed: self = .mixed - case .other: self = .other - case .unknown: self = .unknown - case .none: self = .none - } - } +public class DDTelemetryErrorEventDD: NSObject { + internal let root: DDTelemetryErrorEvent - internal var toSwift: RUMConnectivity.Interfaces { - switch self { - case .bluetooth: return .bluetooth - case .cellular: return .cellular - case .ethernet: return .ethernet - case .wifi: return .wifi - case .wimax: return .wimax - case .mixed: return .mixed - case .other: return .other - case .unknown: return .unknown - case .none: return .none - } + internal init(root: DDTelemetryErrorEvent) { + self.root = root } - case bluetooth - case cellular - case ethernet - case wifi - case wimax - case mixed - case other - case unknown - case none + @objc public var eventType: String { + root.swiftModel.dd.eventType + } } @objc -public enum DDRUMLongTaskEventRUMConnectivityStatus: Int { - internal init(swift: RUMConnectivity.Status) { - switch swift { - case .connected: self = .connected - case .notConnected: self = .notConnected - case .maybe: self = .maybe - } - } +public class DDTelemetryErrorEventAction: NSObject { + internal let root: DDTelemetryErrorEvent - internal var toSwift: RUMConnectivity.Status { - switch self { - case .connected: return .connected - case .notConnected: return .notConnected - case .maybe: return .maybe - } + internal init(root: DDTelemetryErrorEvent) { + self.root = root } - case connected - case notConnected - case maybe + @objc public var id: String { + root.swiftModel.action!.id + } } @objc -public class DDRUMLongTaskEventRUMEventAttributes: NSObject { - internal let root: DDRUMLongTaskEvent +public class DDTelemetryErrorEventApplication: NSObject { + internal let root: DDTelemetryErrorEvent - internal init(root: DDRUMLongTaskEvent) { + internal init(root: DDTelemetryErrorEvent) { self.root = root } - @objc public var contextInfo: [String: Any] { - root.swiftModel.context!.contextInfo.castToObjectiveC() + @objc public var id: String { + root.swiftModel.application!.id } } @objc -public class DDRUMLongTaskEventLongTask: NSObject { - internal let root: DDRUMLongTaskEvent +public class DDTelemetryErrorEventError: NSObject { + internal let root: DDTelemetryErrorEvent - internal init(root: DDRUMLongTaskEvent) { + internal init(root: DDTelemetryErrorEvent) { self.root = root } - @objc public var duration: NSNumber { - root.swiftModel.longTask.duration as NSNumber - } - - @objc public var id: String? { - root.swiftModel.longTask.id + @objc public var kind: String? { + root.swiftModel.error!.kind } - @objc public var isFrozenFrame: NSNumber? { - root.swiftModel.longTask.isFrozenFrame as NSNumber? + @objc public var stack: String? { + root.swiftModel.error!.stack } } @objc -public class DDRUMLongTaskEventSession: NSObject { - internal let root: DDRUMLongTaskEvent +public class DDTelemetryErrorEventSession: NSObject { + internal let root: DDTelemetryErrorEvent - internal init(root: DDRUMLongTaskEvent) { + internal init(root: DDTelemetryErrorEvent) { self.root = root } - @objc public var hasReplay: NSNumber? { - root.swiftModel.session.hasReplay as NSNumber? + @objc public var id: String { + root.swiftModel.session!.id } +} - @objc public var id: String { - root.swiftModel.session.id +@objc +public class DDTelemetryErrorEventView: NSObject { + internal let root: DDTelemetryErrorEvent + + internal init(root: DDTelemetryErrorEvent) { + self.root = root } - @objc public var type: DDRUMLongTaskEventSessionSessionType { - .init(swift: root.swiftModel.session.type) + @objc public var id: String { + root.swiftModel.view!.id } } @objc -public enum DDRUMLongTaskEventSessionSessionType: Int { - internal init(swift: RUMLongTaskEvent.Session.SessionType) { - switch swift { - case .user: self = .user - case .synthetics: self = .synthetics - case .ciTest: self = .ciTest - } +public class DDTelemetryDebugEvent: NSObject { + internal var swiftModel: TelemetryDebugEvent + internal var root: DDTelemetryDebugEvent { self } + + internal init(swiftModel: TelemetryDebugEvent) { + self.swiftModel = swiftModel } - internal var toSwift: RUMLongTaskEvent.Session.SessionType { - switch self { - case .user: return .user - case .synthetics: return .synthetics - case .ciTest: return .ciTest - } + @objc public var dd: DDTelemetryDebugEventDD { + DDTelemetryDebugEventDD(root: root) } - case user - case synthetics - case ciTest -} + @objc public var action: DDTelemetryDebugEventAction? { + root.swiftModel.action != nil ? DDTelemetryDebugEventAction(root: root) : nil + } -@objc -public enum DDRUMLongTaskEventSource: Int { - internal init(swift: RUMLongTaskEvent.Source?) { - switch swift { - case nil: self = .none - case .android?: self = .android - case .ios?: self = .ios - case .browser?: self = .browser - case .flutter?: self = .flutter - case .reactNative?: self = .reactNative - } + @objc public var application: DDTelemetryDebugEventApplication? { + root.swiftModel.application != nil ? DDTelemetryDebugEventApplication(root: root) : nil } - internal var toSwift: RUMLongTaskEvent.Source? { - switch self { - case .none: return nil - case .android: return .android - case .ios: return .ios - case .browser: return .browser - case .flutter: return .flutter - case .reactNative: return .reactNative - } + @objc public var date: NSNumber { + root.swiftModel.date as NSNumber } - case none - case android - case ios - case browser - case flutter - case reactNative -} + @objc public var message: String { + root.swiftModel.message + } -@objc -public class DDRUMLongTaskEventSynthetics: NSObject { - internal let root: DDRUMLongTaskEvent + @objc public var service: String { + root.swiftModel.service + } - internal init(root: DDRUMLongTaskEvent) { - self.root = root + @objc public var session: DDTelemetryDebugEventSession? { + root.swiftModel.session != nil ? DDTelemetryDebugEventSession(root: root) : nil } - @objc public var injected: NSNumber? { - root.swiftModel.synthetics!.injected as NSNumber? + @objc public var status: String { + root.swiftModel.status } - @objc public var resultId: String { - root.swiftModel.synthetics!.resultId + @objc public var version: String { + root.swiftModel.version } - @objc public var testId: String { - root.swiftModel.synthetics!.testId + @objc public var view: DDTelemetryDebugEventView? { + root.swiftModel.view != nil ? DDTelemetryDebugEventView(root: root) : nil } } @objc -public class DDRUMLongTaskEventRUMUser: NSObject { - internal let root: DDRUMLongTaskEvent +public class DDTelemetryDebugEventDD: NSObject { + internal let root: DDTelemetryDebugEvent - internal init(root: DDRUMLongTaskEvent) { + internal init(root: DDTelemetryDebugEvent) { self.root = root } - @objc public var email: String? { - root.swiftModel.usr!.email + @objc public var eventType: String { + root.swiftModel.dd.eventType } +} - @objc public var id: String? { - root.swiftModel.usr!.id - } +@objc +public class DDTelemetryDebugEventAction: NSObject { + internal let root: DDTelemetryDebugEvent - @objc public var name: String? { - root.swiftModel.usr!.name + internal init(root: DDTelemetryDebugEvent) { + self.root = root } - @objc public var usrInfo: [String: Any] { - root.swiftModel.usr!.usrInfo.castToObjectiveC() + @objc public var id: String { + root.swiftModel.action!.id } } @objc -public class DDRUMLongTaskEventView: NSObject { - internal let root: DDRUMLongTaskEvent +public class DDTelemetryDebugEventApplication: NSObject { + internal let root: DDTelemetryDebugEvent - internal init(root: DDRUMLongTaskEvent) { + internal init(root: DDTelemetryDebugEvent) { self.root = root } @objc public var id: String { - root.swiftModel.view.id + root.swiftModel.application!.id } +} - @objc public var name: String? { - set { root.swiftModel.view.name = newValue } - get { root.swiftModel.view.name } +@objc +public class DDTelemetryDebugEventSession: NSObject { + internal let root: DDTelemetryDebugEvent + + internal init(root: DDTelemetryDebugEvent) { + self.root = root } - @objc public var referrer: String? { - set { root.swiftModel.view.referrer = newValue } - get { root.swiftModel.view.referrer } + @objc public var id: String { + root.swiftModel.session!.id } +} - @objc public var url: String { - set { root.swiftModel.view.url = newValue } - get { root.swiftModel.view.url } +@objc +public class DDTelemetryDebugEventView: NSObject { + internal let root: DDTelemetryDebugEvent + + internal init(root: DDTelemetryDebugEvent) { + self.root = root + } + + @objc public var id: String { + root.swiftModel.view!.id } } // swiftlint:enable force_unwrapping -// Generated from https://github.com/DataDog/rum-events-format/tree/114c173caac5ea15446a157b666acbab05431361 +// Generated from https://github.com/DataDog/rum-events-format/tree/c8a844abb59cb376be2fcdc9deda74dc328af660 diff --git a/Sources/DatadogObjc/RUMMonitor+objc.swift b/Sources/DatadogObjc/RUMMonitor+objc.swift index bf9931f2ee..6692c0367d 100644 --- a/Sources/DatadogObjc/RUMMonitor+objc.swift +++ b/Sources/DatadogObjc/RUMMonitor+objc.swift @@ -15,7 +15,8 @@ import enum Datadog.RUMMethod import struct Datadog.RUMView import protocol Datadog.UIKitRUMViewsPredicate import struct Datadog.RUMAction -import protocol Datadog.UIKitRUMUserActionsPredicate +import protocol Datadog.UITouchRUMUserActionsPredicate +import protocol Datadog.UIPressRUMUserActionsPredicate internal struct UIKitRUMViewsPredicateBridge: UIKitRUMViewsPredicate { let objcPredicate: DDUIKitRUMViewsPredicate @@ -53,11 +54,29 @@ public protocol DDUIKitRUMViewsPredicate: AnyObject { func rumView(for viewController: UIViewController) -> DDRUMView? } -internal struct UIKitRUMUserActionsPredicateBridge: UIKitRUMUserActionsPredicate { - let objcPredicate: DDUIKitRUMUserActionsPredicate? +internal struct UIKitRUMUserActionsPredicateBridge: UITouchRUMUserActionsPredicate & UIPressRUMUserActionsPredicate { + let objcPredicate: AnyObject? + + init(objcPredicate: DDUITouchRUMUserActionsPredicate) { + self.objcPredicate = objcPredicate + } + + init(objcPredicate: DDUIPressRUMUserActionsPredicate) { + self.objcPredicate = objcPredicate + } func rumAction(targetView: UIView) -> RUMAction? { - return objcPredicate?.rumAction(targetView: targetView)?.swiftAction + guard let objcPredicate = objcPredicate as? DDUITouchRUMUserActionsPredicate else { + return nil + } + return objcPredicate.rumAction(targetView: targetView)?.swiftAction + } + + func rumAction(press type: UIPress.PressType, targetView: UIView) -> RUMAction? { + guard let objcPredicate = objcPredicate as? DDUIPressRUMUserActionsPredicate else { + return nil + } + return objcPredicate.rumAction(press: type, targetView: targetView)?.swiftAction } } @@ -81,14 +100,32 @@ public class DDRUMAction: NSObject { } } +#if os(tvOS) +@objc +public protocol DDUIKitRUMUserActionsPredicate: DDUIPressRUMUserActionsPredicate {} +#else @objc -public protocol DDUIKitRUMUserActionsPredicate: AnyObject { +public protocol DDUIKitRUMUserActionsPredicate: DDUITouchRUMUserActionsPredicate {} +#endif + +@objc +public protocol DDUITouchRUMUserActionsPredicate: AnyObject { /// The predicate deciding if the RUM Action should be recorded. /// - Parameter targetView: an instance of the `UIView` which received the action. /// - Returns: RUM Action if it should be recorded, `nil` otherwise. func rumAction(targetView: UIView) -> DDRUMAction? } +@objc +public protocol DDUIPressRUMUserActionsPredicate: AnyObject { + /// The predicate deciding if the RUM Action should be recorded. + /// - Parameters: + /// - type: the `UIPress.PressType` which received the action. + /// - targetView: an instance of the `UIView` which received the action. + /// - Returns: RUM Action if it should be recorded, `nil` otherwise. + func rumAction(press type: UIPress.PressType, targetView: UIView) -> DDRUMAction? +} + @objc public enum DDRUMErrorSource: Int { /// Error originated in the source code. diff --git a/Sources/_Datadog_Private/ObjcAppLaunchHandler.m b/Sources/_Datadog_Private/ObjcAppLaunchHandler.m index cc2a8400e4..97e16351d4 100644 --- a/Sources/_Datadog_Private/ObjcAppLaunchHandler.m +++ b/Sources/_Datadog_Private/ObjcAppLaunchHandler.m @@ -18,6 +18,11 @@ static NSTimeInterval FrameworkLoadTime = 0.0; // The time interval between the application starts and it's responsive and accepts touch events. static NSTimeInterval TimeToApplicationDidBecomeActive = 0.0; +// System sets environment variable ActivePrewarm to 1 when app is pre-warmed. +static BOOL isActivePrewarm = NO; +// A very long application launch time is most-likely the result of a pre-warmed process. +// We consider 30s as a threshold for pre-warm detection. +static NSTimeInterval ValidAppLaunchTimeThreshold = 30; NS_INLINE NSTimeInterval QueryProcessStartTimeWithFallback(NSTimeInterval fallbackTime) { NSTimeInterval processStartTime; @@ -59,6 +64,8 @@ + (void)load { // This is called at the `_Datadog_Private` load time, keep the work minimal FrameworkLoadTime = CFAbsoluteTimeGetCurrent(); + isActivePrewarm = [NSProcessInfo.processInfo.environment[@"ActivePrewarm"] isEqualToString:@"1"]; + NSNotificationCenter * __weak center = NSNotificationCenter.defaultCenter; id __block token = [center addObserverForName:UIApplicationDidBecomeActiveNotification @@ -81,7 +88,13 @@ + (void)load { CFTimeInterval __dd_private_AppLaunchTime() { pthread_rwlock_rdlock(&rwLock); CFTimeInterval time = TimeToApplicationDidBecomeActive; - if (time == 0) time = ComputeProcessTimeFromStart(); pthread_rwlock_unlock(&rwLock); + if (time == 0) time = ComputeProcessTimeFromStart(); return time; } + +BOOL __dd_private_isActivePrewarm() { + if (isActivePrewarm) return isActivePrewarm; + CFTimeInterval time = __dd_private_AppLaunchTime(); + return time > ValidAppLaunchTimeThreshold; +} diff --git a/Sources/_Datadog_Private/include/ObjcAppLaunchHandler.h b/Sources/_Datadog_Private/include/ObjcAppLaunchHandler.h index 430455a0b3..1233fead24 100644 --- a/Sources/_Datadog_Private/include/ObjcAppLaunchHandler.h +++ b/Sources/_Datadog_Private/include/ObjcAppLaunchHandler.h @@ -4,7 +4,7 @@ * Copyright 2019-2020 Datadog, Inc. */ -#import +#import /// Returns the time interval between startup of the application process and the /// `UIApplicationDidBecomeActiveNotification`. @@ -12,3 +12,8 @@ /// If the `UIApplicationDidBecomeActiveNotification` has not been reached yet, /// it returns time interval between startup of the application process and now. CFTimeInterval __dd_private_AppLaunchTime(void); + +/// Returns `true` when the application is pre-warmed. +/// +/// System sets environment variable `ActivePrewarm` to 1 when app is pre-warmed. +BOOL __dd_private_isActivePrewarm(void); diff --git a/Tests/DatadogBenchmarkTests/DataStorage/TracingStorageBenchmarkTests.swift b/Tests/DatadogBenchmarkTests/DataStorage/TracingStorageBenchmarkTests.swift index 6192da8a1f..2c675a103c 100644 --- a/Tests/DatadogBenchmarkTests/DataStorage/TracingStorageBenchmarkTests.swift +++ b/Tests/DatadogBenchmarkTests/DataStorage/TracingStorageBenchmarkTests.swift @@ -88,6 +88,7 @@ class TracingStorageBenchmarkTests: XCTestCase { duration: Double.random(in: 0.0..<1.0), isError: false, source: "ios", + origin: nil, tracerVersion: "0.0.0", applicationVersion: "0.0.0", networkConnectionInfo: NetworkConnectionInfo( diff --git a/Tests/DatadogCrashReportingTests/PLCrashReporterIntegration/DDCrashReportBuilderTests.swift b/Tests/DatadogCrashReportingTests/PLCrashReporterIntegration/DDCrashReportBuilderTests.swift index e98adcffa8..20495f77d5 100644 --- a/Tests/DatadogCrashReportingTests/PLCrashReporterIntegration/DDCrashReportBuilderTests.swift +++ b/Tests/DatadogCrashReportingTests/PLCrashReporterIntegration/DDCrashReportBuilderTests.swift @@ -36,7 +36,7 @@ class DDCrashReportBuilderTests: XCTestCase { ) XCTAssertTrue( ddCrashReport.stack.contains("XCTest"), - "`DDCrashReport's` stack should include at least one frame from `DatadogCrashReportingTests` image" + "`DDCrashReport's` stack should include at least one frame from `XCTest` image" ) XCTAssertTrue( ddCrashReport.binaryImages.contains(where: { $0.libraryName == "DatadogCrashReportingTests" }), diff --git a/Tests/DatadogCrashReportingTests/PLCrashReporterIntegration/DDCrashReportExporterTests.swift b/Tests/DatadogCrashReportingTests/PLCrashReporterIntegration/DDCrashReportExporterTests.swift index 31ac798ab3..000c3d4e94 100644 --- a/Tests/DatadogCrashReportingTests/PLCrashReporterIntegration/DDCrashReportExporterTests.swift +++ b/Tests/DatadogCrashReportingTests/PLCrashReporterIntegration/DDCrashReportExporterTests.swift @@ -204,6 +204,26 @@ class DDCrashReportExporterTests: XCTestCase { XCTAssertEqual(actualStack, expectedStack) } + func testWhenLastFrameInTheStackHasNoLibraryBaseAddress_itIsFilteredOut() { + let stackFrames: [StackFrame] = [ + .init(number: 0, libraryName: "Foo", libraryBaseAddress: 100, instructionPointer: 102), + .init(number: 1, libraryName: "Foo", libraryBaseAddress: 100, instructionPointer: 112), + .init(number: 2, libraryName: "Bizz", libraryBaseAddress: 400, instructionPointer: 432), + .init(number: 3, libraryName: "Bizz", libraryBaseAddress: nil, instructionPointer: 432), + ] + + crashReport.exceptionInfo = .init(name: .mockAny(), reason: .mockAny(), stackFrames: stackFrames) + + let actualStack = exporter.export(crashReport).stack + let expectedStack = """ + 0 Foo 0x0000000000000066 0x64 + 2 + 1 Foo 0x0000000000000070 0x64 + 12 + 2 Bizz 0x00000000000001b0 0x190 + 32 + """ + + XCTAssertEqual(actualStack, expectedStack) + } + // MARK: - Formatting threads func testExportingThreads() { @@ -251,6 +271,29 @@ class DDCrashReportExporterTests: XCTestCase { XCTAssertEqual(exportedThreads[2].stack, expectedOtherThreadStack) } + func testWhenLastFrameInThreadStackHasNoLibraryBaseAddress_itIsNotFilteredOut() { + let crashedThreadStackFrames: [StackFrame] = [ + .init(number: 0, libraryName: "Foo", libraryBaseAddress: 100, instructionPointer: 102), + .init(number: 1, libraryName: "Foo", libraryBaseAddress: 100, instructionPointer: 112), + .init(number: 2, libraryName: "Bizz", libraryBaseAddress: 400, instructionPointer: 432), + .init(number: 3, libraryName: nil, libraryBaseAddress: nil, instructionPointer: 432), + ] + + crashReport.threads = [ + .init(threadNumber: 0, crashed: true, stackFrames: crashedThreadStackFrames), + ] + + let actualStack = exporter.export(crashReport).threads[0].stack + let expectedStack = """ + 0 Foo 0x0000000000000066 0x64 + 2 + 1 Foo 0x0000000000000070 0x64 + 12 + 2 Bizz 0x00000000000001b0 0x190 + 32 + 3 ??? 0x00000000000001b0 0x0 + 0 + """ + + XCTAssertEqual(actualStack, expectedStack) + } + // MARK: - Formatting binary images func testExportingBinaryImages() { diff --git a/Tests/DatadogIntegrationTests/Scenarios/CrashReporting/CrashReportingWithLoggingScenarioTests.swift b/Tests/DatadogIntegrationTests/Scenarios/CrashReporting/CrashReportingWithLoggingScenarioTests.swift index 2115258e18..ba91d8b0f7 100644 --- a/Tests/DatadogIntegrationTests/Scenarios/CrashReporting/CrashReportingWithLoggingScenarioTests.swift +++ b/Tests/DatadogIntegrationTests/Scenarios/CrashReporting/CrashReportingWithLoggingScenarioTests.swift @@ -9,7 +9,7 @@ import XCTest private extension ExampleApplication { /// Tapping this button will crash the app. func tapCallFatalError() { - buttons["Call fatalError()"].tap() + buttons["Call fatalError()"].safeTap() } } diff --git a/Tests/DatadogIntegrationTests/Scenarios/Logging/LoggingCommonAsserts.swift b/Tests/DatadogIntegrationTests/Scenarios/Logging/LoggingCommonAsserts.swift index 2d83074d68..57203523cb 100644 --- a/Tests/DatadogIntegrationTests/Scenarios/Logging/LoggingCommonAsserts.swift +++ b/Tests/DatadogIntegrationTests/Scenarios/Logging/LoggingCommonAsserts.swift @@ -36,10 +36,10 @@ extension LoggingCommonAsserts { let expectedHeadersRegexes = [ #"^Content-Type: application/json$"#, - #"^User-Agent: Example/1.0 CFNetwork \([a-zA-Z ]+; iOS/[0-9.]+\)$"#, // e.g. "User-Agent: Example/1.0 CFNetwork (iPhone; iOS/14.5)" + #"^User-Agent: .*/\d+[.\d]* CFNetwork \([a-zA-Z ]+; iOS/[0-9.]+\)$"#, // e.g. "User-Agent: Example/1.0 CFNetwork (iPhone; iOS/14.5)" #"^DD-API-KEY: ui-tests-client-token$"#, #"^DD-EVP-ORIGIN: ios$"#, - #"^DD-EVP-ORIGIN-VERSION: [0-9].[0-9].[0-9]([-a-z0-9])*$"#, // e.g. "DD-EVP-ORIGIN-VERSION: 1.7.0-beta2" + #"^DD-EVP-ORIGIN-VERSION: [0-9]+.[0-9]+.[0-9]+([-a-z0-9])*$"#, // e.g. "DD-EVP-ORIGIN-VERSION: 1.7.0-beta2" #"^DD-REQUEST-ID: [0-9A-F]{8}(-[0-9A-F]{4}){3}-[0-9A-F]{12}$"# // e.g. "DD-REQUEST-ID: 524A2616-D2AA-4FE5-BBD9-898D173BE658" ] expectedHeadersRegexes.forEach { expectedHeaderRegex in diff --git a/Tests/DatadogIntegrationTests/Scenarios/RUM/RUMCommonAsserts.swift b/Tests/DatadogIntegrationTests/Scenarios/RUM/RUMCommonAsserts.swift index 96451dd125..7c778c8fcd 100644 --- a/Tests/DatadogIntegrationTests/Scenarios/RUM/RUMCommonAsserts.swift +++ b/Tests/DatadogIntegrationTests/Scenarios/RUM/RUMCommonAsserts.swift @@ -22,7 +22,7 @@ extension RUMCommonAsserts { XCTAssertEqual(request.httpMethod, "POST") // Example path here: `/36882784-420B-494F-910D-CBAC5897A309?ddsource=ios&&ddtags=service:ui-tests-service-name,version:1.0,sdk_version:1.3.0-beta3,env:integration` - let pathRegex = #"^(.*)(\?ddsource=ios&ddtags=service:ui-tests-service-name,version:1.0,sdk_version:)([0-9].[0-9].[0-9]([-a-z0-9])*)(,env:integration)$"# + let pathRegex = #"^(.*)(\?ddsource=ios&ddtags=service:ui-tests-service-name,version:1.0,sdk_version:)([0-9]+.[0-9]+.[0-9]+([-a-z0-9])*)(,env:integration)$"# XCTAssertTrue( request.path.matches(regex: pathRegex), """ @@ -36,10 +36,10 @@ extension RUMCommonAsserts { let expectedHeadersRegexes = [ #"^Content-Type: text/plain;charset=UTF-8$"#, - #"^User-Agent: Example/1.0 CFNetwork \([a-zA-Z ]+; iOS/[0-9.]+\)$"#, // e.g. "User-Agent: Example/1.0 CFNetwork (iPhone; iOS/14.5)" + #"^User-Agent: .*/\d+[.\d]* CFNetwork \([a-zA-Z ]+; iOS/[0-9.]+\)$"#, // e.g. "User-Agent: Example/1.0 CFNetwork (iPhone; iOS/14.5)" #"^DD-API-KEY: ui-tests-client-token$"#, #"^DD-EVP-ORIGIN: ios$"#, - #"^DD-EVP-ORIGIN-VERSION: [0-9].[0-9].[0-9]([-a-z0-9])*$"#, // e.g. "DD-EVP-ORIGIN-VERSION: 1.7.0-beta2" + #"^DD-EVP-ORIGIN-VERSION: [0-9]+.[0-9]+.[0-9]+([-a-z0-9])*$"#, // e.g. "DD-EVP-ORIGIN-VERSION: 1.7.0-beta2" #"^DD-REQUEST-ID: [0-9A-F]{8}(-[0-9A-F]{4}){3}-[0-9A-F]{12}$"# // e.g. "DD-REQUEST-ID: 524A2616-D2AA-4FE5-BBD9-898D173BE658" ] expectedHeadersRegexes.forEach { expectedHeaderRegex in diff --git a/Tests/DatadogIntegrationTests/Scenarios/Tracing/TracingCommonAsserts.swift b/Tests/DatadogIntegrationTests/Scenarios/Tracing/TracingCommonAsserts.swift index 7a527f6483..875531143f 100644 --- a/Tests/DatadogIntegrationTests/Scenarios/Tracing/TracingCommonAsserts.swift +++ b/Tests/DatadogIntegrationTests/Scenarios/Tracing/TracingCommonAsserts.swift @@ -46,10 +46,10 @@ extension TracingCommonAsserts { let expectedHeadersRegexes = [ #"^Content-Type: text/plain;charset=UTF-8$"#, - #"^User-Agent: Example/1.0 CFNetwork \([a-zA-Z ]+; iOS/[0-9.]+\)$"#, // e.g. "User-Agent: Example/1.0 CFNetwork (iPhone; iOS/14.5)" + #"^User-Agent: .*/\d+[.\d]* CFNetwork \([a-zA-Z ]+; iOS/[0-9.]+\)$"#, // e.g. "User-Agent: Example/1.0 CFNetwork (iPhone; iOS/14.5)" #"^DD-API-KEY: ui-tests-client-token$"#, #"^DD-EVP-ORIGIN: ios$"#, - #"^DD-EVP-ORIGIN-VERSION: [0-9].[0-9].[0-9]([-a-z0-9])*$"#, // e.g. "DD-EVP-ORIGIN-VERSION: 1.7.0-beta2" + #"^DD-EVP-ORIGIN-VERSION: [0-9]+.[0-9]+.[0-9]+([-a-z0-9])*$"#, // e.g. "DD-EVP-ORIGIN-VERSION: 1.7.0-beta2" #"^DD-REQUEST-ID: [0-9A-F]{8}(-[0-9A-F]{4}){3}-[0-9A-F]{12}$"# // e.g. "DD-REQUEST-ID: 524A2616-D2AA-4FE5-BBD9-898D173BE658" ] expectedHeadersRegexes.forEach { expectedHeaderRegex in diff --git a/Tests/DatadogIntegrationTests/Scenarios/TrackingConsent/TrackingConsentScenarioTests.swift b/Tests/DatadogIntegrationTests/Scenarios/TrackingConsent/TrackingConsentScenarioTests.swift index bf2099edde..741d332fbe 100644 --- a/Tests/DatadogIntegrationTests/Scenarios/TrackingConsent/TrackingConsentScenarioTests.swift +++ b/Tests/DatadogIntegrationTests/Scenarios/TrackingConsent/TrackingConsentScenarioTests.swift @@ -44,7 +44,7 @@ private class TSPictureScreen: XCUIApplication { private class TSConsentSettingsScreen: XCUIApplication { func selectConsent(value: String) { - buttons[value].tap() + buttons[value].safeTap() } func tapClose() -> TSHomeScreen { diff --git a/Tests/DatadogTests/Datadog/Core/System/CarrierInfoProviderTests.swift b/Tests/DatadogTests/Datadog/Core/System/CarrierInfoProviderTests.swift index e738230dc9..353c2f58c5 100644 --- a/Tests/DatadogTests/Datadog/Core/System/CarrierInfoProviderTests.swift +++ b/Tests/DatadogTests/Datadog/Core/System/CarrierInfoProviderTests.swift @@ -4,8 +4,11 @@ * Copyright 2019-2020 Datadog, Inc. */ +#if canImport(CoreTelephony) + import XCTest import CoreTelephony + @testable import Datadog class CarrierInfoProviderTests: XCTestCase { @@ -162,3 +165,5 @@ class CarrierInfoProviderTests: XCTestCase { XCTAssertEqual(initializeFrom(coreTelephonyConstant: "invalid"), .unknown) } } + +#endif diff --git a/Tests/DatadogTests/Datadog/Core/System/LaunchTimeProviderTests.swift b/Tests/DatadogTests/Datadog/Core/System/LaunchTimeProviderTests.swift index 9a108040fa..feeb52fae6 100644 --- a/Tests/DatadogTests/Datadog/Core/System/LaunchTimeProviderTests.swift +++ b/Tests/DatadogTests/Datadog/Core/System/LaunchTimeProviderTests.swift @@ -7,7 +7,15 @@ import XCTest @testable import Datadog +// TODO: RUMM-2034 Remove this flag once we have a host application for tests +#if !os(tvOS) + class LaunchTimeProviderTests: XCTestCase { + override func tearDown() { + super.tearDown() + setenv("ActivePrewarm", "", 1) + } + func testGivenStartedApplication_whenRequestingLaunchTimeAtAnyTime_itReturnsTheSameValue() { // Given let provider = LaunchTimeProvider() @@ -35,4 +43,29 @@ class LaunchTimeProviderTests: XCTestCase { ) // swiftlint:enable opening_brace } + + func testIsActivePrewarm_returnsTrue() { + // Given + let provider = LaunchTimeProvider() + + // When + setenv("ActivePrewarm", "1", 1) + NSClassFromString("AppLaunchHandler")?.load() + + // Then + XCTAssertTrue(provider.isActivePrewarm) + } + + func testIsActivePrewarm_returnsFalse() { + // Given + let provider = LaunchTimeProvider() + + // When + NSClassFromString("AppLaunchHandler")?.load() + + // Then + XCTAssertFalse(provider.isActivePrewarm) + } } + +#endif diff --git a/Tests/DatadogTests/Datadog/Core/System/MobileDeviceTests.swift b/Tests/DatadogTests/Datadog/Core/System/MobileDeviceTests.swift index 6e7e91d3b2..1c96fa5001 100644 --- a/Tests/DatadogTests/Datadog/Core/System/MobileDeviceTests.swift +++ b/Tests/DatadogTests/Datadog/Core/System/MobileDeviceTests.swift @@ -24,6 +24,7 @@ class MobileDeviceTests: XCTestCase { XCTAssertEqual(mobileDevice.osVersion, uiDevice.systemVersion) } + #if os(iOS) func testWhenRunningOnMobile_itUsesUIDeviceBatteryState() { func mobileDevice(withBatteryState bateryState: UIDevice.BatteryState) -> MobileDevice { return MobileDevice( @@ -85,4 +86,5 @@ class MobileDeviceTests: XCTestCase { mobileDevice.resetBatteryStatusMonitoring() XCTAssertFalse(uiDevice.isBatteryMonitoringEnabled) } + #endif } diff --git a/Tests/DatadogTests/Datadog/Core/System/NetworkConnectionInfoProviderTests.swift b/Tests/DatadogTests/Datadog/Core/System/NetworkConnectionInfoProviderTests.swift index 9037b5c955..c8c0aae6a9 100644 --- a/Tests/DatadogTests/Datadog/Core/System/NetworkConnectionInfoProviderTests.swift +++ b/Tests/DatadogTests/Datadog/Core/System/NetworkConnectionInfoProviderTests.swift @@ -26,7 +26,7 @@ class NetworkConnectionInfoProviderTests: XCTestCase { // MARK: - iOS 12+ func testNWPathNetworkConnectionInfoProviderGivesValue() { - if #available(iOS 12.0, *) { + if #available(iOS 12.0, tvOS 12, *) { let provider = NetworkConnectionInfoProvider( wrappedProvider: NWPathNetworkConnectionInfoProvider() ) @@ -42,7 +42,7 @@ class NetworkConnectionInfoProviderTests: XCTestCase { } func testNWPathNetworkConnectionInfoProviderCanBeSafelyAccessedFromConcurrentThreads() { - if #available(iOS 12.0, *) { + if #available(iOS 12.0, tvOS 12, *) { let provider = NetworkConnectionInfoProvider( wrappedProvider: NWPathNetworkConnectionInfoProvider() ) @@ -54,7 +54,7 @@ class NetworkConnectionInfoProviderTests: XCTestCase { } func testNWPathMonitorHandling() { - if #available(iOS 12.0, *) { + if #available(iOS 12.0, tvOS 12, *) { weak var nwPathMonitorWeakReference: NWPathMonitor? autoreleasepool { @@ -102,7 +102,7 @@ class NetworkConnectionInfoConversionTests: XCTestCase { typealias Interface = NetworkConnectionInfo.Interface func testNWPathStatus() { - if #available(iOS 12.0, *) { + if #available(iOS 12.0, tvOS 12, *) { XCTAssertEqual(Reachability(from: .satisfied), .yes) XCTAssertEqual(Reachability(from: .unsatisfied), .no) XCTAssertEqual(Reachability(from: .requiresConnection), .maybe) @@ -110,7 +110,7 @@ class NetworkConnectionInfoConversionTests: XCTestCase { } func testNWInterface() { - if #available(iOS 12.0, *) { + if #available(iOS 12.0, tvOS 12, *) { XCTAssertEqual(Array(fromInterfaceTypes: []), []) XCTAssertEqual(Array(fromInterfaceTypes: [.wifi]), [.wifi]) XCTAssertEqual(Array(fromInterfaceTypes: [.wiredEthernet]), [.wiredEthernet]) diff --git a/Tests/DatadogTests/Datadog/Core/Upload/RequestBuilderTests.swift b/Tests/DatadogTests/Datadog/Core/Upload/RequestBuilderTests.swift index c721a5fe7b..59d5929f76 100644 --- a/Tests/DatadogTests/Datadog/Core/Upload/RequestBuilderTests.swift +++ b/Tests/DatadogTests/Datadog/Core/Upload/RequestBuilderTests.swift @@ -64,6 +64,26 @@ class RequestBuilderTests: XCTestCase { XCTAssertEqual(request.allHTTPHeaderFields?["User-Agent"], "FoobarApp/1.2.3 CFNetwork (iPhone; iOS/13.3.1)") } + func testBuildingRequestWithComplexUserAgentHeader() { + let builder = RequestBuilder( + url: .mockRandom(), + queryItems: .mockRandom(), + headers: [ + .userAgentHeader( + appName: "Foobar 電話 𝛼β", + appVersion: "1.2.3", + device: .mockWith( + model: "iPhone", + osName: "iOS", + osVersion: "13.3.1" + ) + ) + ] + ) + let request = builder.uploadRequest(with: .mockRandom()) + XCTAssertEqual(request.allHTTPHeaderFields?["User-Agent"], "Foobar/1.2.3 CFNetwork (iPhone; iOS/13.3.1)") + } + func testBuildingRequestWithDDAPIKeyHeader() { let randomClientToken: String = .mockRandom() let builder = RequestBuilder(url: .mockRandom(), queryItems: .mockRandom(), headers: [.ddAPIKeyHeader(clientToken: randomClientToken)]) diff --git a/Tests/DatadogTests/Datadog/CrashReporting/CrashContext/CrashContextProviderTests.swift b/Tests/DatadogTests/Datadog/CrashReporting/CrashContext/CrashContextProviderTests.swift index 1baa1590d2..efc20ca69b 100644 --- a/Tests/DatadogTests/Datadog/CrashReporting/CrashContext/CrashContextProviderTests.swift +++ b/Tests/DatadogTests/Datadog/CrashReporting/CrashContext/CrashContextProviderTests.swift @@ -5,8 +5,11 @@ */ import XCTest -@testable import Datadog +#if canImport(CoreTelephony) import CoreTelephony +#endif + +@testable import Datadog /// This suite tests if `CrashContextProvider` gets updated by different SDK components, each updating /// separate part of the `CrashContext` information. @@ -194,6 +197,7 @@ class CrashContextProviderTests: XCTestCase { } // MARK: - `CarrierInfo` Integration + #if !os(tvOS) private let ctTelephonyNetworkInfoMock = CTTelephonyNetworkInfoMock( serviceCurrentRadioAccessTechnology: ["000001": CTRadioAccessTechnologyLTE], @@ -278,6 +282,7 @@ class CrashContextProviderTests: XCTestCase { XCTAssertNotEqual(carrierInfoInInitialContext, carrierInfoInUpdatedContext) } } + #endif // MARK: - `AppStateListener` Integration diff --git a/Tests/DatadogTests/Datadog/FeaturesIntegration/CITestIntegrationTests.swift b/Tests/DatadogTests/Datadog/FeaturesIntegration/CITestIntegrationTests.swift new file mode 100644 index 0000000000..3e2bd5f072 --- /dev/null +++ b/Tests/DatadogTests/Datadog/FeaturesIntegration/CITestIntegrationTests.swift @@ -0,0 +1,14 @@ +/* + * 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-2020 Datadog, Inc. + */ + +@testable import Datadog +import XCTest + +class CITestIntegrationTests: XCTestCase { + func testByDefaultCITestIntegrationIsNotConfigured() throws { + XCTAssertNil(CITestIntegration.active) + } +} diff --git a/Tests/DatadogTests/Datadog/InternalMonitoring/InternalMonitoringFeatureTests.swift b/Tests/DatadogTests/Datadog/InternalMonitoring/InternalMonitoringFeatureTests.swift index 745ab0f431..90573dd1fc 100644 --- a/Tests/DatadogTests/Datadog/InternalMonitoring/InternalMonitoringFeatureTests.swift +++ b/Tests/DatadogTests/Datadog/InternalMonitoring/InternalMonitoringFeatureTests.swift @@ -25,9 +25,10 @@ class InternalMonitoringFeatureTests: XCTestCase { // MARK: - HTTP Message func testItUsesExpectedHTTPMessage() throws { - let randomApplicationName: String = .mockRandom() + let randomApplicationName: String = .mockRandom(among: .alphanumerics) let randomApplicationVersion: String = .mockRandom() let randomSource: String = .mockRandom(among: .alphanumerics) + let randomOrigin: String = .mockRandom(among: .alphanumerics) let randomSDKVersion: String = .mockRandom(among: .alphanumerics) let randomUploadURL: URL = .mockRandom() let randomClientToken: String = .mockRandom() @@ -45,6 +46,7 @@ class InternalMonitoringFeatureTests: XCTestCase { applicationName: randomApplicationName, applicationVersion: randomApplicationVersion, source: randomSource, + origin: randomOrigin, sdkVersion: randomSDKVersion ), logsUploadURL: randomUploadURL, @@ -75,7 +77,7 @@ class InternalMonitoringFeatureTests: XCTestCase { XCTAssertEqual(request.allHTTPHeaderFields?["Content-Type"], "application/json") XCTAssertEqual(request.allHTTPHeaderFields?["Content-Encoding"], "deflate") XCTAssertEqual(request.allHTTPHeaderFields?["DD-API-KEY"], randomClientToken) - XCTAssertEqual(request.allHTTPHeaderFields?["DD-EVP-ORIGIN"], randomSource) + XCTAssertEqual(request.allHTTPHeaderFields?["DD-EVP-ORIGIN"], randomOrigin) XCTAssertEqual(request.allHTTPHeaderFields?["DD-EVP-ORIGIN-VERSION"], randomSDKVersion) XCTAssertEqual(request.allHTTPHeaderFields?["DD-REQUEST-ID"]?.matches(regex: .uuidRegex), true) } diff --git a/Tests/DatadogTests/Datadog/LoggerTests.swift b/Tests/DatadogTests/Datadog/LoggerTests.swift index e1e20ef5ab..e9658356f2 100644 --- a/Tests/DatadogTests/Datadog/LoggerTests.swift +++ b/Tests/DatadogTests/Datadog/LoggerTests.swift @@ -167,7 +167,7 @@ class LoggerTests: XCTestCase { Datadog.instance = Datadog( consentProvider: ConsentProvider(initialConsent: .granted), userInfoProvider: UserInfoProvider(), - launchTimeProvider: LaunchTimeProviderMock() + launchTimeProvider: LaunchTimeProviderMock.mockAny() ) defer { Datadog.flushAndDeinitialize() } @@ -674,52 +674,6 @@ class LoggerTests: XCTestCase { logMatcher.assertNoValue(forKeyPath: LoggingWithActiveSpanIntegration.Attributes.spanID) } - // MARK: - Integration With Environment Context - - func testGivenBundlingWithTraceEnabledAndTracerRegisteredAndEnvironmentContext_whenSendingLog_itContainsEnvironmentContextAttributes() throws { - LoggingFeature.instance = .mockByRecordingLogMatchers(directories: temporaryFeatureDirectories) - defer { LoggingFeature.instance?.deinitialize() } - - setenv("x-datadog-trace-id", "111111", 1) - setenv("x-datadog-parent-id", "222222", 1) - - TracingFeature.instance = .mockNoOp() - defer { TracingFeature.instance?.deinitialize() } - - // given - let logger = Logger.builder.build() - Global.sharedTracer = Tracer.initialize(configuration: .init()) - defer { Global.sharedTracer = DDNoopGlobals.tracer } - - // when - let span = Global.sharedTracer.startSpan(operationName: "span").setActive() - logger.info("info message 1") - span.finish() - logger.info("info message 2") - - // then - let logMatchers = try LoggingFeature.waitAndReturnLogMatchers(count: 2) - logMatchers[0].assertValue( - forKeyPath: LoggingWithEnvironmentSpanIntegration.Attributes.traceID, - equals: "\(span.context.dd.traceID.rawValue)" - ) - logMatchers[0].assertValue( - forKeyPath: LoggingWithEnvironmentSpanIntegration.Attributes.spanID, - equals: "\(span.context.dd.spanID.rawValue)" - ) - logMatchers[1].assertValue( - forKeyPath: LoggingWithEnvironmentSpanIntegration.Attributes.traceID, - equals: "\(TracingUUID(rawValue: 111_111).rawValue)" - ) - logMatchers[1].assertValue( - forKeyPath: LoggingWithEnvironmentSpanIntegration.Attributes.spanID, - equals: "\(TracingUUID(rawValue: 222_222).rawValue)" - ) - - unsetenv("x-datadog-trace-id") - unsetenv("x-datadog-parent-id") - } - // MARK: - Log Dates Correction func testGivenTimeDifferenceBetweenDeviceAndServer_whenCollectingLogs_thenLogDateUsesServerTime() throws { diff --git a/Tests/DatadogTests/Datadog/Logging/LogOutputs/LogConsoleOutputTests.swift b/Tests/DatadogTests/Datadog/Logging/LogOutputs/LogConsoleOutputTests.swift index 61833c6e5d..f646113afa 100644 --- a/Tests/DatadogTests/Datadog/Logging/LogOutputs/LogConsoleOutputTests.swift +++ b/Tests/DatadogTests/Datadog/Logging/LogOutputs/LogConsoleOutputTests.swift @@ -11,6 +11,16 @@ import XCTest class LogConsoleOutputTests: XCTestCase { private let log: LogEvent = .mockWith(date: .mockDecember15th2019At10AMUTC(), status: .info, message: "Info message.") + func testItPrintsLogsUsingGlobalConsole() { + var messagePrinted: String = "" + consolePrint = { messagePrinted = $0 } + defer { consolePrint = { print($0) } } + + let output1 = LogConsoleOutput(format: .short, timeZone: .UTC) + output1.write(log: log) + XCTAssertEqual(messagePrinted, "10:00:00.000 [INFO] Info message.") + } + func testItPrintsLogsUsingShortFormat() { var messagePrinted: String = "" diff --git a/Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift b/Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift index c2a667a83d..d862f9bf84 100644 --- a/Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift +++ b/Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift @@ -25,9 +25,10 @@ class LoggingFeatureTests: XCTestCase { // MARK: - HTTP Message func testItUsesExpectedHTTPMessage() throws { - let randomApplicationName: String = .mockRandom() + let randomApplicationName: String = .mockRandom(among: .alphanumerics) let randomApplicationVersion: String = .mockRandom() let randomSource: String = .mockRandom(among: .alphanumerics) + let randomOrigin: String = .mockRandom(among: .alphanumerics) let randomSDKVersion: String = .mockRandom(among: .alphanumerics) let randomUploadURL: URL = .mockRandom() let randomClientToken: String = .mockRandom() @@ -45,6 +46,7 @@ class LoggingFeatureTests: XCTestCase { applicationName: randomApplicationName, applicationVersion: randomApplicationVersion, source: randomSource, + origin: randomOrigin, sdkVersion: randomSDKVersion ), uploadURL: randomUploadURL, @@ -75,7 +77,7 @@ class LoggingFeatureTests: XCTestCase { XCTAssertEqual(request.allHTTPHeaderFields?["Content-Type"], "application/json") XCTAssertEqual(request.allHTTPHeaderFields?["Content-Encoding"], "deflate") XCTAssertEqual(request.allHTTPHeaderFields?["DD-API-KEY"], randomClientToken) - XCTAssertEqual(request.allHTTPHeaderFields?["DD-EVP-ORIGIN"], randomSource) + XCTAssertEqual(request.allHTTPHeaderFields?["DD-EVP-ORIGIN"], randomOrigin) XCTAssertEqual(request.allHTTPHeaderFields?["DD-EVP-ORIGIN-VERSION"], randomSDKVersion) XCTAssertEqual(request.allHTTPHeaderFields?["DD-REQUEST-ID"]?.matches(regex: .uuidRegex), true) } diff --git a/Tests/DatadogTests/Datadog/Mocks/CoreMocks.swift b/Tests/DatadogTests/Datadog/Mocks/CoreMocks.swift index 1934070769..732706118c 100644 --- a/Tests/DatadogTests/Datadog/Mocks/CoreMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/CoreMocks.swift @@ -194,6 +194,7 @@ extension FeaturesConfiguration.Common { environment: String = .mockAny(), performance: PerformancePreset = .init(batchSize: .medium, uploadFrequency: .average, bundleType: .iOSApp), source: String = .mockAny(), + origin: String? = nil, sdkVersion: String = .mockAny(), proxyConfiguration: [AnyHashable: Any]? = nil ) -> Self { @@ -205,6 +206,7 @@ extension FeaturesConfiguration.Common { environment: environment, performance: performance, source: source, + origin: origin, sdkVersion: sdkVersion, proxyConfiguration: proxyConfiguration ) @@ -489,7 +491,7 @@ extension FeaturesCommonDependencies { ) ), carrierInfoProvider: CarrierInfoProviderType = CarrierInfoProviderMock.mockAny(), - launchTimeProvider: LaunchTimeProviderType = LaunchTimeProviderMock(), + launchTimeProvider: LaunchTimeProviderType = LaunchTimeProviderMock.mockAny(), appStateListener: AppStateListening = AppStateListenerMock.mockAny() ) -> FeaturesCommonDependencies { let httpClient: HTTPClient @@ -680,7 +682,22 @@ class DateCorrectorMock: DateCorrectorType { } struct LaunchTimeProviderMock: LaunchTimeProviderType { - var launchTime: TimeInterval = 0 + let launchTime: TimeInterval + let isActivePrewarm: Bool +} + +extension LaunchTimeProviderMock { + static func mockAny() -> LaunchTimeProviderMock { + return mockWith(launchTime: 0, isActivePrewarm: false) + } + + static func mockWith(launchTime: TimeInterval, isActivePrewarm: Bool = false) -> LaunchTimeProviderMock { + return LaunchTimeProviderMock(launchTime: launchTime, isActivePrewarm: isActivePrewarm) + } + + static func mockRandom(launchTime: TimeInterval = .mockRandom(), isActivePrewarm: Bool = .random()) -> LaunchTimeProviderMock { + return mockWith(launchTime: launchTime, isActivePrewarm: isActivePrewarm) + } } extension AppState: AnyMockable, RandomMockable { diff --git a/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift b/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift index 084b579721..2a21ca57b9 100644 --- a/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift @@ -613,7 +613,7 @@ extension RUMScopeDependencies { static func mockWith( appStateListener: AppStateListening = AppStateListenerMock.mockAny(), userInfoProvider: RUMUserInfoProvider = RUMUserInfoProvider(userInfoProvider: .mockAny()), - launchTimeProvider: LaunchTimeProviderType = LaunchTimeProviderMock(), + launchTimeProvider: LaunchTimeProviderType = LaunchTimeProviderMock.mockAny(), connectivityInfoProvider: RUMConnectivityInfoProvider = RUMConnectivityInfoProvider( networkConnectionInfoProvider: NetworkConnectionInfoProviderMock(networkConnectionInfo: nil), carrierInfoProvider: CarrierInfoProviderMock(carrierInfo: nil) @@ -624,6 +624,7 @@ extension RUMScopeDependencies { rumUUIDGenerator: RUMUUIDGenerator = DefaultRUMUUIDGenerator(), dateCorrector: DateCorrectorType = DateCorrectorMock(), crashContextIntegration: RUMWithCrashContextIntegration? = nil, + ciTest: RUMCITest? = nil, onSessionStart: @escaping RUMSessionListener = mockNoOpSessionListerner() ) -> RUMScopeDependencies { return RUMScopeDependencies( @@ -637,6 +638,7 @@ extension RUMScopeDependencies { rumUUIDGenerator: rumUUIDGenerator, dateCorrector: dateCorrector, crashContextIntegration: crashContextIntegration, + ciTest: ciTest, vitalCPUReader: SamplingBasedVitalReaderMock(), vitalMemoryReader: SamplingBasedVitalReaderMock(), vitalRefreshRateReader: ContinuousVitalReaderMock(), @@ -656,6 +658,7 @@ extension RUMScopeDependencies { rumUUIDGenerator: RUMUUIDGenerator? = nil, dateCorrector: DateCorrectorType? = nil, crashContextIntegration: RUMWithCrashContextIntegration? = nil, + ciTest: RUMCITest? = nil, onSessionStart: @escaping RUMSessionListener = mockNoOpSessionListerner() ) -> RUMScopeDependencies { return RUMScopeDependencies( @@ -669,6 +672,7 @@ extension RUMScopeDependencies { rumUUIDGenerator: rumUUIDGenerator ?? self.rumUUIDGenerator, dateCorrector: dateCorrector ?? self.dateCorrector, crashContextIntegration: crashContextIntegration ?? self.crashContextIntegration, + ciTest: ciTest, vitalCPUReader: SamplingBasedVitalReaderMock(), vitalMemoryReader: SamplingBasedVitalReaderMock(), vitalRefreshRateReader: ContinuousVitalReaderMock(), @@ -903,7 +907,13 @@ class UIKitRUMViewsHandlerMock: UIViewControllerHandler { } } -class UIKitRUMUserActionsPredicateMock: UIKitRUMUserActionsPredicate { +#if os(tvOS) +typealias UIKitRUMUserActionsPredicateMock = UIPressRUMUserActionsPredicateMock +#else +typealias UIKitRUMUserActionsPredicateMock = UITouchRUMUserActionsPredicateMock +#endif + +class UITouchRUMUserActionsPredicateMock: UITouchRUMUserActionsPredicate { var resultByView: [UIView: RUMAction] = [:] var result: RUMAction? @@ -916,6 +926,19 @@ class UIKitRUMUserActionsPredicateMock: UIKitRUMUserActionsPredicate { } } +class UIPressRUMUserActionsPredicateMock: UIPressRUMUserActionsPredicate { + var resultByView: [UIView: RUMAction] = [:] + var result: RUMAction? + + init(result: RUMAction? = nil) { + self.result = result + } + + func rumAction(press type: UIPress.PressType, targetView: UIView) -> RUMAction? { + return resultByView[targetView] ?? result + } +} + class UIKitRUMUserActionsHandlerMock: UIEventHandler { var onSubscribe: ((RUMCommandSubscriber) -> Void)? var onSendEvent: ((UIApplication, UIEvent) -> Void)? diff --git a/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/CoreTelephonyMocks.swift b/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/CoreTelephonyMocks.swift index e77c7f58da..bd52e74d9b 100644 --- a/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/CoreTelephonyMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/CoreTelephonyMocks.swift @@ -4,6 +4,7 @@ * Copyright 2019-2020 Datadog, Inc. */ +#if canImport(CoreTelephony) import CoreTelephony /* @@ -67,3 +68,5 @@ class CTTelephonyNetworkInfoMock: CTTelephonyNetworkInfo { override var currentRadioAccessTechnology: String? { _serviceCurrentRadioAccessTechnology?.first?.value } override var subscriberCellularProvider: CTCarrier? { _serviceSubscriberCellularProviders?.first?.value } } + +#endif diff --git a/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/UIKitMocks.swift b/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/UIKitMocks.swift index 4aca6fa6c6..4675a1f446 100644 --- a/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/UIKitMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/UIKitMocks.swift @@ -11,27 +11,52 @@ A collection of mocks for different `UIKit` types. It follows the mocking conventions described in `FoundationMocks.swift`. */ +#if !os(tvOS) extension UIDevice.BatteryState { static func mockAny() -> UIDevice.BatteryState { return .full } } +#endif class UIDeviceMock: UIDevice { + override var model: String { _model } + override var systemName: String { _systemName } + override var systemVersion: String { "mock system version" } + private var _model: String private var _systemName: String private var _systemVersion: String + + #if os(tvOS) + init( + model: String = .mockAny(), + systemName: String = .mockAny(), + systemVersion: String = .mockAny() + ) { + self._model = model + self._systemName = systemName + self._systemVersion = systemVersion + } + #else + override var isBatteryMonitoringEnabled: Bool { + get { _isBatteryMonitoringEnabled } + set { _isBatteryMonitoringEnabled = newValue } + } + override var batteryState: UIDevice.BatteryState { _batteryState } + override var batteryLevel: Float { _batteryLevel } + private var _isBatteryMonitoringEnabled: Bool - private var _batteryState: UIDevice.BatteryState private var _batteryLevel: Float + private var _batteryState: UIDevice.BatteryState init( model: String = .mockAny(), systemName: String = .mockAny(), systemVersion: String = .mockAny(), isBatteryMonitoringEnabled: Bool = .mockAny(), - batteryState: UIDevice.BatteryState = .mockAny(), - batteryLevel: Float = .mockAny() + batteryLevel: Float = .mockAny(), + batteryState: UIDevice.BatteryState = .mockAny() ) { self._model = model self._systemName = systemName @@ -40,26 +65,33 @@ class UIDeviceMock: UIDevice { self._batteryState = batteryState self._batteryLevel = batteryLevel } - - override var model: String { _model } - override var systemName: String { _systemName } - override var systemVersion: String { "mock system version" } - override var isBatteryMonitoringEnabled: Bool { - get { _isBatteryMonitoringEnabled } - set { _isBatteryMonitoringEnabled = newValue } - } - override var batteryState: UIDevice.BatteryState { _batteryState } - override var batteryLevel: Float { _batteryLevel } + #endif } extension UIEvent { - static func mockAny() -> UIEvent { + static func mockAnyTouch() -> UIEvent { + return .mockWith(touches: [.mockAny()]) + } + + static func mockAnyPress() -> UIEvent { return .mockWith(touches: [.mockAny()]) } + static func mockWith(touch: UITouch) -> UIEvent { + return UIEventMock(allTouches: [touch]) + } + static func mockWith(touches: Set?) -> UIEvent { return UIEventMock(allTouches: touches) } + + static func mockWith(press: UIPress) -> UIPressesEvent { + return UIPressesEventMock(allPresses: [press]) + } + + static func mockWith(presses: Set) -> UIPressesEvent { + return UIPressesEventMock(allPresses: presses) + } } private class UIEventMock: UIEvent { @@ -72,16 +104,43 @@ private class UIEventMock: UIEvent { override var allTouches: Set? { _allTouches } } +private class UIPressesEventMock: UIPressesEvent { + private let _allPresses: Set + + fileprivate init(allPresses: Set = []) { + _allPresses = allPresses + } + + override var allPresses: Set { _allPresses } +} + extension UITouch { static func mockAny() -> UITouch { - return mockWith(phase: .ended, view: UIView()) + return mockWith(view: UIView()) } - static func mockWith(phase: UITouch.Phase, view: UIView?) -> UITouch { + static func mockWith( + phase: UITouch.Phase = .ended, + view: UIView? = .init() + ) -> UITouch { return UITouchMock(phase: phase, view: view) } } +extension UIPress { + static func mockAny() -> UIPress { + return mockWith(type: .select, view: UIView()) + } + + static func mockWith( + phase: UIPress.Phase = .ended, + type: UIPress.PressType = .select, + view: UIView? = .init() + ) -> UIPress { + return UIPressMock(phase: phase, type: type, view: view) + } +} + private class UITouchMock: UITouch { private let _phase: UITouch.Phase private let _view: UIView? @@ -95,6 +154,22 @@ private class UITouchMock: UITouch { override var view: UIView? { _view } } +private class UIPressMock: UIPress { + private let _phase: UIPress.Phase + private let _type: UIPress.PressType + private let _view: UIView? + + fileprivate init(phase: UIPress.Phase, type: UIPress.PressType, view: UIView?) { + _phase = phase + _type = type + _view = view + } + + override var phase: UIPress.Phase { _phase } + override var type: UIPress.PressType { _type } + override var responder: UIResponder? { _view } +} + extension UIApplication.State: AnyMockable, RandomMockable { static func mockAny() -> UIApplication.State { return .active diff --git a/Tests/DatadogTests/Datadog/Mocks/TracingFeatureMocks.swift b/Tests/DatadogTests/Datadog/Mocks/TracingFeatureMocks.swift index b47feea11f..90a2acaaaa 100644 --- a/Tests/DatadogTests/Datadog/Mocks/TracingFeatureMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/TracingFeatureMocks.swift @@ -178,6 +178,7 @@ extension SpanEvent: AnyMockable, RandomMockable { duration: TimeInterval = .mockAny(), isError: Bool = .mockAny(), source: String = .mockAny(), + origin: String? = nil, tracerVersion: String = .mockAny(), applicationVersion: String = .mockAny(), networkConnectionInfo: NetworkConnectionInfo? = .mockAny(), @@ -196,6 +197,7 @@ extension SpanEvent: AnyMockable, RandomMockable { duration: duration, isError: isError, source: source, + origin: origin, tracerVersion: tracerVersion, applicationVersion: applicationVersion, networkConnectionInfo: networkConnectionInfo, @@ -219,6 +221,7 @@ extension SpanEvent: AnyMockable, RandomMockable { duration: .mockRandom(), isError: .random(), source: .mockRandom(), + origin: .mockRandom(), tracerVersion: .mockRandom(), applicationVersion: .mockRandom(), networkConnectionInfo: .mockRandom(), @@ -300,6 +303,7 @@ extension SpanEventBuilder { carrierInfoProvider: CarrierInfoProviderType = CarrierInfoProviderMock.mockAny(), dateCorrector: DateCorrectorType = DateCorrectorMock(), source: String = .mockAny(), + origin: String? = nil, sdkVersion: String = .mockAny(), eventsMapper: SpanEventMapper? = nil ) -> SpanEventBuilder { @@ -312,6 +316,7 @@ extension SpanEventBuilder { carrierInfoProvider: carrierInfoProvider, dateCorrector: dateCorrector, source: source, + origin: origin, eventsMapper: eventsMapper ) } diff --git a/Tests/DatadogTests/Datadog/RUM/Debugging/RUMDebuggingTests.swift b/Tests/DatadogTests/Datadog/RUM/Debugging/RUMDebuggingTests.swift index 1b7c916ad9..d1c80ec69d 100644 --- a/Tests/DatadogTests/Datadog/RUM/Debugging/RUMDebuggingTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/Debugging/RUMDebuggingTests.swift @@ -8,6 +8,9 @@ import XCTest import UIKit @testable import Datadog +// TODO: RUMM-2034 Remove this flag once we have a host application for tests +#if !os(tvOS) + class RUMDebuggingTests: XCTestCase { func testWhenOneRUMViewIsActive_itDisplaysSingleRUMViewOutline() throws { let expectation = self.expectation(description: "Render RUMDebugging") @@ -73,3 +76,5 @@ class RUMDebuggingTests: XCTestCase { XCTAssertLessThan(firstViewOutlineLabel.alpha, secondViewOutlineLabel.alpha) } } + +#endif diff --git a/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIApplicationSwizzlerTests.swift b/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIApplicationSwizzlerTests.swift index a6b2533284..ce9c9d4240 100644 --- a/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIApplicationSwizzlerTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIApplicationSwizzlerTests.swift @@ -7,6 +7,9 @@ import XCTest @testable import Datadog +// TODO: RUMM-2034 Remove this flag once we have a host application for tests +#if !os(tvOS) + class UIApplicationSwizzlerTests: XCTestCase { private let handler = UIKitRUMUserActionsHandlerMock() private lazy var swizzler = try! UIApplicationSwizzler(handler: handler) @@ -38,3 +41,5 @@ class UIApplicationSwizzlerTests: XCTestCase { waitForExpectations(timeout: 1.5, handler: nil) } } + +#endif diff --git a/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift b/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift index b167883a03..49aceee619 100644 --- a/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift @@ -11,13 +11,17 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { private let dateProvider = RelativeDateProvider(using: .mockDecember15th2019At10AMUTC()) private let commandSubscriber = RUMCommandSubscriberMock() - private func createHandler(userActionsPredicate: UIKitRUMUserActionsPredicate = DefaultUIKitRUMUserActionsPredicate()) -> UIKitRUMUserActionsHandler { - let handler = UIKitRUMUserActionsHandler(dateProvider: dateProvider, predicate: userActionsPredicate) + private func touchHandler(with predicate: UITouchRUMUserActionsPredicate = DefaultUIKitRUMUserActionsPredicate()) -> UIKitRUMUserActionsHandler { + let handler = UIKitRUMUserActionsHandler(dateProvider: dateProvider, predicate: predicate) handler.publish(to: commandSubscriber) return handler } - private lazy var handler = createHandler() + private func pressHandler(with predicate: UIPressRUMUserActionsPredicate = DefaultUIKitRUMUserActionsPredicate()) -> UIKitRUMUserActionsHandler { + let handler = UIKitRUMUserActionsHandler(dateProvider: dateProvider, predicate: predicate) + handler.publish(to: commandSubscriber) + return handler + } private var mockAppWindow: UIWindow! // swiftlint:disable:this implicitly_unwrapped_optional @@ -35,6 +39,7 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { func testGivenViewWithAccessibilityIdentifier_whenSingleTouchEnds_itSendsRUMAction() { // Given + let handler = touchHandler() let fixtures: [(view: UIView, expectedRUMActionName: String)] = [ ( view: UIButton() @@ -64,7 +69,7 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { // When handler.notify_sendEvent( application: .shared, - event: .mockWith(touches: [.mockWith(phase: .ended, view: view)]) + event: .mockWith(touch: .mockWith(view: view)) ) // Then @@ -78,6 +83,7 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { func testGivenViewWithNoAccessibilityIdentifier_whenSingleTouchEnds_itSendsRUMAction() { // Given + let handler = touchHandler() let fixtures: [(view: UIView, expectedRUMActionName: String)] = [ ( view: UIButton() @@ -100,7 +106,7 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { // When handler.notify_sendEvent( application: .shared, - event: .mockWith(touches: [.mockWith(phase: .ended, view: view)]) + event: .mockWith(touch: .mockWith(view: view)) ) // Then @@ -116,13 +122,14 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { func testGivenAnyViewWithUnrecognizedHierarchy_whenTouchEnds_itGetsIgnored() { // Given + let handler = touchHandler() let superview = UIView().attached(to: mockAppWindow) let view = UIView().attached(to: superview) // When handler.notify_sendEvent( application: .shared, - event: .mockWith(touches: [.mockWith(phase: .ended, view: view)]) + event: .mockWith(touch: .mockWith(view: view)) ) // Then @@ -133,26 +140,28 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { let mockKeyboardWindow = MockUIRemoteKeyboardWindow(frame: .zero) // Given + let handler = touchHandler() let view = UIView().attached(to: mockKeyboardWindow) // When handler.notify_sendEvent( application: .shared, - event: .mockWith(touches: [.mockWith(phase: .ended, view: view)]) + event: .mockWith(touch: .mockWith(view: view)) ) // Then XCTAssertNil(commandSubscriber.lastReceivedCommand) } - func testGivenAnyUIControlNotAttachedToAnyWindow_itGetsIgnoredForPrivacyReason() { + func testGivenAnyUIControlTouchNotAttachedToAnyWindow_itGetsIgnoredForPrivacyReason() { // Given + let handler = touchHandler() let uiControl = UIControl() // When handler.notify_sendEvent( application: .shared, - event: .mockWith(touches: [.mockWith(phase: .ended, view: uiControl)]) + event: .mockWith(touch: .mockWith(view: uiControl)) ) // Then @@ -161,10 +170,11 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { func testItIgnoresSingleTouchEventWithPhaseOtherThanEnded() { // Given + let handler = touchHandler() let view = UIControl().attached(to: mockAppWindow) let ignoredTouchPhases: [UITouch.Phase] - if #available(iOS 13.4, *) { + if #available(iOS 13.4, tvOS 13.4, *) { ignoredTouchPhases = [.began, .moved, .stationary, .cancelled, .regionEntered, .regionMoved, .regionExited] } else { ignoredTouchPhases = [.began, .moved, .stationary, .cancelled] @@ -174,7 +184,7 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { // When handler.notify_sendEvent( application: .shared, - event: .mockWith(touches: [.mockWith(phase: touchPhase, view: view)]) + event: .mockWith(touch: .mockWith(phase: touchPhase, view: view)) ) // Then @@ -184,6 +194,7 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { func testItIgnoresMultitouchEvents() { // Given + let handler = touchHandler() let view = UIControl().attached(to: mockAppWindow) // When @@ -191,8 +202,8 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { application: .shared, event: .mockWith( touches: [ - .mockWith(phase: .ended, view: view), // 1st touch - .mockWith(phase: .ended, view: view) // 2nd touch + .mockWith(view: view), // 1st touch + .mockWith(view: view) // 2nd touch ] ) ) @@ -202,6 +213,9 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { } func testItIgnoresEventsWithNoTouch() { + // Given + let handler = touchHandler() + // When handler.notify_sendEvent( application: .shared, @@ -212,18 +226,18 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { XCTAssertNil(commandSubscriber.lastReceivedCommand) } - func testItAppliesUserAttributesAndCustomName() { + func testGivenTouchEvent_itAppliesUserAttributesAndCustomName() { // Given let mockAttributes: [AttributeKey: AttributeValue] = mockRandomAttributes() - let handler = createHandler( - userActionsPredicate: MockUIKitRUMUserActionsPredicate( + let handler = touchHandler( + with: MockUIKitRUMUserActionsPredicate( actionOverride: (name: "foobar", attributes: mockAttributes) ) ) let view = UIButton() .attached(to: mockAppWindow) .with(accessibilityIdentifier: "Some Button") - let event = UIEvent.mockWith(touches: [.mockWith(phase: .ended, view: view)]) + let event = UIEvent.mockWith(touch: .mockWith(view: view)) // When handler.notify_sendEvent( @@ -237,15 +251,173 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { AssertDictionariesEqual(command!.attributes, mockAttributes) } - func testGivenUserActionPredicateReturnsNil_itDoesntSendAction() { + func testGivenUserActionPredicateReturnsNil_itDoesntSendTapAction() { // Given - let handler = createHandler( - userActionsPredicate: MockUIKitRUMUserActionsPredicate(actionOverride: nil) + let handler = touchHandler( + with: MockUIKitRUMUserActionsPredicate(actionOverride: nil) ) let view = UIButton() .attached(to: mockAppWindow) .with(accessibilityIdentifier: "Some Button") - let event = UIEvent.mockWith(touches: [.mockWith(phase: .ended, view: view)]) + let event = UIEvent.mockWith(touch: .mockWith(view: view)) + + // When + handler.notify_sendEvent( + application: .shared, + event: event + ) + + // Then + XCTAssertNil(commandSubscriber.lastReceivedCommand) + } + + // MARK: - Scenarios For Accepting Click Events + + func testGivenUIPress_whenSinglePressEnds_itSendsRUMAction() { + // Given + let handler = pressHandler() + let fixtures: [(event: UIEvent, expect: String)] = [ + ( + event: .mockWith( + press: .mockWith( + type: .select, + view: UIView() + .attached(to: mockAppWindow) + .with(accessibilityIdentifier: "Some View") + ) + ), + expect: "UIView(Some View)" + ), + ( + event: .mockWith(press: .mockWith(type: .menu, view: UIView().attached(to: mockAppWindow))), + expect: "menu" + ), + ( + event: .mockWith(press: .mockWith(type: .playPause, view: UIView().attached(to: mockAppWindow))), + expect: "play-pause" + ) + ] + + fixtures.forEach { event, expect in + // When + handler.notify_sendEvent(application: .shared, event: event) + + // Then + let command = commandSubscriber.lastReceivedCommand as? RUMAddUserActionCommand + XCTAssertEqual(command?.name, expect) + XCTAssertEqual(command?.actionType, .click) + XCTAssertEqual(command?.time, .mockDecember15th2019At10AMUTC()) + XCTAssertEqual(command?.attributes.count, 0) + } + } + + // MARK: - Scenarios For Ignoring Tap Events + + func testGivenAnyViewPresentedInKeyboardWindow_whenPressEnds_itGetsIgnoredForPrivacyReason() { + let mockKeyboardWindow = MockUIRemoteKeyboardWindow(frame: .zero) + + // Given + let handler = pressHandler() + let view = UIView().attached(to: mockKeyboardWindow) + + // When + handler.notify_sendEvent( + application: .shared, + event: .mockWith(press: .mockWith(view: view)) + ) + + // Then + XCTAssertNil(commandSubscriber.lastReceivedCommand) + } + + func testGivenAnyUIControlPressNotAttachedToAnyWindow_itGetsIgnoredForPrivacyReason() { + // Given + let handler = pressHandler() + let uiControl = UIControl() + + // When + handler.notify_sendEvent( + application: .shared, + event: .mockWith(press: .mockWith(view: uiControl)) + ) + + // Then + XCTAssertNil(commandSubscriber.lastReceivedCommand) + } + + func testItIgnoresSinglePressEventWithPhaseOtherThanEnded() { + // Given + let handler = pressHandler() + let view = UIControl().attached(to: mockAppWindow) + + let ignoredPressPhases: [UIPress.Phase] = [.began, .stationary, .cancelled] + + ignoredPressPhases.forEach { phase in + // When + handler.notify_sendEvent( + application: .shared, + event: .mockWith(press: .mockWith(phase: phase, view: view)) + ) + + // Then + XCTAssertNil(commandSubscriber.lastReceivedCommand) + } + } + + func testItIgnoresMultiPressEvents() { + // Given + let handler = pressHandler() + let view = UIControl().attached(to: mockAppWindow) + + // When + handler.notify_sendEvent( + application: .shared, + event: .mockWith( + presses: [ + .mockWith(view: view), // 1st touch + .mockWith(view: view) // 2nd touch + ] + ) + ) + + // Then + XCTAssertNil(commandSubscriber.lastReceivedCommand) + } + + func testGivenPressEvent_ItAppliesUserAttributesAndCustomName() { + // Given + let mockAttributes: [AttributeKey: AttributeValue] = mockRandomAttributes() + let handler = pressHandler( + with: MockUIKitRUMUserActionsPredicate( + actionOverride: (name: "foobar", attributes: mockAttributes) + ) + ) + let view = UIButton() + .attached(to: mockAppWindow) + .with(accessibilityIdentifier: "Some Button") + let event = UIEvent.mockWith(press: .mockWith(view: view)) + + // When + handler.notify_sendEvent( + application: .shared, + event: event + ) + + // Then + let command = commandSubscriber.lastReceivedCommand as? RUMAddUserActionCommand + XCTAssertEqual(command?.name, "foobar") + AssertDictionariesEqual(command!.attributes, mockAttributes) + } + + func testGivenUserActionPredicateReturnsNil_itDoesntSendClickAction() { + // Given + let handler = pressHandler( + with: MockUIKitRUMUserActionsPredicate(actionOverride: nil) + ) + let view = UIButton() + .attached(to: mockAppWindow) + .with(accessibilityIdentifier: "Some Button") + let event = UIEvent.mockWith(press: .mockWith(view: view)) // When handler.notify_sendEvent( @@ -275,7 +447,7 @@ private extension UIView { /// The mock the keyboard window by having the class name contain "UIRemoteKeyboardWindow" string. private class MockUIRemoteKeyboardWindow: UIWindow {} -private class MockUIKitRUMUserActionsPredicate: UIKitRUMUserActionsPredicate { +private class MockUIKitRUMUserActionsPredicate: UITouchRUMUserActionsPredicate & UIPressRUMUserActionsPredicate { private let actionOverride: (name: String, attributes: [AttributeKey: AttributeValue])? init(actionOverride: (name: String, attributes: [AttributeKey: AttributeValue])?) { @@ -283,10 +455,14 @@ private class MockUIKitRUMUserActionsPredicate: UIKitRUMUserActionsPredicate { } func rumAction(targetView: UIView) -> RUMAction? { - if let action = actionOverride { - return RUMAction(name: action.name, attributes: action.attributes) - } else { + guard let action = actionOverride else { return nil } + + return RUMAction(name: action.name, attributes: action.attributes) + } + + func rumAction(press type: UIPress.PressType, targetView: UIView) -> RUMAction? { + return rumAction(targetView: targetView) } } diff --git a/Tests/DatadogTests/Datadog/RUM/Instrumentation/Views/UIKit/UIKitRUMViewsPredicateTests.swift b/Tests/DatadogTests/Datadog/RUM/Instrumentation/Views/UIKit/UIKitRUMViewsPredicateTests.swift index 450101e1d1..f61172d91c 100644 --- a/Tests/DatadogTests/Datadog/RUM/Instrumentation/Views/UIKit/UIKitRUMViewsPredicateTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/Instrumentation/Views/UIKit/UIKitRUMViewsPredicateTests.swift @@ -54,7 +54,7 @@ class UIKitRUMViewsPredicateTests: XCTestCase { #if canImport(SwiftUI) func testGivenDefaultPredicate_whenAskingSwiftUIViewController_itReturnsNoView() { - guard #available(iOS 13, *) else { + guard #available(iOS 13, tvOS 13, *) else { return } // Given diff --git a/Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift b/Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift index d145c656eb..f052c57467 100644 --- a/Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift @@ -25,11 +25,12 @@ class RUMFeatureTests: XCTestCase { // MARK: - HTTP Message func testItUsesExpectedHTTPMessage() throws { - let randomApplicationName: String = .mockRandom() + let randomApplicationName: String = .mockRandom(among: .alphanumerics) let randomApplicationVersion: String = .mockRandom(among: .decimalDigits) let randomServiceName: String = .mockRandom(among: .alphanumerics) let randomEnvironmentName: String = .mockRandom(among: .alphanumerics) let randomSource: String = .mockRandom(among: .alphanumerics) + let randomOrigin: String = .mockRandom(among: .alphanumerics) let randomSDKVersion: String = .mockRandom(among: .alphanumerics) let randomUploadURL: URL = .mockRandom() let randomClientToken: String = .mockRandom() @@ -49,6 +50,7 @@ class RUMFeatureTests: XCTestCase { serviceName: randomServiceName, environment: randomEnvironmentName, source: randomSource, + origin: randomOrigin, sdkVersion: randomSDKVersion ), uploadURL: randomUploadURL, @@ -84,7 +86,7 @@ class RUMFeatureTests: XCTestCase { XCTAssertEqual(request.allHTTPHeaderFields?["Content-Type"], "text/plain;charset=UTF-8") XCTAssertEqual(request.allHTTPHeaderFields?["Content-Encoding"], "deflate") XCTAssertEqual(request.allHTTPHeaderFields?["DD-API-KEY"], randomClientToken) - XCTAssertEqual(request.allHTTPHeaderFields?["DD-EVP-ORIGIN"], randomSource) + XCTAssertEqual(request.allHTTPHeaderFields?["DD-EVP-ORIGIN"], randomOrigin) XCTAssertEqual(request.allHTTPHeaderFields?["DD-EVP-ORIGIN-VERSION"], randomSDKVersion) XCTAssertEqual(request.allHTTPHeaderFields?["DD-REQUEST-ID"]?.matches(regex: .uuidRegex), true) } diff --git a/Tests/DatadogTests/Datadog/RUM/RUMMonitor/Scopes/RUMViewScopeTests.swift b/Tests/DatadogTests/Datadog/RUM/RUMMonitor/Scopes/RUMViewScopeTests.swift index 343eb97879..8834c3f72e 100644 --- a/Tests/DatadogTests/Datadog/RUM/RUMMonitor/Scopes/RUMViewScopeTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/RUMMonitor/Scopes/RUMViewScopeTests.swift @@ -66,12 +66,13 @@ class RUMViewScopeTests: XCTestCase { } func testWhenInitialViewReceivesAnyCommand_itSendsApplicationStartAction() throws { + // Given let currentTime: Date = .mockDecember15th2019At10AMUTC() let scope = RUMViewScope( isInitialView: true, parent: parent, dependencies: dependencies.replacing( - launchTimeProvider: LaunchTimeProviderMock(launchTime: 2) // 2 seconds + launchTimeProvider: LaunchTimeProviderMock.mockWith(launchTime: 2) // 2 seconds ), identity: mockView, path: "UIViewController", @@ -81,8 +82,10 @@ class RUMViewScopeTests: XCTestCase { startTime: currentTime ) + // When _ = scope.process(command: RUMCommandMock(time: currentTime)) + // Then let event = try XCTUnwrap(output.recordedEvents(ofType: RUMActionEvent.self).first) XCTAssertEqual(event.date, Date.mockDecember15th2019At10AMUTC().timeIntervalSince1970.toInt64Milliseconds) XCTAssertEqual(event.application.id, scope.context.rumApplicationID) @@ -97,6 +100,32 @@ class RUMViewScopeTests: XCTestCase { XCTAssertEqual(event.dd.session?.plan, .plan1, "All RUM events should use RUM Lite plan") XCTAssertEqual(event.source, .ios) XCTAssertEqual(event.service, randomServiceName) + XCTAssertNil(event.context?.contextInfo[RUMViewScope.Constants.activePrewarm]) + } + + func testWhenActivePrewarm_itSendsApplicationStartAction_withoutLoadingTime() throws { + // Given + let scope: RUMViewScope = .mockWith( + isInitialView: true, + parent: parent, + dependencies: dependencies.replacing( + launchTimeProvider: LaunchTimeProviderMock.mockWith( + launchTime: 2, // 2 seconds + isActivePrewarm: true + ) + ), + identity: mockView + ) + + // When + _ = scope.process(command: RUMCommandMock()) + + // Then + let event = try XCTUnwrap(output.recordedEvents(ofType: RUMActionEvent.self).first) + let isActivePrewarm = try XCTUnwrap(event.context?.contextInfo[RUMViewScope.Constants.activePrewarm] as? Bool) + XCTAssertEqual(event.action.type, .applicationStart) + XCTAssertNil(event.action.loadingTime) + XCTAssertTrue(isActivePrewarm) } func testWhenInitialViewReceivesAnyCommand_itSendsViewUpdateEvent() throws { diff --git a/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift b/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift index 22181cfeb3..20a862681b 100644 --- a/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift @@ -4,8 +4,11 @@ * Copyright 2019-2020 Datadog, Inc. */ +#if !os(tvOS) + import XCTest import WebKit + @testable import Datadog final class DDUserContentController: WKUserContentController { @@ -23,6 +26,10 @@ final class DDUserContentController: WKUserContentController { } } +final class MockMessageHandler: NSObject, WKScriptMessageHandler { + func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { } +} + final class MockScriptMessage: WKScriptMessage { let mockBody: Any @@ -96,6 +103,31 @@ class WKUserContentController_DatadogTests: XCTestCase { XCTAssertEqual(recordedLogMessages, Array(repeating: "`trackDatadogEvents(in:)` was called more than once for the same WebView. Second call will be ignored. Make sure you call it only once.", count: multipleTimes - 1)) } + func testWhenStoppingTracking_itKeepsNonDatadogComponents() throws { + let controller = DDUserContentController() + + controller.trackDatadogEvents(in: []) + + let componentCount = 10 + for i in 0.. Void) { - queue.asyncAfter(deadline: .now() + 1) { - completion() - } - } - - let request1Span = tracer.startSpan(operationName: "/resource/1") - makeAPIRequest { - request1Span.finish() - } - - let request2Span = tracer.startSpan(operationName: "/resource/2") - makeAPIRequest { - request2Span.finish() - } - tracer.activeSpan?.finish() - - let spanMatchers = try TracingFeature.waitAndReturnSpanMatchers(count: 2) - XCTAssertEqual(try spanMatchers[0].parentSpanID(), TracingUUID(rawValue: 222_222).toHexadecimalString) - XCTAssertEqual(try spanMatchers[0].traceID(), TracingUUID(rawValue: 111_111).toHexadecimalString) - XCTAssertEqual(try spanMatchers[1].parentSpanID(), TracingUUID(rawValue: 222_222).toHexadecimalString) - XCTAssertEqual(try spanMatchers[1].traceID(), TracingUUID(rawValue: 111_111).toHexadecimalString) - - unsetenv("x-datadog-trace-id") - unsetenv("x-datadog-parent-id") - } - - func testSendingSpanWithActiveSpanAsAParentAndEnvironmentContext() throws { - TracingFeature.instance = .mockByRecordingSpanMatchers(directories: temporaryFeatureDirectories) - defer { TracingFeature.instance?.deinitialize() } - - setenv("x-datadog-trace-id", "111111", 1) - setenv("x-datadog-parent-id", "222222", 1) - - let tracer = Tracer.initialize(configuration: .init()).dd - let queue1 = DispatchQueue(label: "\(#function)-queue1") - let queue2 = DispatchQueue(label: "\(#function)-queue2") - - let rootSpan = tracer.startSpan(operationName: "root operation").setActive() - - queue1.sync { - let child1Span = tracer.startSpan(operationName: "child 1 operation") - child1Span.finish() - } - - queue2.sync { - let child2Span = tracer.startSpan(operationName: "child 2 operation") - child2Span.finish() - } - - rootSpan.finish() - - let spanMatchers = try TracingFeature.waitAndReturnSpanMatchers(count: 3) - let rootMatcher = spanMatchers[2] - let child1Matcher = spanMatchers[1] - let child2Matcher = spanMatchers[0] - - XCTAssertEqual(try rootMatcher.parentSpanID(), TracingUUID(rawValue: 222_222).toHexadecimalString) - XCTAssertEqual(try spanMatchers[0].traceID(), TracingUUID(rawValue: 111_111).toHexadecimalString) - XCTAssertEqual(try child1Matcher.parentSpanID(), try rootMatcher.spanID()) - XCTAssertEqual(try child1Matcher.traceID(), TracingUUID(rawValue: 111_111).toHexadecimalString) - XCTAssertEqual(try child2Matcher.parentSpanID(), try rootMatcher.spanID()) - XCTAssertEqual(try child2Matcher.traceID(), TracingUUID(rawValue: 111_111).toHexadecimalString) - - unsetenv("x-datadog-trace-id") - unsetenv("x-datadog-parent-id") - } } // swiftlint:enable multiline_arguments_brackets diff --git a/Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift b/Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift index b2853bd49b..06fc2a8502 100644 --- a/Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift +++ b/Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift @@ -25,9 +25,10 @@ class TracingFeatureTests: XCTestCase { // MARK: - HTTP Message func testItUsesExpectedHTTPMessage() throws { - let randomApplicationName: String = .mockRandom() + let randomApplicationName: String = .mockRandom(among: .alphanumerics) let randomApplicationVersion: String = .mockRandom() let randomSource: String = .mockRandom() + let randomOrigin: String = .mockRandom() let randomSDKVersion: String = .mockRandom(among: .alphanumerics) let randomUploadURL: URL = .mockRandom() let randomClientToken: String = .mockRandom() @@ -45,6 +46,7 @@ class TracingFeatureTests: XCTestCase { applicationName: randomApplicationName, applicationVersion: randomApplicationVersion, source: randomSource, + origin: randomOrigin, sdkVersion: randomSDKVersion ), uploadURL: randomUploadURL, @@ -76,7 +78,7 @@ class TracingFeatureTests: XCTestCase { XCTAssertEqual(request.allHTTPHeaderFields?["Content-Type"], "text/plain;charset=UTF-8") XCTAssertEqual(request.allHTTPHeaderFields?["Content-Encoding"], "deflate") XCTAssertEqual(request.allHTTPHeaderFields?["DD-API-KEY"], randomClientToken) - XCTAssertEqual(request.allHTTPHeaderFields?["DD-EVP-ORIGIN"], randomSource) + XCTAssertEqual(request.allHTTPHeaderFields?["DD-EVP-ORIGIN"], randomOrigin) XCTAssertEqual(request.allHTTPHeaderFields?["DD-EVP-ORIGIN-VERSION"], randomSDKVersion) XCTAssertEqual(request.allHTTPHeaderFields?["DD-REQUEST-ID"]?.matches(regex: .uuidRegex), true) } diff --git a/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/Interception/TaskInterceptionTests.swift b/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/Interception/TaskInterceptionTests.swift index 3b29c95bcf..3ec6002899 100644 --- a/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/Interception/TaskInterceptionTests.swift +++ b/Tests/DatadogTests/Datadog/URLSessionAutoInstrumentation/Interception/TaskInterceptionTests.swift @@ -64,7 +64,7 @@ class ResourceMetricsTests: XCTestCase { } func testWhenTaskMakesSingleFetchFromNetwork_thenAllMetricsExceptRedirectionAreCollected() { - guard #available(iOS 13, *) else { + guard #available(iOS 13, tvOS 13, *) else { return } @@ -103,7 +103,7 @@ class ResourceMetricsTests: XCTestCase { } func testWhenTaskMakesMultipleFetchesFromNetwork_thenAllMetricsAreCollected() { - guard #available(iOS 13, *) else { + guard #available(iOS 13, tvOS 13, *) else { return } @@ -164,7 +164,7 @@ class ResourceMetricsTests: XCTestCase { } func testWhenTaskMakesFetchFromLocalCache_thenOnlyFetchMetricIsCollected() { - guard #available(iOS 13, *) else { + guard #available(iOS 13, tvOS 13, *) else { return } diff --git a/Tests/DatadogTests/Datadog/Utils/SwiftUIExtensionsTests.swift b/Tests/DatadogTests/Datadog/Utils/SwiftUIExtensionsTests.swift index cdc6f2d342..ce0d5af346 100644 --- a/Tests/DatadogTests/Datadog/Utils/SwiftUIExtensionsTests.swift +++ b/Tests/DatadogTests/Datadog/Utils/SwiftUIExtensionsTests.swift @@ -10,17 +10,17 @@ import XCTest import SwiftUI @testable import Datadog -@available(iOS 13, *) +@available(iOS 13, tvOS 13, *) class CustomHostingController: UIHostingController {} -@available(iOS 13, *) +@available(iOS 13, tvOS 13, *) final class TestView: View { var body = EmptyView() } class SwiftUIExtensionsTests: XCTestCase { func testSwiftUIViewTypeDescription() { - guard #available(iOS 13, *) else { + guard #available(iOS 13, tvOS 13, *) else { return } @@ -29,7 +29,7 @@ class SwiftUIExtensionsTests: XCTestCase { } func testBundleIsSwiftUI() { - guard #available(iOS 13, *) else { + guard #available(iOS 13, tvOS 13, *) else { return } diff --git a/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift b/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift index a3f83c9da8..d5502b4b29 100644 --- a/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift +++ b/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift @@ -149,8 +149,9 @@ class DDConfigurationTests: XCTestCase { objcBuilder.trackUIKitRUMViews(using: viewPredicate) XCTAssertTrue((objcBuilder.build().sdkConfiguration.rumUIKitViewsPredicate as? UIKitRUMViewsPredicateBridge)?.objcPredicate === viewPredicate) - class ObjCActionPredicate: DDUIKitRUMUserActionsPredicate { + class ObjCActionPredicate: DDUIKitRUMUserActionsPredicate & DDUITouchRUMUserActionsPredicate & DDUIPressRUMUserActionsPredicate { func rumAction(targetView: UIView) -> DDRUMAction? { nil } + func rumAction(press type: UIPress.PressType, targetView: UIView) -> DDRUMAction? { nil } } let actionPredicate = ObjCActionPredicate() objcBuilder.trackUIKitRUMActions(using: actionPredicate) diff --git a/Tests/DatadogTests/DatadogObjc/DDRUMMonitorTests.swift b/Tests/DatadogTests/DatadogObjc/DDRUMMonitorTests.swift index 7e051bfa39..435a347ace 100644 --- a/Tests/DatadogTests/DatadogObjc/DDRUMMonitorTests.swift +++ b/Tests/DatadogTests/DatadogObjc/DDRUMMonitorTests.swift @@ -38,8 +38,8 @@ class DDRUMViewTests: XCTestCase { } class UIKitRUMUserActionsPredicateBridgeTests: XCTestCase { - func testItForwardsCallToObjcPredicate() { - class MockPredicate: DDUIKitRUMUserActionsPredicate { + func testItForwardsCallToObjcTouchPredicate() { + class MockPredicate: DDUITouchRUMUserActionsPredicate { var didCallRUMAction = false func rumAction(targetView: UIView) -> DDRUMAction? { didCallRUMAction = true @@ -54,6 +54,23 @@ class UIKitRUMUserActionsPredicateBridgeTests: XCTestCase { XCTAssertTrue(objcPredicate.didCallRUMAction) } + + func testItForwardsCallToObjcPressPredicate() { + class MockPredicate: DDUIPressRUMUserActionsPredicate { + var didCallRUMAction = false + func rumAction(press: UIPress.PressType, targetView: UIView) -> DDRUMAction? { + didCallRUMAction = true + return nil + } + } + + let objcPredicate = MockPredicate() + + let predicateBridge = UIKitRUMUserActionsPredicateBridge(objcPredicate: objcPredicate) + _ = predicateBridge.rumAction(press: .select, targetView: UIView()) + + XCTAssertTrue(objcPredicate.didCallRUMAction) + } } class DDRUMActionTests: XCTestCase { diff --git a/Tests/DatadogTests/DatadogObjc/ObjcAPITests/DDConfiguration+apiTests.m b/Tests/DatadogTests/DatadogObjc/ObjcAPITests/DDConfiguration+apiTests.m index 9dbc42301f..30d1d9dcd0 100644 --- a/Tests/DatadogTests/DatadogObjc/ObjcAPITests/DDConfiguration+apiTests.m +++ b/Tests/DatadogTests/DatadogObjc/ObjcAPITests/DDConfiguration+apiTests.m @@ -30,6 +30,8 @@ @interface CustomDDUIKitRUMUserActionsPredicate () Default Configuration UISceneDelegateClassName $(PRODUCT_MODULE_NAME).SceneDelegate - UISceneStoryboardFile - Main - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main UIRequiredDeviceCapabilities armv7 diff --git a/dependency-manager-tests/spm/SPMProject/SceneDelegate.swift b/dependency-manager-tests/carthage/App/SceneDelegate.swift similarity index 74% rename from dependency-manager-tests/spm/SPMProject/SceneDelegate.swift rename to dependency-manager-tests/carthage/App/SceneDelegate.swift index c812c9793c..09f8e5a3ae 100644 --- a/dependency-manager-tests/spm/SPMProject/SceneDelegate.swift +++ b/dependency-manager-tests/carthage/App/SceneDelegate.swift @@ -10,6 +10,14 @@ internal class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + guard let windowScene = scene as? UIWindowScene else { + return + } + + let window = UIWindow(windowScene: windowScene) + window.rootViewController = ViewController() + self.window = window + window.makeKeyAndVisible() } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/dependency-manager-tests/carthage/CTProject/ViewController.swift b/dependency-manager-tests/carthage/App/ViewController.swift similarity index 79% rename from dependency-manager-tests/carthage/CTProject/ViewController.swift rename to dependency-manager-tests/carthage/App/ViewController.swift index 2e8416afae..7cf60e6efa 100644 --- a/dependency-manager-tests/carthage/CTProject/ViewController.swift +++ b/dependency-manager-tests/carthage/App/ViewController.swift @@ -35,5 +35,18 @@ internal class ViewController: UIViewController { // Start span, but never finish it (no upload) _ = Global.sharedTracer.startSpan(operationName: "This too") + + addLabel() + } + + private func addLabel() { + let label = UILabel() + label.autoresizingMask = [.flexibleWidth, .flexibleHeight] + view.addSubview(label) + + label.text = "Testing..." + label.textColor = .white + label.sizeToFit() + label.center = view.center } } diff --git a/dependency-manager-tests/carthage/CTProjectTests/CTProjectTests.swift b/dependency-manager-tests/carthage/AppTests/AppTests.swift similarity index 94% rename from dependency-manager-tests/carthage/CTProjectTests/CTProjectTests.swift rename to dependency-manager-tests/carthage/AppTests/AppTests.swift index 58380e7e60..29557b3131 100644 --- a/dependency-manager-tests/carthage/CTProjectTests/CTProjectTests.swift +++ b/dependency-manager-tests/carthage/AppTests/AppTests.swift @@ -5,7 +5,8 @@ */ import XCTest -@testable import CTProject + +@testable import App class CTProjectTests: XCTestCase { func testCallingLogicThatLoadsSDK() throws { diff --git a/dependency-manager-tests/carthage/CTProjectTests/Info.plist b/dependency-manager-tests/carthage/AppTests/Info.plist similarity index 100% rename from dependency-manager-tests/carthage/CTProjectTests/Info.plist rename to dependency-manager-tests/carthage/AppTests/Info.plist diff --git a/dependency-manager-tests/carthage/CTProjectUITests/CTProjectUITests.swift b/dependency-manager-tests/carthage/AppUITests/AppUITests.swift similarity index 100% rename from dependency-manager-tests/carthage/CTProjectUITests/CTProjectUITests.swift rename to dependency-manager-tests/carthage/AppUITests/AppUITests.swift diff --git a/dependency-manager-tests/carthage/CTProjectUITests/Info.plist b/dependency-manager-tests/carthage/AppUITests/Info.plist similarity index 100% rename from dependency-manager-tests/carthage/CTProjectUITests/Info.plist rename to dependency-manager-tests/carthage/AppUITests/Info.plist diff --git a/dependency-manager-tests/carthage/CTProject.xcodeproj/project.pbxproj b/dependency-manager-tests/carthage/CTProject.xcodeproj/project.pbxproj index 4a9312c4bd..e1157d8967 100644 --- a/dependency-manager-tests/carthage/CTProject.xcodeproj/project.pbxproj +++ b/dependency-manager-tests/carthage/CTProject.xcodeproj/project.pbxproj @@ -10,17 +10,27 @@ 61C36419243752A500C4D4E6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C36418243752A500C4D4E6 /* AppDelegate.swift */; }; 61C3641B243752A500C4D4E6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3641A243752A500C4D4E6 /* SceneDelegate.swift */; }; 61C3641D243752A500C4D4E6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3641C243752A500C4D4E6 /* ViewController.swift */; }; - 61C36420243752A500C4D4E6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61C3641E243752A500C4D4E6 /* Main.storyboard */; }; - 61C36425243752A600C4D4E6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61C36423243752A600C4D4E6 /* LaunchScreen.storyboard */; }; - 61C36430243752A600C4D4E6 /* CTProjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3642F243752A600C4D4E6 /* CTProjectTests.swift */; }; - 61C3643B243752A600C4D4E6 /* CTProjectUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3643A243752A600C4D4E6 /* CTProjectUITests.swift */; }; + 61C36430243752A600C4D4E6 /* AppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3642F243752A600C4D4E6 /* AppTests.swift */; }; + 61C3643B243752A600C4D4E6 /* AppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3643A243752A600C4D4E6 /* AppUITests.swift */; }; 9E9D5E8A25F90FC6002F12A0 /* DatadogObjc.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9D5E8625F90FC6002F12A0 /* DatadogObjc.xcframework */; }; 9E9D5E8B25F90FC6002F12A0 /* DatadogObjc.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9D5E8625F90FC6002F12A0 /* DatadogObjc.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9E9D5E8C25F90FC6002F12A0 /* Datadog.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9D5E8725F90FC6002F12A0 /* Datadog.xcframework */; }; 9E9D5E8D25F90FC6002F12A0 /* Datadog.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9D5E8725F90FC6002F12A0 /* Datadog.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9EF87B8C26B04E1F00998076 /* CrashReporter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 615D9E652604B5AB006DC6D1 /* CrashReporter.xcframework */; }; 9EF87B8D26B04E1F00998076 /* CrashReporter.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 615D9E652604B5AB006DC6D1 /* CrashReporter.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 9EF87B8E26B04E1F00998076 /* DatadogCrashReporting.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 615D9E6A2604B5B1006DC6D1 /* DatadogCrashReporting.xcframework */; }; + D24C2F7627CCDDAA001365B0 /* DatadogCrashReporting.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 615D9E6A2604B5B1006DC6D1 /* DatadogCrashReporting.xcframework */; }; + D290BA1B27CD09740019936D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3641C243752A500C4D4E6 /* ViewController.swift */; }; + D290BA1C27CD09740019936D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C36418243752A500C4D4E6 /* AppDelegate.swift */; }; + D290BA1D27CD09740019936D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3641A243752A500C4D4E6 /* SceneDelegate.swift */; }; + D290BA1F27CD09740019936D /* CrashReporter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 615D9E652604B5AB006DC6D1 /* CrashReporter.xcframework */; }; + D290BA2027CD09740019936D /* DatadogCrashReporting.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 615D9E6A2604B5B1006DC6D1 /* DatadogCrashReporting.xcframework */; }; + D290BA2127CD09740019936D /* Datadog.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9D5E8725F90FC6002F12A0 /* Datadog.xcframework */; }; + D290BA2227CD09740019936D /* DatadogObjc.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9D5E8625F90FC6002F12A0 /* DatadogObjc.xcframework */; }; + D290BA2627CD09740019936D /* CrashReporter.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 615D9E652604B5AB006DC6D1 /* CrashReporter.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D290BA2827CD09740019936D /* Datadog.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9D5E8725F90FC6002F12A0 /* Datadog.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D290BA2927CD09740019936D /* DatadogObjc.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9D5E8625F90FC6002F12A0 /* DatadogObjc.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D290BA3327CD09A20019936D /* AppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3642F243752A600C4D4E6 /* AppTests.swift */; }; + D290BA3F27CD09C70019936D /* AppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C3643A243752A600C4D4E6 /* AppUITests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -38,6 +48,20 @@ remoteGlobalIDString = 61C36414243752A500C4D4E6; remoteInfo = CTProject; }; + D290BA4727CD09EC0019936D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61C3640D243752A500C4D4E6 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D290BA1927CD09740019936D; + remoteInfo = "App tvOS"; + }; + D290BA4927CD09F00019936D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61C3640D243752A500C4D4E6 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D290BA1927CD09740019936D; + remoteInfo = "App tvOS"; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -54,6 +78,19 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; + D290BA2527CD09740019936D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + D290BA2627CD09740019936D /* CrashReporter.xcframework in Embed Frameworks */, + D290BA2827CD09740019936D /* Datadog.xcframework in Embed Frameworks */, + D290BA2927CD09740019936D /* DatadogObjc.xcframework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -61,22 +98,23 @@ 615519332461CDB4002A85CF /* Datadog.local.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Datadog.local.xcconfig; sourceTree = ""; }; 615D9E652604B5AB006DC6D1 /* CrashReporter.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = CrashReporter.xcframework; path = Carthage/Build/CrashReporter.xcframework; sourceTree = ""; }; 615D9E6A2604B5B1006DC6D1 /* DatadogCrashReporting.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = DatadogCrashReporting.xcframework; path = Carthage/Build/DatadogCrashReporting.xcframework; sourceTree = ""; }; - 61C36415243752A500C4D4E6 /* CTProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CTProject.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 61C36415243752A500C4D4E6 /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; 61C36418243752A500C4D4E6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 61C3641A243752A500C4D4E6 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 61C3641C243752A500C4D4E6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 61C3641F243752A500C4D4E6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 61C36424243752A600C4D4E6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 61C36426243752A600C4D4E6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 61C3642B243752A600C4D4E6 /* CTProjectTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CTProjectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 61C3642F243752A600C4D4E6 /* CTProjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTProjectTests.swift; sourceTree = ""; }; + 61C3642B243752A600C4D4E6 /* App iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 61C3642F243752A600C4D4E6 /* AppTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTests.swift; sourceTree = ""; }; 61C36431243752A600C4D4E6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 61C36436243752A600C4D4E6 /* CTProjectUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CTProjectUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 61C3643A243752A600C4D4E6 /* CTProjectUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTProjectUITests.swift; sourceTree = ""; }; + 61C36436243752A600C4D4E6 /* App iOS UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App iOS UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 61C3643A243752A600C4D4E6 /* AppUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUITests.swift; sourceTree = ""; }; 61C3643C243752A600C4D4E6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9E9D5E8525F90FC6002F12A0 /* Kronos.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Kronos.xcframework; path = Carthage/Build/Kronos.xcframework; sourceTree = ""; }; 9E9D5E8625F90FC6002F12A0 /* DatadogObjc.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = DatadogObjc.xcframework; path = Carthage/Build/DatadogObjc.xcframework; sourceTree = ""; }; 9E9D5E8725F90FC6002F12A0 /* Datadog.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Datadog.xcframework; path = Carthage/Build/Datadog.xcframework; sourceTree = ""; }; + D290BA2D27CD09740019936D /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; + D290BA3927CD09A20019936D /* App tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + D290BA4527CD09C70019936D /* App tvOS UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App tvOS UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,9 +123,9 @@ buildActionMask = 2147483647; files = ( 9EF87B8C26B04E1F00998076 /* CrashReporter.xcframework in Frameworks */, + D24C2F7627CCDDAA001365B0 /* DatadogCrashReporting.xcframework in Frameworks */, 9E9D5E8C25F90FC6002F12A0 /* Datadog.xcframework in Frameworks */, 9E9D5E8A25F90FC6002F12A0 /* DatadogObjc.xcframework in Frameworks */, - 9EF87B8E26B04E1F00998076 /* DatadogCrashReporting.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -105,6 +143,31 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D290BA1E27CD09740019936D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D290BA1F27CD09740019936D /* CrashReporter.xcframework in Frameworks */, + D290BA2027CD09740019936D /* DatadogCrashReporting.xcframework in Frameworks */, + D290BA2127CD09740019936D /* Datadog.xcframework in Frameworks */, + D290BA2227CD09740019936D /* DatadogObjc.xcframework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D290BA3427CD09A20019936D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D290BA4027CD09C70019936D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -122,9 +185,9 @@ isa = PBXGroup; children = ( 615519312461CDB4002A85CF /* xcconfigs */, - 61C36417243752A500C4D4E6 /* CTProject */, - 61C3642E243752A600C4D4E6 /* CTProjectTests */, - 61C36439243752A600C4D4E6 /* CTProjectUITests */, + 61C36417243752A500C4D4E6 /* App */, + 61C3642E243752A600C4D4E6 /* AppTests */, + 61C36439243752A600C4D4E6 /* AppUITests */, 61C36416243752A500C4D4E6 /* Products */, 61C364492437547A00C4D4E6 /* Frameworks */, ); @@ -133,42 +196,43 @@ 61C36416243752A500C4D4E6 /* Products */ = { isa = PBXGroup; children = ( - 61C36415243752A500C4D4E6 /* CTProject.app */, - 61C3642B243752A600C4D4E6 /* CTProjectTests.xctest */, - 61C36436243752A600C4D4E6 /* CTProjectUITests.xctest */, + 61C36415243752A500C4D4E6 /* App.app */, + 61C3642B243752A600C4D4E6 /* App iOS Tests.xctest */, + 61C36436243752A600C4D4E6 /* App iOS UITests.xctest */, + D290BA2D27CD09740019936D /* App.app */, + D290BA3927CD09A20019936D /* App tvOS Tests.xctest */, + D290BA4527CD09C70019936D /* App tvOS UITests.xctest */, ); name = Products; sourceTree = ""; }; - 61C36417243752A500C4D4E6 /* CTProject */ = { + 61C36417243752A500C4D4E6 /* App */ = { isa = PBXGroup; children = ( 61C36418243752A500C4D4E6 /* AppDelegate.swift */, 61C3641A243752A500C4D4E6 /* SceneDelegate.swift */, 61C3641C243752A500C4D4E6 /* ViewController.swift */, - 61C3641E243752A500C4D4E6 /* Main.storyboard */, - 61C36423243752A600C4D4E6 /* LaunchScreen.storyboard */, 61C36426243752A600C4D4E6 /* Info.plist */, ); - path = CTProject; + path = App; sourceTree = ""; }; - 61C3642E243752A600C4D4E6 /* CTProjectTests */ = { + 61C3642E243752A600C4D4E6 /* AppTests */ = { isa = PBXGroup; children = ( - 61C3642F243752A600C4D4E6 /* CTProjectTests.swift */, + 61C3642F243752A600C4D4E6 /* AppTests.swift */, 61C36431243752A600C4D4E6 /* Info.plist */, ); - path = CTProjectTests; + path = AppTests; sourceTree = ""; }; - 61C36439243752A600C4D4E6 /* CTProjectUITests */ = { + 61C36439243752A600C4D4E6 /* AppUITests */ = { isa = PBXGroup; children = ( - 61C3643A243752A600C4D4E6 /* CTProjectUITests.swift */, + 61C3643A243752A600C4D4E6 /* AppUITests.swift */, 61C3643C243752A600C4D4E6 /* Info.plist */, ); - path = CTProjectUITests; + path = AppUITests; sourceTree = ""; }; 61C364492437547A00C4D4E6 /* Frameworks */ = { @@ -186,9 +250,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 61C36414243752A500C4D4E6 /* CTProject */ = { + 61C36414243752A500C4D4E6 /* App iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 61C3643F243752A600C4D4E6 /* Build configuration list for PBXNativeTarget "CTProject" */; + buildConfigurationList = 61C3643F243752A600C4D4E6 /* Build configuration list for PBXNativeTarget "App iOS" */; buildPhases = ( 61C36411243752A500C4D4E6 /* Sources */, 61C36412243752A500C4D4E6 /* Frameworks */, @@ -200,14 +264,14 @@ ); dependencies = ( ); - name = CTProject; + name = "App iOS"; productName = CTProject; - productReference = 61C36415243752A500C4D4E6 /* CTProject.app */; + productReference = 61C36415243752A500C4D4E6 /* App.app */; productType = "com.apple.product-type.application"; }; - 61C3642A243752A600C4D4E6 /* CTProjectTests */ = { + 61C3642A243752A600C4D4E6 /* App iOS Tests */ = { isa = PBXNativeTarget; - buildConfigurationList = 61C36442243752A600C4D4E6 /* Build configuration list for PBXNativeTarget "CTProjectTests" */; + buildConfigurationList = 61C36442243752A600C4D4E6 /* Build configuration list for PBXNativeTarget "App iOS Tests" */; buildPhases = ( 61C36427243752A600C4D4E6 /* Sources */, 61C36428243752A600C4D4E6 /* Frameworks */, @@ -218,14 +282,14 @@ dependencies = ( 61C3642D243752A600C4D4E6 /* PBXTargetDependency */, ); - name = CTProjectTests; + name = "App iOS Tests"; productName = CTProjectTests; - productReference = 61C3642B243752A600C4D4E6 /* CTProjectTests.xctest */; + productReference = 61C3642B243752A600C4D4E6 /* App iOS Tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 61C36435243752A600C4D4E6 /* CTProjectUITests */ = { + 61C36435243752A600C4D4E6 /* App iOS UITests */ = { isa = PBXNativeTarget; - buildConfigurationList = 61C36445243752A600C4D4E6 /* Build configuration list for PBXNativeTarget "CTProjectUITests" */; + buildConfigurationList = 61C36445243752A600C4D4E6 /* Build configuration list for PBXNativeTarget "App iOS UITests" */; buildPhases = ( 61C36432243752A600C4D4E6 /* Sources */, 61C36433243752A600C4D4E6 /* Frameworks */, @@ -236,9 +300,64 @@ dependencies = ( 61C36438243752A600C4D4E6 /* PBXTargetDependency */, ); - name = CTProjectUITests; + name = "App iOS UITests"; + productName = CTProjectUITests; + productReference = 61C36436243752A600C4D4E6 /* App iOS UITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + D290BA1927CD09740019936D /* App tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D290BA2A27CD09740019936D /* Build configuration list for PBXNativeTarget "App tvOS" */; + buildPhases = ( + D290BA1A27CD09740019936D /* Sources */, + D290BA1E27CD09740019936D /* Frameworks */, + D290BA2327CD09740019936D /* Resources */, + D290BA2427CD09740019936D /* ⚙️ Run linter */, + D290BA2527CD09740019936D /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "App tvOS"; + productName = CTProject; + productReference = D290BA2D27CD09740019936D /* App.app */; + productType = "com.apple.product-type.application"; + }; + D290BA2F27CD09A20019936D /* App tvOS Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D290BA3627CD09A20019936D /* Build configuration list for PBXNativeTarget "App tvOS Tests" */; + buildPhases = ( + D290BA3227CD09A20019936D /* Sources */, + D290BA3427CD09A20019936D /* Frameworks */, + D290BA3527CD09A20019936D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D290BA4A27CD09F00019936D /* PBXTargetDependency */, + ); + name = "App tvOS Tests"; + productName = CTProjectTests; + productReference = D290BA3927CD09A20019936D /* App tvOS Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + D290BA3B27CD09C70019936D /* App tvOS UITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D290BA4227CD09C70019936D /* Build configuration list for PBXNativeTarget "App tvOS UITests" */; + buildPhases = ( + D290BA3E27CD09C70019936D /* Sources */, + D290BA4027CD09C70019936D /* Frameworks */, + D290BA4127CD09C70019936D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D290BA4827CD09EC0019936D /* PBXTargetDependency */, + ); + name = "App tvOS UITests"; productName = CTProjectUITests; - productReference = 61C36436243752A600C4D4E6 /* CTProjectUITests.xctest */; + productReference = D290BA4527CD09C70019936D /* App tvOS UITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; /* End PBXNativeTarget section */ @@ -248,7 +367,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1140; - LastUpgradeCheck = 1140; + LastUpgradeCheck = 1310; ORGANIZATIONNAME = Datadog; TargetAttributes = { 61C36414243752A500C4D4E6 = { @@ -262,6 +381,12 @@ CreatedOnToolsVersion = 11.4; TestTargetID = 61C36414243752A500C4D4E6; }; + D290BA2F27CD09A20019936D = { + TestTargetID = D290BA1927CD09740019936D; + }; + D290BA3B27CD09C70019936D = { + TestTargetID = D290BA1927CD09740019936D; + }; }; }; buildConfigurationList = 61C36410243752A500C4D4E6 /* Build configuration list for PBXProject "CTProject" */; @@ -277,9 +402,12 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 61C36414243752A500C4D4E6 /* CTProject */, - 61C3642A243752A600C4D4E6 /* CTProjectTests */, - 61C36435243752A600C4D4E6 /* CTProjectUITests */, + 61C36414243752A500C4D4E6 /* App iOS */, + 61C3642A243752A600C4D4E6 /* App iOS Tests */, + 61C36435243752A600C4D4E6 /* App iOS UITests */, + D290BA1927CD09740019936D /* App tvOS */, + D290BA2F27CD09A20019936D /* App tvOS Tests */, + D290BA3B27CD09C70019936D /* App tvOS UITests */, ); }; /* End PBXProject section */ @@ -289,8 +417,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61C36425243752A600C4D4E6 /* LaunchScreen.storyboard in Resources */, - 61C36420243752A500C4D4E6 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -308,6 +434,27 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D290BA2327CD09740019936D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D290BA3527CD09A20019936D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D290BA4127CD09C70019936D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -330,6 +477,25 @@ shellScript = "if which swiftlint >/dev/null; then\n cd ${SOURCE_ROOT}/../../\n ./tools/lint/run-linter.sh\nfi\n"; showEnvVarsInLog = 0; }; + D290BA2427CD09740019936D /* ⚙️ Run linter */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "⚙️ Run linter"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\n cd ${SOURCE_ROOT}/../../\n ./tools/lint/run-linter.sh\nfi\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -347,7 +513,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61C36430243752A600C4D4E6 /* CTProjectTests.swift in Sources */, + 61C36430243752A600C4D4E6 /* AppTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -355,7 +521,33 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61C3643B243752A600C4D4E6 /* CTProjectUITests.swift in Sources */, + 61C3643B243752A600C4D4E6 /* AppUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D290BA1A27CD09740019936D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D290BA1B27CD09740019936D /* ViewController.swift in Sources */, + D290BA1C27CD09740019936D /* AppDelegate.swift in Sources */, + D290BA1D27CD09740019936D /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D290BA3227CD09A20019936D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D290BA3327CD09A20019936D /* AppTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D290BA3E27CD09C70019936D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D290BA3F27CD09C70019936D /* AppUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -364,34 +556,25 @@ /* Begin PBXTargetDependency section */ 61C3642D243752A600C4D4E6 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61C36414243752A500C4D4E6 /* CTProject */; + target = 61C36414243752A500C4D4E6 /* App iOS */; targetProxy = 61C3642C243752A600C4D4E6 /* PBXContainerItemProxy */; }; 61C36438243752A600C4D4E6 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61C36414243752A500C4D4E6 /* CTProject */; + target = 61C36414243752A500C4D4E6 /* App iOS */; targetProxy = 61C36437243752A600C4D4E6 /* PBXContainerItemProxy */; }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 61C3641E243752A500C4D4E6 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 61C3641F243752A500C4D4E6 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; + D290BA4827CD09EC0019936D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D290BA1927CD09740019936D /* App tvOS */; + targetProxy = D290BA4727CD09EC0019936D /* PBXContainerItemProxy */; }; - 61C36423243752A600C4D4E6 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 61C36424243752A600C4D4E6 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; + D290BA4A27CD09F00019936D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D290BA1927CD09740019936D /* App tvOS */; + targetProxy = D290BA4927CD09F00019936D /* PBXContainerItemProxy */; }; -/* End PBXVariantGroup section */ +/* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 61C3643D243752A600C4D4E6 /* Debug */ = { @@ -421,6 +604,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -452,6 +636,7 @@ SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TVOS_DEPLOYMENT_TARGET = 13.0; VALIDATE_WORKSPACE = YES; }; name = Debug; @@ -483,6 +668,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -507,6 +693,7 @@ SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; + TVOS_DEPLOYMENT_TARGET = 13.0; VALIDATE_PRODUCT = YES; VALIDATE_WORKSPACE = YES; }; @@ -517,13 +704,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = CTProject/Info.plist; + INFOPLIST_FILE = App/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.CTProject; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = App; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -534,13 +721,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = CTProject/Info.plist; + INFOPLIST_FILE = App/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.CTProject; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = App; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -552,7 +739,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = CTProjectTests/Info.plist; + INFOPLIST_FILE = AppTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -562,7 +749,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CTProject.app/CTProject"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; }; name = Debug; }; @@ -572,7 +759,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = CTProjectTests/Info.plist; + INFOPLIST_FILE = AppTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -582,7 +769,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CTProject.app/CTProject"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; }; name = Release; }; @@ -591,7 +778,7 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = CTProjectUITests/Info.plist; + INFOPLIST_FILE = AppUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -610,7 +797,7 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = CTProjectUITests/Info.plist; + INFOPLIST_FILE = AppUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -624,6 +811,118 @@ }; name = Release; }; + D290BA2B27CD09740019936D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = App/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.CTProject; + PRODUCT_NAME = App; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + D290BA2C27CD09740019936D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = App/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.CTProject; + PRODUCT_NAME = App; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + D290BA3727CD09A20019936D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = AppTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.CTProjectTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; + }; + name = Debug; + }; + D290BA3827CD09A20019936D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = AppTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.CTProjectTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; + }; + name = Release; + }; + D290BA4327CD09C70019936D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = AppUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.CTProjectUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = "App tvOS"; + }; + name = Debug; + }; + D290BA4427CD09C70019936D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = AppUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.CTProjectUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = "App tvOS"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -636,7 +935,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61C3643F243752A600C4D4E6 /* Build configuration list for PBXNativeTarget "CTProject" */ = { + 61C3643F243752A600C4D4E6 /* Build configuration list for PBXNativeTarget "App iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 61C36440243752A600C4D4E6 /* Debug */, @@ -645,7 +944,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61C36442243752A600C4D4E6 /* Build configuration list for PBXNativeTarget "CTProjectTests" */ = { + 61C36442243752A600C4D4E6 /* Build configuration list for PBXNativeTarget "App iOS Tests" */ = { isa = XCConfigurationList; buildConfigurations = ( 61C36443243752A600C4D4E6 /* Debug */, @@ -654,7 +953,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61C36445243752A600C4D4E6 /* Build configuration list for PBXNativeTarget "CTProjectUITests" */ = { + 61C36445243752A600C4D4E6 /* Build configuration list for PBXNativeTarget "App iOS UITests" */ = { isa = XCConfigurationList; buildConfigurations = ( 61C36446243752A600C4D4E6 /* Debug */, @@ -663,6 +962,33 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + D290BA2A27CD09740019936D /* Build configuration list for PBXNativeTarget "App tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D290BA2B27CD09740019936D /* Debug */, + D290BA2C27CD09740019936D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D290BA3627CD09A20019936D /* Build configuration list for PBXNativeTarget "App tvOS Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D290BA3727CD09A20019936D /* Debug */, + D290BA3827CD09A20019936D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D290BA4227CD09C70019936D /* Build configuration list for PBXNativeTarget "App tvOS UITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D290BA4327CD09C70019936D /* Debug */, + D290BA4427CD09C70019936D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 61C3640D243752A500C4D4E6 /* Project object */; diff --git a/dependency-manager-tests/carthage/CTProject.xcodeproj/xcshareddata/xcschemes/App iOS.xcscheme b/dependency-manager-tests/carthage/CTProject.xcodeproj/xcshareddata/xcschemes/App iOS.xcscheme new file mode 100644 index 0000000000..ad41d37b29 --- /dev/null +++ b/dependency-manager-tests/carthage/CTProject.xcodeproj/xcshareddata/xcschemes/App iOS.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dependency-manager-tests/carthage/CTProject.xcodeproj/xcshareddata/xcschemes/App tvOS.xcscheme b/dependency-manager-tests/carthage/CTProject.xcodeproj/xcshareddata/xcschemes/App tvOS.xcscheme new file mode 100644 index 0000000000..b4a4c83563 --- /dev/null +++ b/dependency-manager-tests/carthage/CTProject.xcodeproj/xcshareddata/xcschemes/App tvOS.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dependency-manager-tests/carthage/CTProject/Base.lproj/LaunchScreen.storyboard b/dependency-manager-tests/carthage/CTProject/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 865e9329f3..0000000000 --- a/dependency-manager-tests/carthage/CTProject/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dependency-manager-tests/carthage/CTProject/Base.lproj/Main.storyboard b/dependency-manager-tests/carthage/CTProject/Base.lproj/Main.storyboard deleted file mode 100644 index fbb30ef19f..0000000000 --- a/dependency-manager-tests/carthage/CTProject/Base.lproj/Main.storyboard +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dependency-manager-tests/carthage/Makefile b/dependency-manager-tests/carthage/Makefile index bd97559c06..9bed8e6243 100644 --- a/dependency-manager-tests/carthage/Makefile +++ b/dependency-manager-tests/carthage/Makefile @@ -18,7 +18,7 @@ test: sed "s|GIT_REMOTE|${GIT_REMOTE}|g" > Cartfile @rm -rf Carthage/ @echo "🧪 Run 'carthage update'" - @carthage update --platform iOS --use-xcframeworks + @carthage update --platform iOS,tvOS --use-xcframeworks @echo "🧪 Check if expected frameworks exist in $(PWD)/Carthage/Build/" @[ -e "Carthage/Build/Datadog.xcframework" ] && echo "Datadog.xcframework - OK" || { echo "Datadog.xcframework - missing"; false; } @[ -e "Carthage/Build/DatadogObjc.xcframework" ] && echo "DatadogObjc.xcframework - OK" || { echo "DatadogObjc.xcframework - missing"; false; } diff --git a/dependency-manager-tests/cocoapods/CPProject/AppDelegate.swift b/dependency-manager-tests/cocoapods/App/AppDelegate.swift similarity index 100% rename from dependency-manager-tests/cocoapods/CPProject/AppDelegate.swift rename to dependency-manager-tests/cocoapods/App/AppDelegate.swift diff --git a/dependency-manager-tests/cocoapods/CPProject/Info.plist b/dependency-manager-tests/cocoapods/App/Info.plist similarity index 90% rename from dependency-manager-tests/cocoapods/CPProject/Info.plist rename to dependency-manager-tests/cocoapods/App/Info.plist index 5b531f7b27..e8155e136e 100644 --- a/dependency-manager-tests/cocoapods/CPProject/Info.plist +++ b/dependency-manager-tests/cocoapods/App/Info.plist @@ -33,18 +33,12 @@ Default Configuration UISceneDelegateClassName $(PRODUCT_MODULE_NAME).SceneDelegate - UISceneStoryboardFile - Main UIApplicationSupportsIndirectInputEvents - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main UIRequiredDeviceCapabilities armv7 diff --git a/dependency-manager-tests/carthage/CTProject/SceneDelegate.swift b/dependency-manager-tests/cocoapods/App/SceneDelegate.swift similarity index 74% rename from dependency-manager-tests/carthage/CTProject/SceneDelegate.swift rename to dependency-manager-tests/cocoapods/App/SceneDelegate.swift index c812c9793c..09f8e5a3ae 100644 --- a/dependency-manager-tests/carthage/CTProject/SceneDelegate.swift +++ b/dependency-manager-tests/cocoapods/App/SceneDelegate.swift @@ -10,6 +10,14 @@ internal class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + guard let windowScene = scene as? UIWindowScene else { + return + } + + let window = UIWindow(windowScene: windowScene) + window.rootViewController = ViewController() + self.window = window + window.makeKeyAndVisible() } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/dependency-manager-tests/cocoapods/CPProject/ViewController.swift b/dependency-manager-tests/cocoapods/App/ViewController.swift similarity index 82% rename from dependency-manager-tests/cocoapods/CPProject/ViewController.swift rename to dependency-manager-tests/cocoapods/App/ViewController.swift index ca173aa038..a4eb958ec4 100644 --- a/dependency-manager-tests/cocoapods/CPProject/ViewController.swift +++ b/dependency-manager-tests/cocoapods/App/ViewController.swift @@ -39,6 +39,8 @@ internal class ViewController: UIViewController { Global.rum.startView(viewController: self) createInstrumentedAlamofireSession() + + addLabel() } private func createInstrumentedAlamofireSession() { @@ -47,4 +49,15 @@ internal class ViewController: UIViewController { eventMonitors: [DDEventMonitor()] ) } + + private func addLabel() { + let label = UILabel() + label.autoresizingMask = [.flexibleWidth, .flexibleHeight] + view.addSubview(label) + + label.text = "Testing..." + label.textColor = .white + label.sizeToFit() + label.center = view.center + } } diff --git a/dependency-manager-tests/cocoapods/CPProjectTests/CPProjectTests.swift b/dependency-manager-tests/cocoapods/AppTests/CPProjectTests.swift similarity index 78% rename from dependency-manager-tests/cocoapods/CPProjectTests/CPProjectTests.swift rename to dependency-manager-tests/cocoapods/AppTests/CPProjectTests.swift index 4f709bdb72..e13c5ad3f0 100644 --- a/dependency-manager-tests/cocoapods/CPProjectTests/CPProjectTests.swift +++ b/dependency-manager-tests/cocoapods/AppTests/CPProjectTests.swift @@ -5,11 +5,8 @@ */ import XCTest -#if COMPILING_FOR_USE_FRAMEWORKS -@testable import CPProjectUseFrameworks -#else -@testable import CPProjectNoUseFrameworks -#endif + +@testable import App class CPProjectTests: XCTestCase { func testCallingLogicThatLoadsSDK() throws { diff --git a/dependency-manager-tests/cocoapods/CPProjectTests/Info.plist b/dependency-manager-tests/cocoapods/AppTests/Info.plist similarity index 100% rename from dependency-manager-tests/cocoapods/CPProjectTests/Info.plist rename to dependency-manager-tests/cocoapods/AppTests/Info.plist diff --git a/dependency-manager-tests/cocoapods/CPProjectUITests/CPProjectUITests.swift b/dependency-manager-tests/cocoapods/AppUITests/CPProjectUITests.swift similarity index 100% rename from dependency-manager-tests/cocoapods/CPProjectUITests/CPProjectUITests.swift rename to dependency-manager-tests/cocoapods/AppUITests/CPProjectUITests.swift diff --git a/dependency-manager-tests/cocoapods/CPProjectUITests/Info.plist b/dependency-manager-tests/cocoapods/AppUITests/Info.plist similarity index 100% rename from dependency-manager-tests/cocoapods/CPProjectUITests/Info.plist rename to dependency-manager-tests/cocoapods/AppUITests/Info.plist diff --git a/dependency-manager-tests/cocoapods/CPProject.xcodeproj/project.pbxproj b/dependency-manager-tests/cocoapods/CPProject.xcodeproj/project.pbxproj index 102e2603c4..c1a092884a 100644 --- a/dependency-manager-tests/cocoapods/CPProject.xcodeproj/project.pbxproj +++ b/dependency-manager-tests/cocoapods/CPProject.xcodeproj/project.pbxproj @@ -7,23 +7,32 @@ objects = { /* Begin PBXBuildFile section */ - 2FF2A19F9C78FC98880874FF /* Pods_Common_CPProjectUseFrameworks.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 424F6BCFD46A729DA7F32FC9 /* Pods_Common_CPProjectUseFrameworks.framework */; }; + 2B2A0652E2BB31985CCA411B /* libPods-App Static iOS Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 88C7C5186A293C78E070E6CF /* libPods-App Static iOS Tests.a */; }; 61373B5926E0E7C900E0F46E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C30626E0E278006EDF53 /* AppDelegate.swift */; }; 61373B5A26E0E7CD00E0F46E /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C30826E0E278006EDF53 /* SceneDelegate.swift */; }; - 61373B5B26E0E7D100E0F46E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C30A26E0E278006EDF53 /* ViewController.swift */; }; - 61373B5C26E0E7D800E0F46E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61B8C30C26E0E278006EDF53 /* Main.storyboard */; }; - 61373B5E26E0E7DF00E0F46E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61B8C31126E0E27A006EDF53 /* LaunchScreen.storyboard */; }; 61373B5F26E0E7E400E0F46E /* CPProjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C31D26E0E27A006EDF53 /* CPProjectTests.swift */; }; 61373B6126E0EA2500E0F46E /* CPProjectUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C32826E0E27A006EDF53 /* CPProjectUITests.swift */; }; 61B8C30726E0E278006EDF53 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C30626E0E278006EDF53 /* AppDelegate.swift */; }; 61B8C30926E0E278006EDF53 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C30826E0E278006EDF53 /* SceneDelegate.swift */; }; - 61B8C30B26E0E278006EDF53 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C30A26E0E278006EDF53 /* ViewController.swift */; }; - 61B8C30E26E0E278006EDF53 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61B8C30C26E0E278006EDF53 /* Main.storyboard */; }; - 61B8C31326E0E27A006EDF53 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61B8C31126E0E27A006EDF53 /* LaunchScreen.storyboard */; }; 61B8C31E26E0E27A006EDF53 /* CPProjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C31D26E0E27A006EDF53 /* CPProjectTests.swift */; }; 61B8C32926E0E27A006EDF53 /* CPProjectUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C32826E0E27A006EDF53 /* CPProjectUITests.swift */; }; - A154B5926600D17ECDD21D84 /* libPods-CPProjectNoUseFrameworksTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B2DA1BBBF19485F5F93D1E62 /* libPods-CPProjectNoUseFrameworksTests.a */; }; - FB53D921A5A47E18B605B20B /* libPods-Common-CPProjectNoUseFrameworks.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 99AEBB22D577EFFA7CED4C35 /* libPods-Common-CPProjectNoUseFrameworks.a */; }; + A0DBB7E71DD4888837ED81B5 /* Pods_Common_App_Dynamic_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8CCD75AF46655F78F7A3D7A /* Pods_Common_App_Dynamic_iOS.framework */; }; + B162FE141838120027D821F9 /* libPods-Common-App Static iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C285D46A1E0E371443F0F77 /* libPods-Common-App Static iOS.a */; }; + CCA17085193225EE98A8B997 /* Pods_Common_App_Dynamic_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F08D599966036C2B51829AB /* Pods_Common_App_Dynamic_tvOS.framework */; }; + D235937A27C8EB0500BF32D7 /* CPProjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C31D26E0E27A006EDF53 /* CPProjectTests.swift */; }; + D235938927C8ECD800BF32D7 /* CPProjectUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C32826E0E27A006EDF53 /* CPProjectUITests.swift */; }; + D245424627C8D3200039E0A6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C30626E0E278006EDF53 /* AppDelegate.swift */; }; + D245424727C8D3200039E0A6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C30826E0E278006EDF53 /* SceneDelegate.swift */; }; + D245425727C8DE3D0039E0A6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D245425627C8DE3D0039E0A6 /* ViewController.swift */; }; + D245425827C8DE3D0039E0A6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D245425627C8DE3D0039E0A6 /* ViewController.swift */; }; + D245425927C8DE3D0039E0A6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D245425627C8DE3D0039E0A6 /* ViewController.swift */; }; + D245425E27C8E1940039E0A6 /* CPProjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C31D26E0E27A006EDF53 /* CPProjectTests.swift */; }; + D245426C27C8E52F0039E0A6 /* CPProjectUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C32826E0E27A006EDF53 /* CPProjectUITests.swift */; }; + D245427927C8E93D0039E0A6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D245425627C8DE3D0039E0A6 /* ViewController.swift */; }; + D245427A27C8E93D0039E0A6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C30626E0E278006EDF53 /* AppDelegate.swift */; }; + D245427B27C8E93D0039E0A6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B8C30826E0E278006EDF53 /* SceneDelegate.swift */; }; + E7FDF9193D8912E2B49A5B99 /* libPods-Common-App Static tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6120B36BC669A3227C25B90F /* libPods-Common-App Static tvOS.a */; }; + EC38782925CC4D95E5F3536F /* libPods-App Static tvOS Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CA325D6A1605874914378E3E /* libPods-App Static tvOS Tests.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -55,42 +64,101 @@ remoteGlobalIDString = 61B8C30226E0E278006EDF53; remoteInfo = CPProject; }; + D235938327C8EC0900BF32D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61B8C2FB26E0E278006EDF53 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D245427627C8E93D0039E0A6; + remoteInfo = "CPProjectNoUseFrameworks tvOS"; + }; + D235939127C8ECE000BF32D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61B8C2FB26E0E278006EDF53 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D245427627C8E93D0039E0A6; + remoteInfo = "CPProjectNoUseFrameworks tvOS"; + }; + D245426627C8E4CD0039E0A6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61B8C2FB26E0E278006EDF53 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D245424227C8D3200039E0A6; + remoteInfo = "CPProjectUseFrameworks tvOS"; + }; + D245427427C8E5870039E0A6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61B8C2FB26E0E278006EDF53 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D245424227C8D3200039E0A6; + remoteInfo = "CPProjectUseFrameworks tvOS"; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 01FD54C4011C8F113E285585 /* Pods-Common-CPProjectNoUseFrameworks.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectNoUseFrameworks.debug.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectNoUseFrameworks/Pods-Common-CPProjectNoUseFrameworks.debug.xcconfig"; sourceTree = ""; }; 02265FB44AE08BD3D3454745 /* Pods-CPProjectNoUseFrameworksTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CPProjectNoUseFrameworksTests.release.xcconfig"; path = "Target Support Files/Pods-CPProjectNoUseFrameworksTests/Pods-CPProjectNoUseFrameworksTests.release.xcconfig"; sourceTree = ""; }; 0614566C30EF2E2D7BAF1117 /* Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksTests.debug.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksTests/Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksTests.debug.xcconfig"; sourceTree = ""; }; + 0C5EA8849018376E6D2BD2F7 /* Pods-Common-CPProjectNoUseFrameworks iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectNoUseFrameworks iOS.release.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectNoUseFrameworks iOS/Pods-Common-CPProjectNoUseFrameworks iOS.release.xcconfig"; sourceTree = ""; }; 17E75BD7BB8D512DB90A9632 /* Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksTests.release.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksTests/Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksTests.release.xcconfig"; sourceTree = ""; }; + 1AD1AA0F4E331947CD53AB1D /* Pods-Common-App Dynamic tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-App Dynamic tvOS.debug.xcconfig"; path = "Target Support Files/Pods-Common-App Dynamic tvOS/Pods-Common-App Dynamic tvOS.debug.xcconfig"; sourceTree = ""; }; 1F5643EF45F5157D39302AB4 /* Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksTests.debug.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksTests/Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksTests.debug.xcconfig"; sourceTree = ""; }; + 3468D63D65BB427B2C213235 /* Pods-Common-CPProjectUseFrameworks tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectUseFrameworks tvOS.debug.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectUseFrameworks tvOS/Pods-Common-CPProjectUseFrameworks tvOS.debug.xcconfig"; sourceTree = ""; }; + 34E3A05F52DE9374E351C695 /* Pods-CPProjectNoUseFrameworksTests tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CPProjectNoUseFrameworksTests tvOS.debug.xcconfig"; path = "Target Support Files/Pods-CPProjectNoUseFrameworksTests tvOS/Pods-CPProjectNoUseFrameworksTests tvOS.debug.xcconfig"; sourceTree = ""; }; + 3668B0235369E05E329D8F21 /* Pods-Common-App Static tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-App Static tvOS.release.xcconfig"; path = "Target Support Files/Pods-Common-App Static tvOS/Pods-Common-App Static tvOS.release.xcconfig"; sourceTree = ""; }; + 3C285D46A1E0E371443F0F77 /* libPods-Common-App Static iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Common-App Static iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 3D97712BEE25C98C566E565A /* Pods-Common-CPProjectNoUseFrameworks.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectNoUseFrameworks.release.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectNoUseFrameworks/Pods-Common-CPProjectNoUseFrameworks.release.xcconfig"; sourceTree = ""; }; - 424F6BCFD46A729DA7F32FC9 /* Pods_Common_CPProjectUseFrameworks.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Common_CPProjectUseFrameworks.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 44638027D4B88B41A7A1B240 /* Pods-Common-App Static tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-App Static tvOS.debug.xcconfig"; path = "Target Support Files/Pods-Common-App Static tvOS/Pods-Common-App Static tvOS.debug.xcconfig"; sourceTree = ""; }; + 47B2FAD72A07C0E26A7C1031 /* Pods-Common-CPProjectUseFrameworks iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectUseFrameworks iOS.release.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectUseFrameworks iOS/Pods-Common-CPProjectUseFrameworks iOS.release.xcconfig"; sourceTree = ""; }; + 4F7B559D3C166C35B42FCC87 /* Pods-Common-App Dynamic iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-App Dynamic iOS.release.xcconfig"; path = "Target Support Files/Pods-Common-App Dynamic iOS/Pods-Common-App Dynamic iOS.release.xcconfig"; sourceTree = ""; }; 51776B4903CB23F278458BB6 /* Pods-CPProjectNoUseFrameworksTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CPProjectNoUseFrameworksTests.debug.xcconfig"; path = "Target Support Files/Pods-CPProjectNoUseFrameworksTests/Pods-CPProjectNoUseFrameworksTests.debug.xcconfig"; sourceTree = ""; }; + 5514B2793CD3F4967A63A825 /* Pods-Common-CPProjectNoUseFrameworks tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectNoUseFrameworks tvOS.release.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectNoUseFrameworks tvOS/Pods-Common-CPProjectNoUseFrameworks tvOS.release.xcconfig"; sourceTree = ""; }; 586B9607FFDD69DAD0C23F22 /* Pods-Common-CPProjectUseFrameworks.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectUseFrameworks.debug.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectUseFrameworks/Pods-Common-CPProjectUseFrameworks.debug.xcconfig"; sourceTree = ""; }; - 61373B2926E0E78300E0F46E /* CPProjectNoUseFrameworks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CPProjectNoUseFrameworks.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 61373B3E26E0E78500E0F46E /* CPProjectNoUseFrameworksTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CPProjectNoUseFrameworksTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 61373B4926E0E78500E0F46E /* CPProjectNoUseFrameworksUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CPProjectNoUseFrameworksUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 61B8C30326E0E278006EDF53 /* CPProjectUseFrameworks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CPProjectUseFrameworks.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 6120B36BC669A3227C25B90F /* libPods-Common-App Static tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Common-App Static tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 61373B2926E0E78300E0F46E /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 61373B3E26E0E78500E0F46E /* App Static iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App Static iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 61373B4926E0E78500E0F46E /* App Static iOS UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App Static iOS UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 61B8C30326E0E278006EDF53 /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; 61B8C30626E0E278006EDF53 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 61B8C30826E0E278006EDF53 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - 61B8C30A26E0E278006EDF53 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 61B8C30D26E0E278006EDF53 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 61B8C31226E0E27A006EDF53 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 61B8C31426E0E27A006EDF53 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 61B8C31926E0E27A006EDF53 /* CPProjectUseFrameworksTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CPProjectUseFrameworksTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 61B8C31926E0E27A006EDF53 /* App Dynamic iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App Dynamic iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 61B8C31D26E0E27A006EDF53 /* CPProjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CPProjectTests.swift; sourceTree = ""; }; 61B8C31F26E0E27A006EDF53 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 61B8C32426E0E27A006EDF53 /* CPProjectUseFrameworksUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CPProjectUseFrameworksUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 61B8C32426E0E27A006EDF53 /* App Dynamic iOS UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App Dynamic iOS UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 61B8C32826E0E27A006EDF53 /* CPProjectUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CPProjectUITests.swift; sourceTree = ""; }; 61B8C32A26E0E27A006EDF53 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 693132861010BF05192CAE5A /* Pods-App Static iOS Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App Static iOS Tests.debug.xcconfig"; path = "Target Support Files/Pods-App Static iOS Tests/Pods-App Static iOS Tests.debug.xcconfig"; sourceTree = ""; }; + 6F08D599966036C2B51829AB /* Pods_Common_App_Dynamic_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Common_App_Dynamic_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7BC8294072C54F7BAD098B99 /* Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksUITests.debug.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksUITests/Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksUITests.debug.xcconfig"; sourceTree = ""; }; 811F6A3208073739F8E4C83E /* Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksTests.release.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksTests/Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksTests.release.xcconfig"; sourceTree = ""; }; + 88C7C5186A293C78E070E6CF /* libPods-App Static iOS Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-App Static iOS Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 8B9CC7B24A8D27E68E785BCA /* Pods-App Static iOS Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App Static iOS Tests.release.xcconfig"; path = "Target Support Files/Pods-App Static iOS Tests/Pods-App Static iOS Tests.release.xcconfig"; sourceTree = ""; }; + 8D32041ACEF0FADD40561EE0 /* Pods-Common-CPProjectUseFrameworks tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectUseFrameworks tvOS.release.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectUseFrameworks tvOS/Pods-Common-CPProjectUseFrameworks tvOS.release.xcconfig"; sourceTree = ""; }; 93617EDCE36F9B3020CD3EB1 /* Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksUITests.release.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksUITests/Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksUITests.release.xcconfig"; sourceTree = ""; }; - 99AEBB22D577EFFA7CED4C35 /* libPods-Common-CPProjectNoUseFrameworks.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Common-CPProjectNoUseFrameworks.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 9725F7F1FC79D90183098381 /* Pods-Common-CPProjectUseFrameworks iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectUseFrameworks iOS.debug.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectUseFrameworks iOS/Pods-Common-CPProjectUseFrameworks iOS.debug.xcconfig"; sourceTree = ""; }; 9D6D3B3BC8427FCEF169BBEC /* Pods-Common-CPProjectUseFrameworks.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectUseFrameworks.release.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectUseFrameworks/Pods-Common-CPProjectUseFrameworks.release.xcconfig"; sourceTree = ""; }; - B2DA1BBBF19485F5F93D1E62 /* libPods-CPProjectNoUseFrameworksTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CPProjectNoUseFrameworksTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + A0A65E902F9810ED6495E6C0 /* Pods-CPProjectNoUseFrameworksTests iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CPProjectNoUseFrameworksTests iOS.debug.xcconfig"; path = "Target Support Files/Pods-CPProjectNoUseFrameworksTests iOS/Pods-CPProjectNoUseFrameworksTests iOS.debug.xcconfig"; sourceTree = ""; }; + A9C82400C8959E70C7EB2502 /* Pods-App Static tvOS Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App Static tvOS Tests.debug.xcconfig"; path = "Target Support Files/Pods-App Static tvOS Tests/Pods-App Static tvOS Tests.debug.xcconfig"; sourceTree = ""; }; + B2FC9302ECB70EADD406DC32 /* Pods-Common-App Static iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-App Static iOS.release.xcconfig"; path = "Target Support Files/Pods-Common-App Static iOS/Pods-Common-App Static iOS.release.xcconfig"; sourceTree = ""; }; BAC50E424C491462E9E6E288 /* Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksUITests.debug.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksUITests/Pods-Common-CPProjectUseFrameworks-CPProjectUseFrameworksUITests.debug.xcconfig"; sourceTree = ""; }; BC677EB73CB7FE4A474BB0D5 /* Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksUITests.release.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksUITests/Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksUITests.release.xcconfig"; sourceTree = ""; }; + BFCEA18578B6134001291BD5 /* Pods-Common-CPProjectNoUseFrameworks tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectNoUseFrameworks tvOS.debug.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectNoUseFrameworks tvOS/Pods-Common-CPProjectNoUseFrameworks tvOS.debug.xcconfig"; sourceTree = ""; }; + CA325D6A1605874914378E3E /* libPods-App Static tvOS Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-App Static tvOS Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + D235938127C8EB0500BF32D7 /* App Static tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App Static tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + D235938F27C8ECD800BF32D7 /* App Static tvOS UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App Static tvOS UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + D245425127C8D3200039E0A6 /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; + D245425627C8DE3D0039E0A6 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + D245426427C8E1940039E0A6 /* App Dynamic tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App Dynamic tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + D245427227C8E52F0039E0A6 /* App Dynamic tvOS UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App Dynamic tvOS UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + D245428227C8E93D0039E0A6 /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; + D6BA75D1FA8AC33CAF25F826 /* Pods-Common-App Dynamic iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-App Dynamic iOS.debug.xcconfig"; path = "Target Support Files/Pods-Common-App Dynamic iOS/Pods-Common-App Dynamic iOS.debug.xcconfig"; sourceTree = ""; }; + D87E62BECE1CA53D846BEB4F /* Pods-Common-App Static iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-App Static iOS.debug.xcconfig"; path = "Target Support Files/Pods-Common-App Static iOS/Pods-Common-App Static iOS.debug.xcconfig"; sourceTree = ""; }; + DDEFBFE32D77637C24C3D3E6 /* Pods-Common-CPProjectNoUseFrameworks iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-CPProjectNoUseFrameworks iOS.debug.xcconfig"; path = "Target Support Files/Pods-Common-CPProjectNoUseFrameworks iOS/Pods-Common-CPProjectNoUseFrameworks iOS.debug.xcconfig"; sourceTree = ""; }; + E882344C32ABB793A439D744 /* Pods-CPProjectNoUseFrameworksTests iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CPProjectNoUseFrameworksTests iOS.release.xcconfig"; path = "Target Support Files/Pods-CPProjectNoUseFrameworksTests iOS/Pods-CPProjectNoUseFrameworksTests iOS.release.xcconfig"; sourceTree = ""; }; + E8CCD75AF46655F78F7A3D7A /* Pods_Common_App_Dynamic_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Common_App_Dynamic_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E9B1A67F5761A9A76A98B9F7 /* Pods-Common-App Dynamic tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Common-App Dynamic tvOS.release.xcconfig"; path = "Target Support Files/Pods-Common-App Dynamic tvOS/Pods-Common-App Dynamic tvOS.release.xcconfig"; sourceTree = ""; }; + F6F50A0329BC1BFB7F845E9B /* Pods-CPProjectNoUseFrameworksTests tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CPProjectNoUseFrameworksTests tvOS.release.xcconfig"; path = "Target Support Files/Pods-CPProjectNoUseFrameworksTests tvOS/Pods-CPProjectNoUseFrameworksTests tvOS.release.xcconfig"; sourceTree = ""; }; + FF9BFB41075F878B2FF57345 /* Pods-App Static tvOS Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App Static tvOS Tests.release.xcconfig"; path = "Target Support Files/Pods-App Static tvOS Tests/Pods-App Static tvOS Tests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -98,7 +166,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FB53D921A5A47E18B605B20B /* libPods-Common-CPProjectNoUseFrameworks.a in Frameworks */, + B162FE141838120027D821F9 /* libPods-Common-App Static iOS.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -106,7 +174,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A154B5926600D17ECDD21D84 /* libPods-CPProjectNoUseFrameworksTests.a in Frameworks */, + 2B2A0652E2BB31985CCA411B /* libPods-App Static iOS Tests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -121,7 +189,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 2FF2A19F9C78FC98880874FF /* Pods_Common_CPProjectUseFrameworks.framework in Frameworks */, + A0DBB7E71DD4888837ED81B5 /* Pods_Common_App_Dynamic_iOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -139,15 +207,60 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D235937B27C8EB0500BF32D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EC38782925CC4D95E5F3536F /* libPods-App Static tvOS Tests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D235938A27C8ECD800BF32D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D245424827C8D3200039E0A6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CCA17085193225EE98A8B997 /* Pods_Common_App_Dynamic_tvOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D245425F27C8E1940039E0A6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D245426D27C8E52F0039E0A6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D245427C27C8E93D0039E0A6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E7FDF9193D8912E2B49A5B99 /* libPods-Common-App Static tvOS.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 61B8C2FA26E0E278006EDF53 = { isa = PBXGroup; children = ( - 61B8C30526E0E278006EDF53 /* CPProject */, - 61B8C31C26E0E27A006EDF53 /* CPProjectTests */, - 61B8C32726E0E27A006EDF53 /* CPProjectUITests */, + 61B8C30526E0E278006EDF53 /* App */, + 61B8C31C26E0E27A006EDF53 /* AppTests */, + 61B8C32726E0E27A006EDF53 /* AppUITests */, 61B8C30426E0E278006EDF53 /* Products */, 8F60E2E92A8515F0E47A9B30 /* Pods */, 914DF2FA9D66773F6CA5E53E /* Frameworks */, @@ -157,45 +270,49 @@ 61B8C30426E0E278006EDF53 /* Products */ = { isa = PBXGroup; children = ( - 61B8C30326E0E278006EDF53 /* CPProjectUseFrameworks.app */, - 61B8C31926E0E27A006EDF53 /* CPProjectUseFrameworksTests.xctest */, - 61B8C32426E0E27A006EDF53 /* CPProjectUseFrameworksUITests.xctest */, - 61373B2926E0E78300E0F46E /* CPProjectNoUseFrameworks.app */, - 61373B3E26E0E78500E0F46E /* CPProjectNoUseFrameworksTests.xctest */, - 61373B4926E0E78500E0F46E /* CPProjectNoUseFrameworksUITests.xctest */, + 61B8C30326E0E278006EDF53 /* App.app */, + 61B8C31926E0E27A006EDF53 /* App Dynamic iOS Tests.xctest */, + 61B8C32426E0E27A006EDF53 /* App Dynamic iOS UITests.xctest */, + 61373B2926E0E78300E0F46E /* App.app */, + 61373B3E26E0E78500E0F46E /* App Static iOS Tests.xctest */, + 61373B4926E0E78500E0F46E /* App Static iOS UITests.xctest */, + D245425127C8D3200039E0A6 /* App.app */, + D245426427C8E1940039E0A6 /* App Dynamic tvOS Tests.xctest */, + D245427227C8E52F0039E0A6 /* App Dynamic tvOS UITests.xctest */, + D245428227C8E93D0039E0A6 /* App.app */, + D235938127C8EB0500BF32D7 /* App Static tvOS Tests.xctest */, + D235938F27C8ECD800BF32D7 /* App Static tvOS UITests.xctest */, ); name = Products; sourceTree = ""; }; - 61B8C30526E0E278006EDF53 /* CPProject */ = { + 61B8C30526E0E278006EDF53 /* App */ = { isa = PBXGroup; children = ( 61B8C30626E0E278006EDF53 /* AppDelegate.swift */, 61B8C30826E0E278006EDF53 /* SceneDelegate.swift */, - 61B8C30A26E0E278006EDF53 /* ViewController.swift */, - 61B8C30C26E0E278006EDF53 /* Main.storyboard */, - 61B8C31126E0E27A006EDF53 /* LaunchScreen.storyboard */, + D245425627C8DE3D0039E0A6 /* ViewController.swift */, 61B8C31426E0E27A006EDF53 /* Info.plist */, ); - path = CPProject; + path = App; sourceTree = ""; }; - 61B8C31C26E0E27A006EDF53 /* CPProjectTests */ = { + 61B8C31C26E0E27A006EDF53 /* AppTests */ = { isa = PBXGroup; children = ( 61B8C31D26E0E27A006EDF53 /* CPProjectTests.swift */, 61B8C31F26E0E27A006EDF53 /* Info.plist */, ); - path = CPProjectTests; + path = AppTests; sourceTree = ""; }; - 61B8C32726E0E27A006EDF53 /* CPProjectUITests */ = { + 61B8C32726E0E27A006EDF53 /* AppUITests */ = { isa = PBXGroup; children = ( 61B8C32826E0E27A006EDF53 /* CPProjectUITests.swift */, 61B8C32A26E0E27A006EDF53 /* Info.plist */, ); - path = CPProjectUITests; + path = AppUITests; sourceTree = ""; }; 8F60E2E92A8515F0E47A9B30 /* Pods */ = { @@ -215,6 +332,30 @@ BC677EB73CB7FE4A474BB0D5 /* Pods-Common-CPProjectNoUseFrameworks-CPProjectNoUseFrameworksUITests.release.xcconfig */, 51776B4903CB23F278458BB6 /* Pods-CPProjectNoUseFrameworksTests.debug.xcconfig */, 02265FB44AE08BD3D3454745 /* Pods-CPProjectNoUseFrameworksTests.release.xcconfig */, + A0A65E902F9810ED6495E6C0 /* Pods-CPProjectNoUseFrameworksTests iOS.debug.xcconfig */, + E882344C32ABB793A439D744 /* Pods-CPProjectNoUseFrameworksTests iOS.release.xcconfig */, + DDEFBFE32D77637C24C3D3E6 /* Pods-Common-CPProjectNoUseFrameworks iOS.debug.xcconfig */, + 0C5EA8849018376E6D2BD2F7 /* Pods-Common-CPProjectNoUseFrameworks iOS.release.xcconfig */, + 9725F7F1FC79D90183098381 /* Pods-Common-CPProjectUseFrameworks iOS.debug.xcconfig */, + 47B2FAD72A07C0E26A7C1031 /* Pods-Common-CPProjectUseFrameworks iOS.release.xcconfig */, + 3468D63D65BB427B2C213235 /* Pods-Common-CPProjectUseFrameworks tvOS.debug.xcconfig */, + 8D32041ACEF0FADD40561EE0 /* Pods-Common-CPProjectUseFrameworks tvOS.release.xcconfig */, + BFCEA18578B6134001291BD5 /* Pods-Common-CPProjectNoUseFrameworks tvOS.debug.xcconfig */, + 5514B2793CD3F4967A63A825 /* Pods-Common-CPProjectNoUseFrameworks tvOS.release.xcconfig */, + 34E3A05F52DE9374E351C695 /* Pods-CPProjectNoUseFrameworksTests tvOS.debug.xcconfig */, + F6F50A0329BC1BFB7F845E9B /* Pods-CPProjectNoUseFrameworksTests tvOS.release.xcconfig */, + 693132861010BF05192CAE5A /* Pods-App Static iOS Tests.debug.xcconfig */, + 8B9CC7B24A8D27E68E785BCA /* Pods-App Static iOS Tests.release.xcconfig */, + A9C82400C8959E70C7EB2502 /* Pods-App Static tvOS Tests.debug.xcconfig */, + FF9BFB41075F878B2FF57345 /* Pods-App Static tvOS Tests.release.xcconfig */, + D6BA75D1FA8AC33CAF25F826 /* Pods-Common-App Dynamic iOS.debug.xcconfig */, + 4F7B559D3C166C35B42FCC87 /* Pods-Common-App Dynamic iOS.release.xcconfig */, + 1AD1AA0F4E331947CD53AB1D /* Pods-Common-App Dynamic tvOS.debug.xcconfig */, + E9B1A67F5761A9A76A98B9F7 /* Pods-Common-App Dynamic tvOS.release.xcconfig */, + D87E62BECE1CA53D846BEB4F /* Pods-Common-App Static iOS.debug.xcconfig */, + B2FC9302ECB70EADD406DC32 /* Pods-Common-App Static iOS.release.xcconfig */, + 44638027D4B88B41A7A1B240 /* Pods-Common-App Static tvOS.debug.xcconfig */, + 3668B0235369E05E329D8F21 /* Pods-Common-App Static tvOS.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -222,9 +363,12 @@ 914DF2FA9D66773F6CA5E53E /* Frameworks */ = { isa = PBXGroup; children = ( - 424F6BCFD46A729DA7F32FC9 /* Pods_Common_CPProjectUseFrameworks.framework */, - 99AEBB22D577EFFA7CED4C35 /* libPods-Common-CPProjectNoUseFrameworks.a */, - B2DA1BBBF19485F5F93D1E62 /* libPods-CPProjectNoUseFrameworksTests.a */, + 88C7C5186A293C78E070E6CF /* libPods-App Static iOS Tests.a */, + CA325D6A1605874914378E3E /* libPods-App Static tvOS Tests.a */, + E8CCD75AF46655F78F7A3D7A /* Pods_Common_App_Dynamic_iOS.framework */, + 6F08D599966036C2B51829AB /* Pods_Common_App_Dynamic_tvOS.framework */, + 3C285D46A1E0E371443F0F77 /* libPods-Common-App Static iOS.a */, + 6120B36BC669A3227C25B90F /* libPods-Common-App Static tvOS.a */, ); name = Frameworks; sourceTree = ""; @@ -232,9 +376,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 61373B2826E0E78300E0F46E /* CPProjectNoUseFrameworks */ = { + 61373B2826E0E78300E0F46E /* App Static iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 61373B5026E0E78500E0F46E /* Build configuration list for PBXNativeTarget "CPProjectNoUseFrameworks" */; + buildConfigurationList = 61373B5026E0E78500E0F46E /* Build configuration list for PBXNativeTarget "App Static iOS" */; buildPhases = ( 8D0504D0CD7CAFBBB5B63F13 /* [CP] Check Pods Manifest.lock */, 61373B2526E0E78300E0F46E /* Sources */, @@ -245,14 +389,14 @@ ); dependencies = ( ); - name = CPProjectNoUseFrameworks; + name = "App Static iOS"; productName = CPProjectNoUseFrameworks; - productReference = 61373B2926E0E78300E0F46E /* CPProjectNoUseFrameworks.app */; + productReference = 61373B2926E0E78300E0F46E /* App.app */; productType = "com.apple.product-type.application"; }; - 61373B3D26E0E78500E0F46E /* CPProjectNoUseFrameworksTests */ = { + 61373B3D26E0E78500E0F46E /* App Static iOS Tests */ = { isa = PBXNativeTarget; - buildConfigurationList = 61373B5326E0E78500E0F46E /* Build configuration list for PBXNativeTarget "CPProjectNoUseFrameworksTests" */; + buildConfigurationList = 61373B5326E0E78500E0F46E /* Build configuration list for PBXNativeTarget "App Static iOS Tests" */; buildPhases = ( D6011F89065F1B0B4B52E465 /* [CP] Check Pods Manifest.lock */, 61373B3A26E0E78500E0F46E /* Sources */, @@ -264,14 +408,14 @@ dependencies = ( 61373B4026E0E78500E0F46E /* PBXTargetDependency */, ); - name = CPProjectNoUseFrameworksTests; + name = "App Static iOS Tests"; productName = CPProjectNoUseFrameworksTests; - productReference = 61373B3E26E0E78500E0F46E /* CPProjectNoUseFrameworksTests.xctest */; + productReference = 61373B3E26E0E78500E0F46E /* App Static iOS Tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 61373B4826E0E78500E0F46E /* CPProjectNoUseFrameworksUITests */ = { + 61373B4826E0E78500E0F46E /* App Static iOS UITests */ = { isa = PBXNativeTarget; - buildConfigurationList = 61373B5626E0E78500E0F46E /* Build configuration list for PBXNativeTarget "CPProjectNoUseFrameworksUITests" */; + buildConfigurationList = 61373B5626E0E78500E0F46E /* Build configuration list for PBXNativeTarget "App Static iOS UITests" */; buildPhases = ( 61373B4526E0E78500E0F46E /* Sources */, 61373B4626E0E78500E0F46E /* Frameworks */, @@ -282,14 +426,14 @@ dependencies = ( 61373B4B26E0E78500E0F46E /* PBXTargetDependency */, ); - name = CPProjectNoUseFrameworksUITests; + name = "App Static iOS UITests"; productName = CPProjectNoUseFrameworksUITests; - productReference = 61373B4926E0E78500E0F46E /* CPProjectNoUseFrameworksUITests.xctest */; + productReference = 61373B4926E0E78500E0F46E /* App Static iOS UITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; - 61B8C30226E0E278006EDF53 /* CPProjectUseFrameworks */ = { + 61B8C30226E0E278006EDF53 /* App Dynamic iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 61B8C32D26E0E27A006EDF53 /* Build configuration list for PBXNativeTarget "CPProjectUseFrameworks" */; + buildConfigurationList = 61B8C32D26E0E27A006EDF53 /* Build configuration list for PBXNativeTarget "App Dynamic iOS" */; buildPhases = ( 5645FD027BB938478818FE88 /* [CP] Check Pods Manifest.lock */, 61B8C2FF26E0E278006EDF53 /* Sources */, @@ -301,14 +445,14 @@ ); dependencies = ( ); - name = CPProjectUseFrameworks; + name = "App Dynamic iOS"; productName = CPProject; - productReference = 61B8C30326E0E278006EDF53 /* CPProjectUseFrameworks.app */; + productReference = 61B8C30326E0E278006EDF53 /* App.app */; productType = "com.apple.product-type.application"; }; - 61B8C31826E0E27A006EDF53 /* CPProjectUseFrameworksTests */ = { + 61B8C31826E0E27A006EDF53 /* App Dynamic iOS Tests */ = { isa = PBXNativeTarget; - buildConfigurationList = 61B8C33026E0E27A006EDF53 /* Build configuration list for PBXNativeTarget "CPProjectUseFrameworksTests" */; + buildConfigurationList = 61B8C33026E0E27A006EDF53 /* Build configuration list for PBXNativeTarget "App Dynamic iOS Tests" */; buildPhases = ( 61B8C31526E0E27A006EDF53 /* Sources */, 61B8C31626E0E27A006EDF53 /* Frameworks */, @@ -319,14 +463,14 @@ dependencies = ( 61B8C31B26E0E27A006EDF53 /* PBXTargetDependency */, ); - name = CPProjectUseFrameworksTests; + name = "App Dynamic iOS Tests"; productName = CPProjectTests; - productReference = 61B8C31926E0E27A006EDF53 /* CPProjectUseFrameworksTests.xctest */; + productReference = 61B8C31926E0E27A006EDF53 /* App Dynamic iOS Tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 61B8C32326E0E27A006EDF53 /* CPProjectUseFrameworksUITests */ = { + 61B8C32326E0E27A006EDF53 /* App Dynamic iOS UITests */ = { isa = PBXNativeTarget; - buildConfigurationList = 61B8C33326E0E27A006EDF53 /* Build configuration list for PBXNativeTarget "CPProjectUseFrameworksUITests" */; + buildConfigurationList = 61B8C33326E0E27A006EDF53 /* Build configuration list for PBXNativeTarget "App Dynamic iOS UITests" */; buildPhases = ( 61B8C32026E0E27A006EDF53 /* Sources */, 61B8C32126E0E27A006EDF53 /* Frameworks */, @@ -337,11 +481,121 @@ dependencies = ( 61B8C32626E0E27A006EDF53 /* PBXTargetDependency */, ); - name = CPProjectUseFrameworksUITests; + name = "App Dynamic iOS UITests"; + productName = CPProjectUITests; + productReference = 61B8C32426E0E27A006EDF53 /* App Dynamic iOS UITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + D235937527C8EB0500BF32D7 /* App Static tvOS Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D235937E27C8EB0500BF32D7 /* Build configuration list for PBXNativeTarget "App Static tvOS Tests" */; + buildPhases = ( + D235937827C8EB0500BF32D7 /* [CP] Check Pods Manifest.lock */, + D235937927C8EB0500BF32D7 /* Sources */, + D235937B27C8EB0500BF32D7 /* Frameworks */, + D235937D27C8EB0500BF32D7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D235938427C8EC0900BF32D7 /* PBXTargetDependency */, + ); + name = "App Static tvOS Tests"; + productName = CPProjectNoUseFrameworksTests; + productReference = D235938127C8EB0500BF32D7 /* App Static tvOS Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + D235938527C8ECD800BF32D7 /* App Static tvOS UITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D235938C27C8ECD800BF32D7 /* Build configuration list for PBXNativeTarget "App Static tvOS UITests" */; + buildPhases = ( + D235938827C8ECD800BF32D7 /* Sources */, + D235938A27C8ECD800BF32D7 /* Frameworks */, + D235938B27C8ECD800BF32D7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D235939227C8ECE000BF32D7 /* PBXTargetDependency */, + ); + name = "App Static tvOS UITests"; + productName = CPProjectNoUseFrameworksUITests; + productReference = D235938F27C8ECD800BF32D7 /* App Static tvOS UITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + D245424227C8D3200039E0A6 /* App Dynamic tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D245424E27C8D3200039E0A6 /* Build configuration list for PBXNativeTarget "App Dynamic tvOS" */; + buildPhases = ( + D245424327C8D3200039E0A6 /* [CP] Check Pods Manifest.lock */, + D245424427C8D3200039E0A6 /* Sources */, + D245424827C8D3200039E0A6 /* Frameworks */, + D245424A27C8D3200039E0A6 /* Resources */, + D245424D27C8D3200039E0A6 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "App Dynamic tvOS"; + productName = CPProject; + productReference = D245425127C8D3200039E0A6 /* App.app */; + productType = "com.apple.product-type.application"; + }; + D245425A27C8E1940039E0A6 /* App Dynamic tvOS Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D245426127C8E1940039E0A6 /* Build configuration list for PBXNativeTarget "App Dynamic tvOS Tests" */; + buildPhases = ( + D245425D27C8E1940039E0A6 /* Sources */, + D245425F27C8E1940039E0A6 /* Frameworks */, + D245426027C8E1940039E0A6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D245426727C8E4CD0039E0A6 /* PBXTargetDependency */, + ); + name = "App Dynamic tvOS Tests"; + productName = CPProjectTests; + productReference = D245426427C8E1940039E0A6 /* App Dynamic tvOS Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + D245426827C8E52F0039E0A6 /* App Dynamic tvOS UITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D245426F27C8E52F0039E0A6 /* Build configuration list for PBXNativeTarget "App Dynamic tvOS UITests" */; + buildPhases = ( + D245426B27C8E52F0039E0A6 /* Sources */, + D245426D27C8E52F0039E0A6 /* Frameworks */, + D245426E27C8E52F0039E0A6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D245427527C8E5870039E0A6 /* PBXTargetDependency */, + ); + name = "App Dynamic tvOS UITests"; productName = CPProjectUITests; - productReference = 61B8C32426E0E27A006EDF53 /* CPProjectUseFrameworksUITests.xctest */; + productReference = D245427227C8E52F0039E0A6 /* App Dynamic tvOS UITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; + D245427627C8E93D0039E0A6 /* App Static tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D245427F27C8E93D0039E0A6 /* Build configuration list for PBXNativeTarget "App Static tvOS" */; + buildPhases = ( + D245427727C8E93D0039E0A6 /* [CP] Check Pods Manifest.lock */, + D245427827C8E93D0039E0A6 /* Sources */, + D245427C27C8E93D0039E0A6 /* Frameworks */, + D245427E27C8E93D0039E0A6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "App Static tvOS"; + productName = CPProjectNoUseFrameworks; + productReference = D245428227C8E93D0039E0A6 /* App.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -373,6 +627,18 @@ CreatedOnToolsVersion = 12.5; TestTargetID = 61B8C30226E0E278006EDF53; }; + D235937527C8EB0500BF32D7 = { + TestTargetID = D245427627C8E93D0039E0A6; + }; + D235938527C8ECD800BF32D7 = { + TestTargetID = D245427627C8E93D0039E0A6; + }; + D245425A27C8E1940039E0A6 = { + TestTargetID = D245424227C8D3200039E0A6; + }; + D245426827C8E52F0039E0A6 = { + TestTargetID = D245424227C8D3200039E0A6; + }; }; }; buildConfigurationList = 61B8C2FE26E0E278006EDF53 /* Build configuration list for PBXProject "CPProject" */; @@ -388,12 +654,18 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 61B8C30226E0E278006EDF53 /* CPProjectUseFrameworks */, - 61B8C31826E0E27A006EDF53 /* CPProjectUseFrameworksTests */, - 61B8C32326E0E27A006EDF53 /* CPProjectUseFrameworksUITests */, - 61373B2826E0E78300E0F46E /* CPProjectNoUseFrameworks */, - 61373B3D26E0E78500E0F46E /* CPProjectNoUseFrameworksTests */, - 61373B4826E0E78500E0F46E /* CPProjectNoUseFrameworksUITests */, + 61B8C30226E0E278006EDF53 /* App Dynamic iOS */, + 61B8C31826E0E27A006EDF53 /* App Dynamic iOS Tests */, + 61B8C32326E0E27A006EDF53 /* App Dynamic iOS UITests */, + 61373B2826E0E78300E0F46E /* App Static iOS */, + 61373B3D26E0E78500E0F46E /* App Static iOS Tests */, + 61373B4826E0E78500E0F46E /* App Static iOS UITests */, + D245424227C8D3200039E0A6 /* App Dynamic tvOS */, + D245425A27C8E1940039E0A6 /* App Dynamic tvOS Tests */, + D245426827C8E52F0039E0A6 /* App Dynamic tvOS UITests */, + D245427627C8E93D0039E0A6 /* App Static tvOS */, + D235937527C8EB0500BF32D7 /* App Static tvOS Tests */, + D235938527C8ECD800BF32D7 /* App Static tvOS UITests */, ); }; /* End PBXProject section */ @@ -403,8 +675,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61373B5E26E0E7DF00E0F46E /* LaunchScreen.storyboard in Resources */, - 61373B5C26E0E7D800E0F46E /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -426,8 +696,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61B8C31326E0E27A006EDF53 /* LaunchScreen.storyboard in Resources */, - 61B8C30E26E0E278006EDF53 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -445,6 +713,48 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D235937D27C8EB0500BF32D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D235938B27C8ECD800BF32D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D245424A27C8D3200039E0A6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D245426027C8E1940039E0A6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D245426E27C8E52F0039E0A6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D245427E27C8E93D0039E0A6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -454,15 +764,15 @@ files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Common-CPProjectUseFrameworks/Pods-Common-CPProjectUseFrameworks-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-Common-App Dynamic iOS/Pods-Common-App Dynamic iOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Common-CPProjectUseFrameworks/Pods-Common-CPProjectUseFrameworks-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-Common-App Dynamic iOS/Pods-Common-App Dynamic iOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Common-CPProjectUseFrameworks/Pods-Common-CPProjectUseFrameworks-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Common-App Dynamic iOS/Pods-Common-App Dynamic iOS-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 5645FD027BB938478818FE88 /* [CP] Check Pods Manifest.lock */ = { @@ -480,7 +790,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Common-CPProjectUseFrameworks-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-Common-App Dynamic iOS-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -502,7 +812,90 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Common-CPProjectNoUseFrameworks-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-Common-App Static iOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + D235937827C8EB0500BF32D7 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-App Static tvOS Tests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + D245424327C8D3200039E0A6 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Common-App Dynamic tvOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + D245424D27C8D3200039E0A6 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Common-App Dynamic tvOS/Pods-Common-App Dynamic tvOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Common-App Dynamic tvOS/Pods-Common-App Dynamic tvOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Common-App Dynamic tvOS/Pods-Common-App Dynamic tvOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + D245427727C8E93D0039E0A6 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Common-App Static tvOS-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -524,7 +917,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-CPProjectNoUseFrameworksTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-App Static iOS Tests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -538,7 +931,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61373B5B26E0E7D100E0F46E /* ViewController.swift in Sources */, + D245425827C8DE3D0039E0A6 /* ViewController.swift in Sources */, 61373B5926E0E7C900E0F46E /* AppDelegate.swift in Sources */, 61373B5A26E0E7CD00E0F46E /* SceneDelegate.swift in Sources */, ); @@ -564,7 +957,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61B8C30B26E0E278006EDF53 /* ViewController.swift in Sources */, + D245425727C8DE3D0039E0A6 /* ViewController.swift in Sources */, 61B8C30726E0E278006EDF53 /* AppDelegate.swift in Sources */, 61B8C30926E0E278006EDF53 /* SceneDelegate.swift in Sources */, ); @@ -586,66 +979,119 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D235937927C8EB0500BF32D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D235937A27C8EB0500BF32D7 /* CPProjectTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D235938827C8ECD800BF32D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D235938927C8ECD800BF32D7 /* CPProjectUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D245424427C8D3200039E0A6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D245425927C8DE3D0039E0A6 /* ViewController.swift in Sources */, + D245424627C8D3200039E0A6 /* AppDelegate.swift in Sources */, + D245424727C8D3200039E0A6 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D245425D27C8E1940039E0A6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D245425E27C8E1940039E0A6 /* CPProjectTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D245426B27C8E52F0039E0A6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D245426C27C8E52F0039E0A6 /* CPProjectUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D245427827C8E93D0039E0A6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D245427927C8E93D0039E0A6 /* ViewController.swift in Sources */, + D245427A27C8E93D0039E0A6 /* AppDelegate.swift in Sources */, + D245427B27C8E93D0039E0A6 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 61373B4026E0E78500E0F46E /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61373B2826E0E78300E0F46E /* CPProjectNoUseFrameworks */; + target = 61373B2826E0E78300E0F46E /* App Static iOS */; targetProxy = 61373B3F26E0E78500E0F46E /* PBXContainerItemProxy */; }; 61373B4B26E0E78500E0F46E /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61373B2826E0E78300E0F46E /* CPProjectNoUseFrameworks */; + target = 61373B2826E0E78300E0F46E /* App Static iOS */; targetProxy = 61373B4A26E0E78500E0F46E /* PBXContainerItemProxy */; }; 61B8C31B26E0E27A006EDF53 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61B8C30226E0E278006EDF53 /* CPProjectUseFrameworks */; + target = 61B8C30226E0E278006EDF53 /* App Dynamic iOS */; targetProxy = 61B8C31A26E0E27A006EDF53 /* PBXContainerItemProxy */; }; 61B8C32626E0E27A006EDF53 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61B8C30226E0E278006EDF53 /* CPProjectUseFrameworks */; + target = 61B8C30226E0E278006EDF53 /* App Dynamic iOS */; targetProxy = 61B8C32526E0E27A006EDF53 /* PBXContainerItemProxy */; }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 61B8C30C26E0E278006EDF53 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 61B8C30D26E0E278006EDF53 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; + D235938427C8EC0900BF32D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D245427627C8E93D0039E0A6 /* App Static tvOS */; + targetProxy = D235938327C8EC0900BF32D7 /* PBXContainerItemProxy */; }; - 61B8C31126E0E27A006EDF53 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 61B8C31226E0E27A006EDF53 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; + D235939227C8ECE000BF32D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D245427627C8E93D0039E0A6 /* App Static tvOS */; + targetProxy = D235939127C8ECE000BF32D7 /* PBXContainerItemProxy */; + }; + D245426727C8E4CD0039E0A6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D245424227C8D3200039E0A6 /* App Dynamic tvOS */; + targetProxy = D245426627C8E4CD0039E0A6 /* PBXContainerItemProxy */; + }; + D245427527C8E5870039E0A6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D245424227C8D3200039E0A6 /* App Dynamic tvOS */; + targetProxy = D245427427C8E5870039E0A6 /* PBXContainerItemProxy */; }; -/* End PBXVariantGroup section */ +/* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 61373B5126E0E78500E0F46E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 01FD54C4011C8F113E285585 /* Pods-Common-CPProjectNoUseFrameworks.debug.xcconfig */; + baseConfigurationReference = D87E62BECE1CA53D846BEB4F /* Pods-Common-App Static iOS.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = JKFCB4CN7C; - INFOPLIST_FILE = CPProject/Info.plist; + INFOPLIST_FILE = App/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectNoUseFrameworks; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = App; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -653,19 +1099,19 @@ }; 61373B5226E0E78500E0F46E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3D97712BEE25C98C566E565A /* Pods-Common-CPProjectNoUseFrameworks.release.xcconfig */; + baseConfigurationReference = B2FC9302ECB70EADD406DC32 /* Pods-Common-App Static iOS.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = JKFCB4CN7C; - INFOPLIST_FILE = CPProject/Info.plist; + INFOPLIST_FILE = App/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectNoUseFrameworks; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = App; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -673,12 +1119,12 @@ }; 61373B5426E0E78500E0F46E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 51776B4903CB23F278458BB6 /* Pods-CPProjectNoUseFrameworksTests.debug.xcconfig */; + baseConfigurationReference = 693132861010BF05192CAE5A /* Pods-App Static iOS Tests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = JKFCB4CN7C; - INFOPLIST_FILE = CPProjectTests/Info.plist; + INFOPLIST_FILE = AppTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -688,18 +1134,18 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CPProjectNoUseFrameworks.app/CPProjectNoUseFrameworks"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; }; name = Debug; }; 61373B5526E0E78500E0F46E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 02265FB44AE08BD3D3454745 /* Pods-CPProjectNoUseFrameworksTests.release.xcconfig */; + baseConfigurationReference = 8B9CC7B24A8D27E68E785BCA /* Pods-App Static iOS Tests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = JKFCB4CN7C; - INFOPLIST_FILE = CPProjectTests/Info.plist; + INFOPLIST_FILE = AppTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -709,7 +1155,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CPProjectNoUseFrameworks.app/CPProjectNoUseFrameworks"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; }; name = Release; }; @@ -718,7 +1164,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = JKFCB4CN7C; - INFOPLIST_FILE = CPProjectUITests/Info.plist; + INFOPLIST_FILE = AppUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -737,7 +1183,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = JKFCB4CN7C; - INFOPLIST_FILE = CPProjectUITests/Info.plist; + INFOPLIST_FILE = AppUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -809,6 +1255,7 @@ SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TVOS_DEPLOYMENT_TARGET = 13.0; }; name = Debug; }; @@ -863,25 +1310,26 @@ SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; + TVOS_DEPLOYMENT_TARGET = 13.0; VALIDATE_PRODUCT = YES; }; name = Release; }; 61B8C32E26E0E27A006EDF53 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 586B9607FFDD69DAD0C23F22 /* Pods-Common-CPProjectUseFrameworks.debug.xcconfig */; + baseConfigurationReference = D6BA75D1FA8AC33CAF25F826 /* Pods-Common-App Dynamic iOS.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = JKFCB4CN7C; - INFOPLIST_FILE = CPProject/Info.plist; + INFOPLIST_FILE = App/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectUseFrameworks; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = App; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -889,19 +1337,19 @@ }; 61B8C32F26E0E27A006EDF53 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9D6D3B3BC8427FCEF169BBEC /* Pods-Common-CPProjectUseFrameworks.release.xcconfig */; + baseConfigurationReference = 4F7B559D3C166C35B42FCC87 /* Pods-Common-App Dynamic iOS.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = JKFCB4CN7C; - INFOPLIST_FILE = CPProject/Info.plist; + INFOPLIST_FILE = App/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectUseFrameworks; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = App; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -913,7 +1361,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = JKFCB4CN7C; - INFOPLIST_FILE = CPProjectTests/Info.plist; + INFOPLIST_FILE = AppTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -921,10 +1369,9 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectUseFrameworksTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG COMPILING_FOR_USE_FRAMEWORKS"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CPProjectUseFrameworks.app/CPProjectUseFrameworks"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; }; name = Debug; }; @@ -934,7 +1381,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = JKFCB4CN7C; - INFOPLIST_FILE = CPProjectTests/Info.plist; + INFOPLIST_FILE = AppTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -944,7 +1391,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CPProjectUseFrameworks.app/CPProjectUseFrameworks"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; }; name = Release; }; @@ -953,7 +1400,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = JKFCB4CN7C; - INFOPLIST_FILE = CPProjectUITests/Info.plist; + INFOPLIST_FILE = AppUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -973,7 +1420,7 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = JKFCB4CN7C; - INFOPLIST_FILE = CPProjectUITests/Info.plist; + INFOPLIST_FILE = AppUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -988,10 +1435,250 @@ }; name = Release; }; + D235937F27C8EB0500BF32D7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A9C82400C8959E70C7EB2502 /* Pods-App Static tvOS Tests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = JKFCB4CN7C; + INFOPLIST_FILE = AppTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectNoUseFrameworksTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; + }; + name = Debug; + }; + D235938027C8EB0500BF32D7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FF9BFB41075F878B2FF57345 /* Pods-App Static tvOS Tests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = JKFCB4CN7C; + INFOPLIST_FILE = AppTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectNoUseFrameworksTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; + }; + name = Release; + }; + D235938D27C8ECD800BF32D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = JKFCB4CN7C; + INFOPLIST_FILE = AppUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectNoUseFrameworksUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = "CPProjectNoUseFrameworks tvOS"; + }; + name = Debug; + }; + D235938E27C8ECD800BF32D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = JKFCB4CN7C; + INFOPLIST_FILE = AppUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectNoUseFrameworksUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = "CPProjectNoUseFrameworks tvOS"; + }; + name = Release; + }; + D245424F27C8D3200039E0A6 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1AD1AA0F4E331947CD53AB1D /* Pods-Common-App Dynamic tvOS.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = JKFCB4CN7C; + INFOPLIST_FILE = App/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectUseFrameworks; + PRODUCT_NAME = App; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + D245425027C8D3200039E0A6 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E9B1A67F5761A9A76A98B9F7 /* Pods-Common-App Dynamic tvOS.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = JKFCB4CN7C; + INFOPLIST_FILE = App/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectUseFrameworks; + PRODUCT_NAME = App; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + D245426227C8E1940039E0A6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = JKFCB4CN7C; + INFOPLIST_FILE = AppTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectUseFrameworksTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; + }; + name = Debug; + }; + D245426327C8E1940039E0A6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = JKFCB4CN7C; + INFOPLIST_FILE = AppTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectUseFrameworksTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; + }; + name = Release; + }; + D245427027C8E52F0039E0A6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = JKFCB4CN7C; + INFOPLIST_FILE = AppUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectUseFrameworksUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = "CPProjectUseFrameworks tvOS"; + }; + name = Debug; + }; + D245427127C8E52F0039E0A6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = JKFCB4CN7C; + INFOPLIST_FILE = AppUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectUseFrameworksUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = "CPProjectUseFrameworks tvOS"; + }; + name = Release; + }; + D245428027C8E93D0039E0A6 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 44638027D4B88B41A7A1B240 /* Pods-Common-App Static tvOS.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = JKFCB4CN7C; + INFOPLIST_FILE = App/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectNoUseFrameworks; + PRODUCT_NAME = App; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + D245428127C8E93D0039E0A6 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3668B0235369E05E329D8F21 /* Pods-Common-App Static tvOS.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = JKFCB4CN7C; + INFOPLIST_FILE = App/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadoghq.CPProjectNoUseFrameworks; + PRODUCT_NAME = App; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 61373B5026E0E78500E0F46E /* Build configuration list for PBXNativeTarget "CPProjectNoUseFrameworks" */ = { + 61373B5026E0E78500E0F46E /* Build configuration list for PBXNativeTarget "App Static iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 61373B5126E0E78500E0F46E /* Debug */, @@ -1000,7 +1687,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61373B5326E0E78500E0F46E /* Build configuration list for PBXNativeTarget "CPProjectNoUseFrameworksTests" */ = { + 61373B5326E0E78500E0F46E /* Build configuration list for PBXNativeTarget "App Static iOS Tests" */ = { isa = XCConfigurationList; buildConfigurations = ( 61373B5426E0E78500E0F46E /* Debug */, @@ -1009,7 +1696,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61373B5626E0E78500E0F46E /* Build configuration list for PBXNativeTarget "CPProjectNoUseFrameworksUITests" */ = { + 61373B5626E0E78500E0F46E /* Build configuration list for PBXNativeTarget "App Static iOS UITests" */ = { isa = XCConfigurationList; buildConfigurations = ( 61373B5726E0E78500E0F46E /* Debug */, @@ -1027,7 +1714,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61B8C32D26E0E27A006EDF53 /* Build configuration list for PBXNativeTarget "CPProjectUseFrameworks" */ = { + 61B8C32D26E0E27A006EDF53 /* Build configuration list for PBXNativeTarget "App Dynamic iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 61B8C32E26E0E27A006EDF53 /* Debug */, @@ -1036,7 +1723,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61B8C33026E0E27A006EDF53 /* Build configuration list for PBXNativeTarget "CPProjectUseFrameworksTests" */ = { + 61B8C33026E0E27A006EDF53 /* Build configuration list for PBXNativeTarget "App Dynamic iOS Tests" */ = { isa = XCConfigurationList; buildConfigurations = ( 61B8C33126E0E27A006EDF53 /* Debug */, @@ -1045,7 +1732,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61B8C33326E0E27A006EDF53 /* Build configuration list for PBXNativeTarget "CPProjectUseFrameworksUITests" */ = { + 61B8C33326E0E27A006EDF53 /* Build configuration list for PBXNativeTarget "App Dynamic iOS UITests" */ = { isa = XCConfigurationList; buildConfigurations = ( 61B8C33426E0E27A006EDF53 /* Debug */, @@ -1054,6 +1741,60 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + D235937E27C8EB0500BF32D7 /* Build configuration list for PBXNativeTarget "App Static tvOS Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D235937F27C8EB0500BF32D7 /* Debug */, + D235938027C8EB0500BF32D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D235938C27C8ECD800BF32D7 /* Build configuration list for PBXNativeTarget "App Static tvOS UITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D235938D27C8ECD800BF32D7 /* Debug */, + D235938E27C8ECD800BF32D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D245424E27C8D3200039E0A6 /* Build configuration list for PBXNativeTarget "App Dynamic tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D245424F27C8D3200039E0A6 /* Debug */, + D245425027C8D3200039E0A6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D245426127C8E1940039E0A6 /* Build configuration list for PBXNativeTarget "App Dynamic tvOS Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D245426227C8E1940039E0A6 /* Debug */, + D245426327C8E1940039E0A6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D245426F27C8E52F0039E0A6 /* Build configuration list for PBXNativeTarget "App Dynamic tvOS UITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D245427027C8E52F0039E0A6 /* Debug */, + D245427127C8E52F0039E0A6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D245427F27C8E93D0039E0A6 /* Build configuration list for PBXNativeTarget "App Static tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D245428027C8E93D0039E0A6 /* Debug */, + D245428127C8E93D0039E0A6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 61B8C2FB26E0E278006EDF53 /* Project object */; diff --git a/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/CPProjectUseFrameworks.xcscheme b/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Dynamic iOS.xcscheme similarity index 84% rename from dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/CPProjectUseFrameworks.xcscheme rename to dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Dynamic iOS.xcscheme index d834e8e16f..02a2c13aa6 100644 --- a/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/CPProjectUseFrameworks.xcscheme +++ b/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Dynamic iOS.xcscheme @@ -15,8 +15,8 @@ @@ -33,8 +33,8 @@ @@ -43,8 +43,8 @@ @@ -65,8 +65,8 @@ @@ -82,8 +82,8 @@ diff --git a/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Dynamic tvOS.xcscheme b/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Dynamic tvOS.xcscheme new file mode 100644 index 0000000000..d141a43c77 --- /dev/null +++ b/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Dynamic tvOS.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/CPProjectNoUseFrameworks.xcscheme b/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Static iOS.xcscheme similarity index 84% rename from dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/CPProjectNoUseFrameworks.xcscheme rename to dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Static iOS.xcscheme index 82c4219962..08e0ea1b9b 100644 --- a/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/CPProjectNoUseFrameworks.xcscheme +++ b/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Static iOS.xcscheme @@ -15,8 +15,8 @@ @@ -33,8 +33,8 @@ @@ -43,8 +43,8 @@ @@ -65,8 +65,8 @@ @@ -82,8 +82,8 @@ diff --git a/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Static tvOS.xcscheme b/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Static tvOS.xcscheme new file mode 100644 index 0000000000..f2239c24c0 --- /dev/null +++ b/dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Static tvOS.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dependency-manager-tests/cocoapods/CPProject/Base.lproj/LaunchScreen.storyboard b/dependency-manager-tests/cocoapods/CPProject/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 865e9329f3..0000000000 --- a/dependency-manager-tests/cocoapods/CPProject/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dependency-manager-tests/cocoapods/CPProject/Base.lproj/Main.storyboard b/dependency-manager-tests/cocoapods/CPProject/Base.lproj/Main.storyboard deleted file mode 100644 index 650f1fd723..0000000000 --- a/dependency-manager-tests/cocoapods/CPProject/Base.lproj/Main.storyboard +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dependency-manager-tests/cocoapods/Podfile.src b/dependency-manager-tests/cocoapods/Podfile.src index 17c7af061b..35eade9236 100644 --- a/dependency-manager-tests/cocoapods/Podfile.src +++ b/dependency-manager-tests/cocoapods/Podfile.src @@ -1,18 +1,33 @@ -platform :ios, '13.0' - abstract_target 'Common' do pod 'DatadogSDK', :git => 'GIT_REMOTE', :GIT_REFERENCE pod 'DatadogSDKAlamofireExtension', :git => 'GIT_REMOTE', :GIT_REFERENCE pod 'DatadogSDKCrashReporting', :git => 'GIT_REMOTE', :GIT_REFERENCE pod 'Alamofire' - target 'CPProjectUseFrameworks' do + target 'App Dynamic iOS' do + platform :ios, '13.0' use_frameworks! end - target 'CPProjectNoUseFrameworks' do - target 'CPProjectNoUseFrameworksTests' do + target 'App Static iOS' do + platform :ios, '13.0' + + target 'App Static iOS Tests' do inherit! :search_paths end end + + target 'App Dynamic tvOS' do + platform :tvos, '13.0' + use_frameworks! + end + + target 'App Static tvOS' do + platform :tvos, '13.0' + + target 'App Static tvOS Tests' do + inherit! :search_paths + end + end + end diff --git a/dependency-manager-tests/spm/SPMProject/AppDelegate.swift b/dependency-manager-tests/spm/App/AppDelegate.swift similarity index 100% rename from dependency-manager-tests/spm/SPMProject/AppDelegate.swift rename to dependency-manager-tests/spm/App/AppDelegate.swift diff --git a/dependency-manager-tests/spm/SPMProject/Info.plist b/dependency-manager-tests/spm/App/Info.plist similarity index 90% rename from dependency-manager-tests/spm/SPMProject/Info.plist rename to dependency-manager-tests/spm/App/Info.plist index 2a3483c0d2..639166254f 100644 --- a/dependency-manager-tests/spm/SPMProject/Info.plist +++ b/dependency-manager-tests/spm/App/Info.plist @@ -33,16 +33,10 @@ Default Configuration UISceneDelegateClassName $(PRODUCT_MODULE_NAME).SceneDelegate - UISceneStoryboardFile - Main - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main UIRequiredDeviceCapabilities armv7 diff --git a/dependency-manager-tests/cocoapods/CPProject/SceneDelegate.swift b/dependency-manager-tests/spm/App/SceneDelegate.swift similarity index 74% rename from dependency-manager-tests/cocoapods/CPProject/SceneDelegate.swift rename to dependency-manager-tests/spm/App/SceneDelegate.swift index c812c9793c..09f8e5a3ae 100644 --- a/dependency-manager-tests/cocoapods/CPProject/SceneDelegate.swift +++ b/dependency-manager-tests/spm/App/SceneDelegate.swift @@ -10,6 +10,14 @@ internal class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + guard let windowScene = scene as? UIWindowScene else { + return + } + + let window = UIWindow(windowScene: windowScene) + window.rootViewController = ViewController() + self.window = window + window.makeKeyAndVisible() } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/dependency-manager-tests/spm/SPMProject/ViewController.swift b/dependency-manager-tests/spm/App/ViewController.swift similarity index 79% rename from dependency-manager-tests/spm/SPMProject/ViewController.swift rename to dependency-manager-tests/spm/App/ViewController.swift index b268b849eb..9176eccd6c 100644 --- a/dependency-manager-tests/spm/SPMProject/ViewController.swift +++ b/dependency-manager-tests/spm/App/ViewController.swift @@ -34,5 +34,18 @@ internal class ViewController: UIViewController { // Start span, but never finish it (no upload) _ = Global.sharedTracer.startSpan(operationName: "This too") + + addLabel() + } + + private func addLabel() { + let label = UILabel() + label.autoresizingMask = [.flexibleWidth, .flexibleHeight] + view.addSubview(label) + + label.text = "Testing..." + label.textColor = .white + label.sizeToFit() + label.center = view.center } } diff --git a/dependency-manager-tests/spm/SPMProjectTests/SPMProjectTests.swift b/dependency-manager-tests/spm/AppTests/AppTests.swift similarity index 94% rename from dependency-manager-tests/spm/SPMProjectTests/SPMProjectTests.swift rename to dependency-manager-tests/spm/AppTests/AppTests.swift index ef03854cfb..67771e7b6a 100644 --- a/dependency-manager-tests/spm/SPMProjectTests/SPMProjectTests.swift +++ b/dependency-manager-tests/spm/AppTests/AppTests.swift @@ -5,7 +5,8 @@ */ import XCTest -@testable import SPMProject + +@testable import App class SPMProjectTests: XCTestCase { func testCallingLogicThatLoadsSDK() throws { diff --git a/dependency-manager-tests/spm/SPMProjectTests/Info.plist b/dependency-manager-tests/spm/AppTests/Info.plist similarity index 100% rename from dependency-manager-tests/spm/SPMProjectTests/Info.plist rename to dependency-manager-tests/spm/AppTests/Info.plist diff --git a/dependency-manager-tests/spm/SPMProjectUITests/SPMProjectUITests.swift b/dependency-manager-tests/spm/AppUITests/AppUITests.swift similarity index 100% rename from dependency-manager-tests/spm/SPMProjectUITests/SPMProjectUITests.swift rename to dependency-manager-tests/spm/AppUITests/AppUITests.swift diff --git a/dependency-manager-tests/spm/SPMProjectUITests/Info.plist b/dependency-manager-tests/spm/AppUITests/Info.plist similarity index 100% rename from dependency-manager-tests/spm/SPMProjectUITests/Info.plist rename to dependency-manager-tests/spm/AppUITests/Info.plist diff --git a/dependency-manager-tests/spm/Makefile b/dependency-manager-tests/spm/Makefile index 91f32f9a9c..531dbe924c 100644 --- a/dependency-manager-tests/spm/Makefile +++ b/dependency-manager-tests/spm/Makefile @@ -24,5 +24,5 @@ create-src-from-xcodeproj: rm -rf SPMProject.xcodeproj.src cp -r SPMProject.xcodeproj SPMProject.xcodeproj.src rm SPMProject.xcodeproj.src/project.xcworkspace/xcshareddata/swiftpm/Package.resolved - sed "s|\"${GIT_REFERENCE}\"|REMOTE_GIT_REFERENCE|g" SPMProject.xcodeproj/project.pbxproj > SPMProject.xcodeproj.src/project.pbxproj + sed "s|\"${GIT_REFERENCE}\"|GIT_REFERENCE|g" SPMProject.xcodeproj/project.pbxproj > SPMProject.xcodeproj.src/project.pbxproj @echo "OK 👌" diff --git a/dependency-manager-tests/spm/SPMProject.xcodeproj.src/project.pbxproj b/dependency-manager-tests/spm/SPMProject.xcodeproj.src/project.pbxproj index 810d7ecf50..d65fe4f82b 100644 --- a/dependency-manager-tests/spm/SPMProject.xcodeproj.src/project.pbxproj +++ b/dependency-manager-tests/spm/SPMProject.xcodeproj.src/project.pbxproj @@ -10,11 +10,15 @@ 61C363DA24374D5F00C4D4E6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C363D924374D5F00C4D4E6 /* AppDelegate.swift */; }; 61C363DC24374D5F00C4D4E6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C363DB24374D5F00C4D4E6 /* SceneDelegate.swift */; }; 61C363DE24374D5F00C4D4E6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C363DD24374D5F00C4D4E6 /* ViewController.swift */; }; - 61C363E124374D5F00C4D4E6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61C363DF24374D5F00C4D4E6 /* Main.storyboard */; }; - 61C363E624374D6000C4D4E6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61C363E424374D6000C4D4E6 /* LaunchScreen.storyboard */; }; - 61C363F124374D6100C4D4E6 /* SPMProjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C363F024374D6100C4D4E6 /* SPMProjectTests.swift */; }; - 61C363FC24374D6100C4D4E6 /* SPMProjectUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C363FB24374D6100C4D4E6 /* SPMProjectUITests.swift */; }; + 61C363F124374D6100C4D4E6 /* AppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C363F024374D6100C4D4E6 /* AppTests.swift */; }; + 61C363FC24374D6100C4D4E6 /* AppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C363FB24374D6100C4D4E6 /* AppUITests.swift */; }; 9E73374026B0123500917C24 /* DatadogCrashReporting in Frameworks */ = {isa = PBXBuildFile; productRef = 9E73373F26B0123500917C24 /* DatadogCrashReporting */; }; + D23BF5F327CCCC3300BB4CCD /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C363DD24374D5F00C4D4E6 /* ViewController.swift */; }; + D23BF5F427CCCC3300BB4CCD /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C363D924374D5F00C4D4E6 /* AppDelegate.swift */; }; + D23BF5F527CCCC3300BB4CCD /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C363DB24374D5F00C4D4E6 /* SceneDelegate.swift */; }; + D23BF5F727CCCC3300BB4CCD /* DatadogCrashReporting in Frameworks */ = {isa = PBXBuildFile; productRef = D23BF5F027CCCC3300BB4CCD /* DatadogCrashReporting */; }; + D23BF60427CCCCF800BB4CCD /* AppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C363FB24374D6100C4D4E6 /* AppUITests.swift */; }; + D23BF61027CCCD5700BB4CCD /* AppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C363F024374D6100C4D4E6 /* AppTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -32,6 +36,20 @@ remoteGlobalIDString = 61C363D524374D5F00C4D4E6; remoteInfo = SPMProject; }; + D23BF61827CCCE2300BB4CCD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61C363CE24374D5F00C4D4E6 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D23BF5EF27CCCC3300BB4CCD; + remoteInfo = "App tvOS"; + }; + D23BF61A27CCCE2700BB4CCD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61C363CE24374D5F00C4D4E6 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D23BF5EF27CCCC3300BB4CCD; + remoteInfo = "App tvOS"; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -45,24 +63,35 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; + D23BF5FA27CCCC3300BB4CCD /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 61C363D624374D5F00C4D4E6 /* SPMProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SPMProject.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 61C363D624374D5F00C4D4E6 /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; 61C363D924374D5F00C4D4E6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 61C363DB24374D5F00C4D4E6 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 61C363DD24374D5F00C4D4E6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 61C363E024374D5F00C4D4E6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 61C363E524374D6000C4D4E6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 61C363E724374D6000C4D4E6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 61C363EC24374D6100C4D4E6 /* SPMProjectTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SPMProjectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 61C363F024374D6100C4D4E6 /* SPMProjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPMProjectTests.swift; sourceTree = ""; }; + 61C363EC24374D6100C4D4E6 /* App iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 61C363F024374D6100C4D4E6 /* AppTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTests.swift; sourceTree = ""; }; 61C363F224374D6100C4D4E6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 61C363F724374D6100C4D4E6 /* SPMProjectUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SPMProjectUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 61C363FB24374D6100C4D4E6 /* SPMProjectUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPMProjectUITests.swift; sourceTree = ""; }; + 61C363F724374D6100C4D4E6 /* App iOS UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App iOS UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 61C363FB24374D6100C4D4E6 /* AppUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUITests.swift; sourceTree = ""; }; 61C363FD24374D6100C4D4E6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61CE5FD52461D3C2005EA621 /* Datadog.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Datadog.xcconfig; sourceTree = ""; }; 61CE5FD62461D3C2005EA621 /* Datadog.local.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Datadog.local.xcconfig; sourceTree = ""; }; + D23BF5FE27CCCC3300BB4CCD /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; + D23BF60A27CCCCF800BB4CCD /* App tvOS UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App tvOS UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + D23BF61627CCCD5700BB4CCD /* App tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "App tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -88,6 +117,28 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D23BF5F627CCCC3300BB4CCD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D23BF5F727CCCC3300BB4CCD /* DatadogCrashReporting in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D23BF60527CCCCF800BB4CCD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D23BF61127CCCD5700BB4CCD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -95,9 +146,9 @@ isa = PBXGroup; children = ( 61CE5FD42461D3C2005EA621 /* xcconfigs */, - 61C363D824374D5F00C4D4E6 /* SPMProject */, - 61C363EF24374D6100C4D4E6 /* SPMProjectTests */, - 61C363FA24374D6100C4D4E6 /* SPMProjectUITests */, + 61C363D824374D5F00C4D4E6 /* App */, + 61C363EF24374D6100C4D4E6 /* AppTests */, + 61C363FA24374D6100C4D4E6 /* AppUITests */, 61C363D724374D5F00C4D4E6 /* Products */, 9EC32C6024E596C20063BCCE /* Frameworks */, ); @@ -106,42 +157,43 @@ 61C363D724374D5F00C4D4E6 /* Products */ = { isa = PBXGroup; children = ( - 61C363D624374D5F00C4D4E6 /* SPMProject.app */, - 61C363EC24374D6100C4D4E6 /* SPMProjectTests.xctest */, - 61C363F724374D6100C4D4E6 /* SPMProjectUITests.xctest */, + 61C363D624374D5F00C4D4E6 /* App.app */, + 61C363EC24374D6100C4D4E6 /* App iOS Tests.xctest */, + 61C363F724374D6100C4D4E6 /* App iOS UITests.xctest */, + D23BF5FE27CCCC3300BB4CCD /* App.app */, + D23BF60A27CCCCF800BB4CCD /* App tvOS UITests.xctest */, + D23BF61627CCCD5700BB4CCD /* App tvOS Tests.xctest */, ); name = Products; sourceTree = ""; }; - 61C363D824374D5F00C4D4E6 /* SPMProject */ = { + 61C363D824374D5F00C4D4E6 /* App */ = { isa = PBXGroup; children = ( 61C363D924374D5F00C4D4E6 /* AppDelegate.swift */, 61C363DB24374D5F00C4D4E6 /* SceneDelegate.swift */, 61C363DD24374D5F00C4D4E6 /* ViewController.swift */, - 61C363DF24374D5F00C4D4E6 /* Main.storyboard */, - 61C363E424374D6000C4D4E6 /* LaunchScreen.storyboard */, 61C363E724374D6000C4D4E6 /* Info.plist */, ); - path = SPMProject; + path = App; sourceTree = ""; }; - 61C363EF24374D6100C4D4E6 /* SPMProjectTests */ = { + 61C363EF24374D6100C4D4E6 /* AppTests */ = { isa = PBXGroup; children = ( - 61C363F024374D6100C4D4E6 /* SPMProjectTests.swift */, + 61C363F024374D6100C4D4E6 /* AppTests.swift */, 61C363F224374D6100C4D4E6 /* Info.plist */, ); - path = SPMProjectTests; + path = AppTests; sourceTree = ""; }; - 61C363FA24374D6100C4D4E6 /* SPMProjectUITests */ = { + 61C363FA24374D6100C4D4E6 /* AppUITests */ = { isa = PBXGroup; children = ( - 61C363FB24374D6100C4D4E6 /* SPMProjectUITests.swift */, + 61C363FB24374D6100C4D4E6 /* AppUITests.swift */, 61C363FD24374D6100C4D4E6 /* Info.plist */, ); - path = SPMProjectUITests; + path = AppUITests; sourceTree = ""; }; 61CE5FD42461D3C2005EA621 /* xcconfigs */ = { @@ -164,9 +216,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 61C363D524374D5F00C4D4E6 /* SPMProject */ = { + 61C363D524374D5F00C4D4E6 /* App iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 61C3640024374D6100C4D4E6 /* Build configuration list for PBXNativeTarget "SPMProject" */; + buildConfigurationList = 61C3640024374D6100C4D4E6 /* Build configuration list for PBXNativeTarget "App iOS" */; buildPhases = ( 61C363D224374D5F00C4D4E6 /* Sources */, 61C363D324374D5F00C4D4E6 /* Frameworks */, @@ -178,17 +230,17 @@ ); dependencies = ( ); - name = SPMProject; + name = "App iOS"; packageProductDependencies = ( 9E73373F26B0123500917C24 /* DatadogCrashReporting */, ); productName = SPMProject; - productReference = 61C363D624374D5F00C4D4E6 /* SPMProject.app */; + productReference = 61C363D624374D5F00C4D4E6 /* App.app */; productType = "com.apple.product-type.application"; }; - 61C363EB24374D6100C4D4E6 /* SPMProjectTests */ = { + 61C363EB24374D6100C4D4E6 /* App iOS Tests */ = { isa = PBXNativeTarget; - buildConfigurationList = 61C3640324374D6100C4D4E6 /* Build configuration list for PBXNativeTarget "SPMProjectTests" */; + buildConfigurationList = 61C3640324374D6100C4D4E6 /* Build configuration list for PBXNativeTarget "App iOS Tests" */; buildPhases = ( 61C363E824374D6100C4D4E6 /* Sources */, 61C363E924374D6100C4D4E6 /* Frameworks */, @@ -199,14 +251,14 @@ dependencies = ( 61C363EE24374D6100C4D4E6 /* PBXTargetDependency */, ); - name = SPMProjectTests; + name = "App iOS Tests"; productName = SPMProjectTests; - productReference = 61C363EC24374D6100C4D4E6 /* SPMProjectTests.xctest */; + productReference = 61C363EC24374D6100C4D4E6 /* App iOS Tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 61C363F624374D6100C4D4E6 /* SPMProjectUITests */ = { + 61C363F624374D6100C4D4E6 /* App iOS UITests */ = { isa = PBXNativeTarget; - buildConfigurationList = 61C3640624374D6100C4D4E6 /* Build configuration list for PBXNativeTarget "SPMProjectUITests" */; + buildConfigurationList = 61C3640624374D6100C4D4E6 /* Build configuration list for PBXNativeTarget "App iOS UITests" */; buildPhases = ( 61C363F324374D6100C4D4E6 /* Sources */, 61C363F424374D6100C4D4E6 /* Frameworks */, @@ -217,11 +269,69 @@ dependencies = ( 61C363F924374D6100C4D4E6 /* PBXTargetDependency */, ); - name = SPMProjectUITests; + name = "App iOS UITests"; productName = SPMProjectUITests; - productReference = 61C363F724374D6100C4D4E6 /* SPMProjectUITests.xctest */; + productReference = 61C363F724374D6100C4D4E6 /* App iOS UITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; + D23BF5EF27CCCC3300BB4CCD /* App tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D23BF5FB27CCCC3300BB4CCD /* Build configuration list for PBXNativeTarget "App tvOS" */; + buildPhases = ( + D23BF5F227CCCC3300BB4CCD /* Sources */, + D23BF5F627CCCC3300BB4CCD /* Frameworks */, + D23BF5F827CCCC3300BB4CCD /* Resources */, + D23BF5F927CCCC3300BB4CCD /* ⚙️ Run linter */, + D23BF5FA27CCCC3300BB4CCD /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "App tvOS"; + packageProductDependencies = ( + D23BF5F027CCCC3300BB4CCD /* DatadogCrashReporting */, + ); + productName = SPMProject; + productReference = D23BF5FE27CCCC3300BB4CCD /* App.app */; + productType = "com.apple.product-type.application"; + }; + D23BF60027CCCCF800BB4CCD /* App tvOS UITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D23BF60727CCCCF800BB4CCD /* Build configuration list for PBXNativeTarget "App tvOS UITests" */; + buildPhases = ( + D23BF60327CCCCF800BB4CCD /* Sources */, + D23BF60527CCCCF800BB4CCD /* Frameworks */, + D23BF60627CCCCF800BB4CCD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D23BF61B27CCCE2700BB4CCD /* PBXTargetDependency */, + ); + name = "App tvOS UITests"; + productName = SPMProjectUITests; + productReference = D23BF60A27CCCCF800BB4CCD /* App tvOS UITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + D23BF60C27CCCD5700BB4CCD /* App tvOS Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D23BF61327CCCD5700BB4CCD /* Build configuration list for PBXNativeTarget "App tvOS Tests" */; + buildPhases = ( + D23BF60F27CCCD5700BB4CCD /* Sources */, + D23BF61127CCCD5700BB4CCD /* Frameworks */, + D23BF61227CCCD5700BB4CCD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D23BF61927CCCE2300BB4CCD /* PBXTargetDependency */, + ); + name = "App tvOS Tests"; + productName = SPMProjectTests; + productReference = D23BF61627CCCD5700BB4CCD /* App tvOS Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -229,7 +339,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1140; - LastUpgradeCheck = 1140; + LastUpgradeCheck = 1310; ORGANIZATIONNAME = Datadog; TargetAttributes = { 61C363D524374D5F00C4D4E6 = { @@ -243,6 +353,12 @@ CreatedOnToolsVersion = 11.4; TestTargetID = 61C363D524374D5F00C4D4E6; }; + D23BF60027CCCCF800BB4CCD = { + TestTargetID = D23BF5EF27CCCC3300BB4CCD; + }; + D23BF60C27CCCD5700BB4CCD = { + TestTargetID = D23BF5EF27CCCC3300BB4CCD; + }; }; }; buildConfigurationList = 61C363D124374D5F00C4D4E6 /* Build configuration list for PBXProject "SPMProject" */; @@ -261,9 +377,12 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 61C363D524374D5F00C4D4E6 /* SPMProject */, - 61C363EB24374D6100C4D4E6 /* SPMProjectTests */, - 61C363F624374D6100C4D4E6 /* SPMProjectUITests */, + 61C363D524374D5F00C4D4E6 /* App iOS */, + 61C363EB24374D6100C4D4E6 /* App iOS Tests */, + 61C363F624374D6100C4D4E6 /* App iOS UITests */, + D23BF5EF27CCCC3300BB4CCD /* App tvOS */, + D23BF60C27CCCD5700BB4CCD /* App tvOS Tests */, + D23BF60027CCCCF800BB4CCD /* App tvOS UITests */, ); }; /* End PBXProject section */ @@ -273,8 +392,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61C363E624374D6000C4D4E6 /* LaunchScreen.storyboard in Resources */, - 61C363E124374D5F00C4D4E6 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -292,6 +409,27 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D23BF5F827CCCC3300BB4CCD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D23BF60627CCCCF800BB4CCD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D23BF61227CCCD5700BB4CCD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -314,6 +452,25 @@ shellScript = "if which swiftlint >/dev/null; then\n cd ${SOURCE_ROOT}/../../\n ./tools/lint/run-linter.sh\nfi\n"; showEnvVarsInLog = 0; }; + D23BF5F927CCCC3300BB4CCD /* ⚙️ Run linter */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "⚙️ Run linter"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\n cd ${SOURCE_ROOT}/../../\n ./tools/lint/run-linter.sh\nfi\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -331,7 +488,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61C363F124374D6100C4D4E6 /* SPMProjectTests.swift in Sources */, + 61C363F124374D6100C4D4E6 /* AppTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -339,7 +496,33 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61C363FC24374D6100C4D4E6 /* SPMProjectUITests.swift in Sources */, + 61C363FC24374D6100C4D4E6 /* AppUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D23BF5F227CCCC3300BB4CCD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D23BF5F327CCCC3300BB4CCD /* ViewController.swift in Sources */, + D23BF5F427CCCC3300BB4CCD /* AppDelegate.swift in Sources */, + D23BF5F527CCCC3300BB4CCD /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D23BF60327CCCCF800BB4CCD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D23BF60427CCCCF800BB4CCD /* AppUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D23BF60F27CCCD5700BB4CCD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D23BF61027CCCD5700BB4CCD /* AppTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -348,34 +531,25 @@ /* Begin PBXTargetDependency section */ 61C363EE24374D6100C4D4E6 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61C363D524374D5F00C4D4E6 /* SPMProject */; + target = 61C363D524374D5F00C4D4E6 /* App iOS */; targetProxy = 61C363ED24374D6100C4D4E6 /* PBXContainerItemProxy */; }; 61C363F924374D6100C4D4E6 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61C363D524374D5F00C4D4E6 /* SPMProject */; + target = 61C363D524374D5F00C4D4E6 /* App iOS */; targetProxy = 61C363F824374D6100C4D4E6 /* PBXContainerItemProxy */; }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 61C363DF24374D5F00C4D4E6 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 61C363E024374D5F00C4D4E6 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; + D23BF61927CCCE2300BB4CCD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D23BF5EF27CCCC3300BB4CCD /* App tvOS */; + targetProxy = D23BF61827CCCE2300BB4CCD /* PBXContainerItemProxy */; }; - 61C363E424374D6000C4D4E6 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 61C363E524374D6000C4D4E6 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; + D23BF61B27CCCE2700BB4CCD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D23BF5EF27CCCC3300BB4CCD /* App tvOS */; + targetProxy = D23BF61A27CCCE2700BB4CCD /* PBXContainerItemProxy */; }; -/* End PBXVariantGroup section */ +/* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 61C363FE24374D6100C4D4E6 /* Debug */ = { @@ -405,6 +579,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -436,6 +611,7 @@ SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TVOS_DEPLOYMENT_TARGET = 13.0; }; name = Debug; }; @@ -466,6 +642,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -490,6 +667,7 @@ SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; + TVOS_DEPLOYMENT_TARGET = 13.0; VALIDATE_PRODUCT = YES; }; name = Release; @@ -501,13 +679,13 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = SPMProject/Info.plist; + INFOPLIST_FILE = App/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.SPMProject; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = App; PROVISIONING_PROFILE_SPECIFIER = ""; "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; SUPPORTS_MACCATALYST = YES; @@ -523,13 +701,13 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = SPMProject/Info.plist; + INFOPLIST_FILE = App/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.SPMProject; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_NAME = App; PROVISIONING_PROFILE_SPECIFIER = ""; "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; SUPPORTS_MACCATALYST = YES; @@ -547,7 +725,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = SPMProjectTests/Info.plist; + INFOPLIST_FILE = AppTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -559,7 +737,7 @@ "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SPMProject.app/SPMProject"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; }; name = Debug; }; @@ -572,7 +750,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = SPMProjectTests/Info.plist; + INFOPLIST_FILE = AppTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -584,7 +762,7 @@ "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SPMProject.app/SPMProject"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; }; name = Release; }; @@ -595,7 +773,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = SPMProjectUITests/Info.plist; + INFOPLIST_FILE = AppUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -618,7 +796,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = SPMProjectUITests/Info.plist; + INFOPLIST_FILE = AppUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -634,6 +812,144 @@ }; name = Release; }; + D23BF5FC27CCCC3300BB4CCD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = App/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.SPMProject; + PRODUCT_NAME = App; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + D23BF5FD27CCCC3300BB4CCD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = App/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.SPMProject; + PRODUCT_NAME = App; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + D23BF60827CCCCF800BB4CCD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = AppUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.SPMProjectUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = "App tvOS"; + }; + name = Debug; + }; + D23BF60927CCCCF800BB4CCD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = AppUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.SPMProjectUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = "App tvOS"; + }; + name = Release; + }; + D23BF61427CCCD5700BB4CCD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = AppTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.SPMProjectTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; + }; + name = Debug; + }; + D23BF61527CCCD5700BB4CCD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = AppTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.SPMProjectTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; + SDKROOT = appletvos; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/App.app/App"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -646,7 +962,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61C3640024374D6100C4D4E6 /* Build configuration list for PBXNativeTarget "SPMProject" */ = { + 61C3640024374D6100C4D4E6 /* Build configuration list for PBXNativeTarget "App iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 61C3640124374D6100C4D4E6 /* Debug */, @@ -655,7 +971,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61C3640324374D6100C4D4E6 /* Build configuration list for PBXNativeTarget "SPMProjectTests" */ = { + 61C3640324374D6100C4D4E6 /* Build configuration list for PBXNativeTarget "App iOS Tests" */ = { isa = XCConfigurationList; buildConfigurations = ( 61C3640424374D6100C4D4E6 /* Debug */, @@ -664,7 +980,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61C3640624374D6100C4D4E6 /* Build configuration list for PBXNativeTarget "SPMProjectUITests" */ = { + 61C3640624374D6100C4D4E6 /* Build configuration list for PBXNativeTarget "App iOS UITests" */ = { isa = XCConfigurationList; buildConfigurations = ( 61C3640724374D6100C4D4E6 /* Debug */, @@ -673,12 +989,47 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + D23BF5FB27CCCC3300BB4CCD /* Build configuration list for PBXNativeTarget "App tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D23BF5FC27CCCC3300BB4CCD /* Debug */, + D23BF5FD27CCCC3300BB4CCD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D23BF60727CCCCF800BB4CCD /* Build configuration list for PBXNativeTarget "App tvOS UITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D23BF60827CCCCF800BB4CCD /* Debug */, + D23BF60927CCCCF800BB4CCD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D23BF61327CCCD5700BB4CCD /* Build configuration list for PBXNativeTarget "App tvOS Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D23BF61427CCCD5700BB4CCD /* Debug */, + D23BF61527CCCD5700BB4CCD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ 9E73373E26B0123500917C24 /* XCRemoteSwiftPackageReference "dd-sdk-ios" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "GIT_REMOTE"; + repositoryURL = "https://github.com/DataDog/dd-sdk-ios"; + requirement = { + branch = GIT_REFERENCE; + kind = branch; + }; + }; + D23BF5F127CCCC3300BB4CCD /* XCRemoteSwiftPackageReference "dd-sdk-ios" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/DataDog/dd-sdk-ios"; requirement = { branch = GIT_REFERENCE; kind = branch; @@ -692,6 +1043,11 @@ package = 9E73373E26B0123500917C24 /* XCRemoteSwiftPackageReference "dd-sdk-ios" */; productName = DatadogCrashReporting; }; + D23BF5F027CCCC3300BB4CCD /* DatadogCrashReporting */ = { + isa = XCSwiftPackageProductDependency; + package = D23BF5F127CCCC3300BB4CCD /* XCRemoteSwiftPackageReference "dd-sdk-ios" */; + productName = DatadogCrashReporting; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 61C363CE24374D5F00C4D4E6 /* Project object */; diff --git a/dependency-manager-tests/spm/SPMProject.xcodeproj.src/xcshareddata/xcschemes/SPMProject.xcscheme b/dependency-manager-tests/spm/SPMProject.xcodeproj.src/xcshareddata/xcschemes/App iOS.xcscheme similarity index 86% rename from dependency-manager-tests/spm/SPMProject.xcodeproj.src/xcshareddata/xcschemes/SPMProject.xcscheme rename to dependency-manager-tests/spm/SPMProject.xcodeproj.src/xcshareddata/xcschemes/App iOS.xcscheme index 5df5eb0262..f96e09d12b 100644 --- a/dependency-manager-tests/spm/SPMProject.xcodeproj.src/xcshareddata/xcschemes/SPMProject.xcscheme +++ b/dependency-manager-tests/spm/SPMProject.xcodeproj.src/xcshareddata/xcschemes/App iOS.xcscheme @@ -1,6 +1,6 @@ @@ -33,8 +33,8 @@ @@ -43,8 +43,8 @@ @@ -65,8 +65,8 @@ @@ -82,8 +82,8 @@ diff --git a/dependency-manager-tests/spm/SPMProject.xcodeproj.src/xcshareddata/xcschemes/App tvOS.xcscheme b/dependency-manager-tests/spm/SPMProject.xcodeproj.src/xcshareddata/xcschemes/App tvOS.xcscheme new file mode 100644 index 0000000000..84da549a56 --- /dev/null +++ b/dependency-manager-tests/spm/SPMProject.xcodeproj.src/xcshareddata/xcschemes/App tvOS.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dependency-manager-tests/spm/SPMProject/Base.lproj/LaunchScreen.storyboard b/dependency-manager-tests/spm/SPMProject/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 865e9329f3..0000000000 --- a/dependency-manager-tests/spm/SPMProject/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dependency-manager-tests/spm/SPMProject/Base.lproj/Main.storyboard b/dependency-manager-tests/spm/SPMProject/Base.lproj/Main.storyboard deleted file mode 100644 index 924c033e17..0000000000 --- a/dependency-manager-tests/spm/SPMProject/Base.lproj/Main.storyboard +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/README.md b/docs/README.md index 297da221d7..cb1341a48e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,12 @@ # Datadog iOS SDK Documentation -Find in this folder dedicated documentation for: +Find dedicated documentation for the following topics: +* [Set up RUM iOS Monitoring](_index.md). * [Tracking consent API (GDPR)](gdpr.md). * [Collecting and sending logs from your iOS application to Datadog](log_collection.md). * [Collecting and sending traces from your iOS application to Datadog](trace_collection.md). * [Collecting and sending RUM events from your iOS application to Datadog](rum_collection.md). +* [Data collected from your iOS application to Datadog](data_collected.md). +* [Advanced configuration for iOS monitoring](advanced_configuration.md)). +* [Enable crash reporting and error tracking for your iOS applications](crash_reporting.md). \ No newline at end of file diff --git a/docs/log_collection.md b/docs/log_collection.md index 26442324f2..5d86491bdc 100644 --- a/docs/log_collection.md +++ b/docs/log_collection.md @@ -107,95 +107,191 @@ DDConfigurationBuilder *builder = [DDConfiguration builderWithClientToken:@"}} {{< /site-region >}} - To be compliant with the GDPR regulation, the SDK requires the `trackingConsent` value at initialization. - The `trackingConsent` can be one of the following values: +{{< site-region region="us3" >}} +{{< tabs >}} +{{% tab "Swift" %}} - - `.pending` - the SDK starts collecting and batching the data but does not send it to Datadog. The SDK waits for the new tracking consent value to decide what to do with the batched data. - - `.granted` - the SDK starts collecting the data and sends it to Datadog. - - `.notGranted` - the SDK does not collect any data: logs, traces, and RUM events are not sent to Datadog. +```swift +Datadog.initialize( + appContext: .init(), + trackingConsent: trackingConsent, + configuration: Datadog.Configuration + .builderUsing(clientToken: "", environment: "") + .set(serviceName: "app-name") + .set(endpoint: .us3) + .build() +) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDConfigurationBuilder *builder = [DDConfiguration builderWithClientToken:@"" + environment:@""]; +[builder setWithServiceName:@"app-name"]; +[builder setWithEndpoint:[DDEndpoint us3]]; - To change the tracking consent value after the SDK is initialized, use the `Datadog.set(trackingConsent:)` API call. - The SDK changes its behavior according to the new value. For example, if the current tracking consent is `.pending`: +[DDDatadog initializeWithAppContext:[DDAppContext new] + trackingConsent:trackingConsent + configuration:[builder build]]; +``` +{{% /tab %}} +{{< /tabs >}} +{{< /site-region >}} - - if changed to `.granted`, the SDK will send all current and future data to Datadog; - - if changed to `.notGranted`, the SDK will wipe all current data and will not collect any future data. +{{< site-region region="us5" >}} +{{< tabs >}} +{{% tab "Swift" %}} - When writing your application, you can enable development logs. All internal messages in the SDK with a priority equal to or higher than the provided level are then logged to console logs. +```swift +Datadog.initialize( + appContext: .init(), + trackingConsent: trackingConsent, + configuration: Datadog.Configuration + .builderUsing(clientToken: "", environment: "") + .set(serviceName: "app-name") + .set(endpoint: .us5) + .build() +) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDConfigurationBuilder *builder = [DDConfiguration builderWithClientToken:@"" + environment:@""]; +[builder setWithServiceName:@"app-name"]; +[builder setWithEndpoint:[DDEndpoint us5]]; - {{< tabs >}} - {{% tab "Swift" %}} - ```swift - Datadog.verbosityLevel = .debug - ``` - {{% /tab %}} - {{% tab "Objective-C" %}} - ```objective-c - DDDatadog.verbosityLevel = DDSDKVerbosityLevelDebug; - ``` - {{% /tab %}} - {{< /tabs >}} +[DDDatadog initializeWithAppContext:[DDAppContext new] + trackingConsent:trackingConsent + configuration:[builder build]]; +``` +{{% /tab %}} +{{< /tabs >}} +{{< /site-region >}} -3. Configure the `Logger`: +{{< site-region region="gov" >}} +{{< tabs >}} +{{% tab "Swift" %}} - {{< tabs >}} - {{% tab "Swift" %}} - ```swift - let logger = Logger.builder - .sendNetworkInfo(true) - .printLogsToConsole(true, usingFormat: .shortWith(prefix: "[iOS App] ")) +```swift +Datadog.initialize( + appContext: .init(), + trackingConsent: trackingConsent, + configuration: Datadog.Configuration + .builderUsing(clientToken: "", environment: "") + .set(serviceName: "app-name") + .set(endpoint: .us1_fed) .build() - ``` - {{% /tab %}} - {{% tab "Objective-C" %}} - ```objective-c - DDLoggerBuilder *builder = [DDLogger builder]; - [builder sendNetworkInfo:YES]; - [builder printLogsToConsole:YES]; - - DDLogger *logger = [builder build]; - ``` - {{% /tab %}} - {{< /tabs >}} +) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDConfigurationBuilder *builder = [DDConfiguration builderWithClientToken:@"" + environment:@""]; +[builder setWithServiceName:@"app-name"]; +[builder setWithEndpoint:[DDEndpoint us1_fed]]; + +[DDDatadog initializeWithAppContext:[DDAppContext new] + trackingConsent:trackingConsent + configuration:[builder build]]; +``` +{{% /tab %}} +{{< /tabs >}} +{{< /site-region >}} + + +To be compliant with the GDPR regulation, the SDK requires the `trackingConsent` value at initialization. +The `trackingConsent` can be one of the following values: + +- `.pending` - the SDK starts collecting and batching the data but does not send it to Datadog. The SDK waits for the new tracking consent value to decide what to do with the batched data. +- `.granted` - the SDK starts collecting the data and sends it to Datadog. +- `.notGranted` - the SDK does not collect any data: logs, traces, and RUM events are not sent to Datadog. + +To change the tracking consent value after the SDK is initialized, use the `Datadog.set(trackingConsent:)` API call. +The SDK changes its behavior according to the new value. For example, if the current tracking consent is `.pending`: + +- if changed to `.granted`, the SDK will send all current and future data to Datadog; +- if changed to `.notGranted`, the SDK will wipe all current data and will not collect any future data. + +Before data is uploaded to Datadog, it is stored in cleartext in the cache directory (`Library/Caches`) of your [application sandbox][6], which can't be read by any other app installed on the device. + +When writing your application, enable development logs to log to console all internal messages in the SDK with a priority equal to or higher than the provided level. + +{{< tabs >}} +{{% tab "Swift" %}} +```swift +Datadog.verbosityLevel = .debug +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDDatadog.verbosityLevel = DDSDKVerbosityLevelDebug; +``` +{{% /tab %}} +{{< /tabs >}} + +3. Configure the `Logger`: + +{{< tabs >}} +{{% tab "Swift" %}} +```swift +let logger = Logger.builder + .sendNetworkInfo(true) + .printLogsToConsole(true, usingFormat: .shortWith(prefix: "[iOS App] ")) + .build() +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDLoggerBuilder *builder = [DDLogger builder]; +[builder sendNetworkInfo:YES]; +[builder printLogsToConsole:YES]; + +DDLogger *logger = [builder build]; +``` +{{% /tab %}} +{{< /tabs >}} 4. Send a custom log entry directly to Datadog with one of the following methods: - {{< tabs >}} - {{% tab "Swift" %}} - ```swift - logger.debug("A debug message.") - logger.info("Some relevant information?") - logger.notice("Have you noticed?") - logger.warn("An important warning…") - logger.error("An error was met!") - logger.critical("Something critical happened!") - ``` - {{% /tab %}} - {{% tab "Objective-C" %}} - ```objective-c - [logger debug:@"A debug message."]; - [logger info:@"Some relevant information?"]; - [logger notice:@"Have you noticed?"]; - [logger warn:@"An important warning…"]; - [logger error:@"An error was met!"]; - [logger critical:@"Something critical happened!"]; - ``` - {{% /tab %}} - {{< /tabs >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +logger.debug("A debug message.") +logger.info("Some relevant information?") +logger.notice("Have you noticed?") +logger.warn("An important warning…") +logger.error("An error was met!") +logger.critical("Something critical happened!") +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +[logger debug:@"A debug message."]; +[logger info:@"Some relevant information?"]; +[logger notice:@"Have you noticed?"]; +[logger warn:@"An important warning…"]; +[logger error:@"An error was met!"]; +[logger critical:@"Something critical happened!"]; +``` +{{% /tab %}} +{{< /tabs >}} 5. (Optional) - Provide a map of `attributes` alongside your log message to add attributes to the emitted log. Each entry of the map is added as an attribute. - {{< tabs >}} - {{% tab "Swift" %}} - ```swift - logger.info("Clicked OK", attributes: ["context": "onboarding flow"]) - ``` - {{% /tab %}} - {{% tab "Objective-C" %}} - ```objective-c - [logger info:@"Clicked OK" attributes:@{@"context": @"onboarding flow"}]; - ``` - {{% /tab %}} - {{< /tabs >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +logger.info("Clicked OK", attributes: ["context": "onboarding flow"]) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +[logger info:@"Clicked OK" attributes:@{@"context": @"onboarding flow"}]; +``` +{{% /tab %}} +{{< /tabs >}} ## Advanced logging @@ -316,3 +412,4 @@ logger.removeAttribute(forKey: "device-model") [3]: https://docs.datadoghq.com/account_management/api-app-keys/#api-keys [4]: https://docs.datadoghq.com/logs/processing/attributes_naming_convention/ [5]: https://docs.datadoghq.com/tagging/ +[6]: https://support.apple.com/guide/security/security-of-runtime-process-sec15bfe098e/web diff --git a/docs/rum_collection/_index.md b/docs/rum_collection/_index.md index d22856d1d7..2540d812e1 100644 --- a/docs/rum_collection/_index.md +++ b/docs/rum_collection/_index.md @@ -65,6 +65,9 @@ Datadog.initialize( ) .set(serviceName: "app-name") .set(endpoint: .us1) + .trackUIKitRUMViews() + .trackUIKitActions() + .trackURLSession() .build() ) ``` @@ -76,6 +79,9 @@ DDConfigurationBuilder *builder = [DDConfiguration builderWithRumApplicationID:@ environment:@""]; [builder setWithServiceName:@"app-name"]; [builder setWithEndpoint:[DDEndpoint us1]]; +[builder trackUIKitRUMViews]; +[builder trackUIKitRUMActions]; +[builder trackURLSessionWithFirstPartyHosts:[NSSet new]]; [DDDatadog initializeWithAppContext:[DDAppContext new] trackingConsent:trackingConsent @@ -99,6 +105,7 @@ Datadog.initialize( environment: "" ) .set(serviceName: "app-name") + .set(endpoint: .eu1) .trackUIKitRUMViews() .trackUIKitActions() .trackURLSession() @@ -112,7 +119,130 @@ DDConfigurationBuilder *builder = [DDConfiguration builderWithRumApplicationID:@ clientToken:@"" environment:@""]; [builder setWithServiceName:@"app-name"]; -[builder setWithEndpoint:[DDEndpoint us1]]; +[builder setWithEndpoint:[DDEndpoint eu1]]; +[builder trackUIKitRUMViews]; +[builder trackUIKitRUMActions]; +[builder trackURLSessionWithFirstPartyHosts:[NSSet new]]; + +[DDDatadog initializeWithAppContext:[DDAppContext new] + trackingConsent:trackingConsent + configuration:[builder build]]; +``` +{{% /tab %}} +{{< /tabs >}} +{{< /site-region >}} + +{{< site-region region="us3" >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +Datadog.initialize( + appContext: .init(), + trackingConsent: trackingConsent, + configuration: Datadog.Configuration + .builderUsing( + rumApplicationID: "", + clientToken: "", + environment: "" + ) + .set(serviceName: "app-name") + .set(endpoint: .us3) + .trackUIKitRUMViews() + .trackUIKitActions() + .trackURLSession() + .build() +) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDConfigurationBuilder *builder = [DDConfiguration builderWithRumApplicationID:@"" + clientToken:@"" + environment:@""]; +[builder setWithServiceName:@"app-name"]; +[builder setWithEndpoint:[DDEndpoint us3]]; +[builder trackUIKitRUMViews]; +[builder trackUIKitRUMActions]; +[builder trackURLSessionWithFirstPartyHosts:[NSSet new]]; + +[DDDatadog initializeWithAppContext:[DDAppContext new] + trackingConsent:trackingConsent + configuration:[builder build]]; +``` +{{% /tab %}} +{{< /tabs >}} +{{< /site-region >}} + +{{< site-region region="us5" >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +Datadog.initialize( + appContext: .init(), + trackingConsent: trackingConsent, + configuration: Datadog.Configuration + .builderUsing( + rumApplicationID: "", + clientToken: "", + environment: "" + ) + .set(serviceName: "app-name") + .set(endpoint: .us5) + .trackUIKitRUMViews() + .trackUIKitActions() + .trackURLSession() + .build() +) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDConfigurationBuilder *builder = [DDConfiguration builderWithRumApplicationID:@"" + clientToken:@"" + environment:@""]; +[builder setWithServiceName:@"app-name"]; +[builder setWithEndpoint:[DDEndpoint us5]]; +[builder trackUIKitRUMViews]; +[builder trackUIKitRUMActions]; +[builder trackURLSessionWithFirstPartyHosts:[NSSet new]]; + +[DDDatadog initializeWithAppContext:[DDAppContext new] + trackingConsent:trackingConsent + configuration:[builder build]]; +``` +{{% /tab %}} +{{< /tabs >}} +{{< /site-region >}} + +{{< site-region region="gov" >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +Datadog.initialize( + appContext: .init(), + trackingConsent: trackingConsent, + configuration: Datadog.Configuration + .builderUsing( + rumApplicationID: "", + clientToken: "", + environment: "" + ) + .set(serviceName: "app-name") + .set(endpoint: .us1_fed) + .trackUIKitRUMViews() + .trackUIKitActions() + .trackURLSession() + .build() +) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDConfigurationBuilder *builder = [DDConfiguration builderWithRumApplicationID:@"" + clientToken:@"" + environment:@""]; +[builder setWithServiceName:@"app-name"]; +[builder setWithEndpoint:[DDEndpoint us1_fed]]; [builder trackUIKitRUMViews]; [builder trackUIKitRUMActions]; [builder trackURLSessionWithFirstPartyHosts:[NSSet new]]; @@ -188,5 +318,5 @@ Crash Reporting and Error Tracking for iOS displays any issues and latest availa [5]: https://app.datadoghq.com/rum/create [6]: https://docs.datadoghq.com/account_management/api-app-keys/#api-keys [7]: https://docs.datadoghq.com/account_management/api-app-keys/#client-tokens -[8]: /real_user_monitoring/ios/advanced_configuration/#set-tracking-consent-gdpr-compliance -[9]: /real_user_monitoring/ios/advanced_configuration/#initialization-parameters \ No newline at end of file +[8]: https://docs.datadoghq.com/real_user_monitoring/ios/advanced_configuration/#set-tracking-consent-gdpr-compliance +[9]: https://docs.datadoghq.com/real_user_monitoring/ios/advanced_configuration/#initialization-parameters \ No newline at end of file diff --git a/docs/rum_collection/advanced_configuration.md b/docs/rum_collection/advanced_configuration.md index a9a8664f67..3813840b9a 100644 --- a/docs/rum_collection/advanced_configuration.md +++ b/docs/rum_collection/advanced_configuration.md @@ -4,10 +4,10 @@ kind: documentation further_reading: - link: "https://github.com/DataDog/dd-sdk-ios" tag: "Github" - text: "dd-sdk-ios Source code" + text: "dd-sdk-ios Source Code" - link: "/real_user_monitoring" tag: "Documentation" - text: "Datadog Real User Monitoring" + text: "RUM & Session Replay" --- If you have not set up the SDK yet, follow the [in-app setup instructions][1] or refer to the [iOS RUM setup documentation][2]. @@ -18,12 +18,12 @@ iOS RUM automatically tracks attributes such as user activity, screens, errors, ### Custom Views -In addition to [tracking views automatically][4], you can also track specific distinct views (viewControllers) when they become visible and interactive. Stop tracking when the view is no longer visible using the following methods in `Global.rum`: +In addition to [tracking views automatically](#automatically-track-views), you can also track specific distinct views such as `viewControllers` when they become visible and interactive. Stop tracking when the view is no longer visible using the following methods in `Global.rum`: - `.startView(viewController:)` - `.stopView(viewController:)` -Example: +For example: {{< tabs >}} {{% tab "Swift" %}} @@ -40,6 +40,7 @@ override func viewDidDisappear(_ animated: Bool) { Global.rum.stopView(viewController: self) } ``` + {{% /tab %}} {{% tab "Objective-C" %}} ```objective-c @@ -60,11 +61,13 @@ override func viewDidDisappear(_ animated: Bool) { {{% /tab %}} {{< /tabs >}} -Find more details and available options in `DDRUMMonitor` class. +Find more details and available options in the [`DDRUMMonitor` class][9]. ### Add your own performance timing -In addition to RUM’s default attributes, you can measure where your application is spending its time by using the `addTiming(name:)` API. The timing measure is relative to the start of the current RUM view. For example, you can time how long it takes for your hero image to appear: +In addition to RUM’s default attributes, you can measure where your application is spending its time by using the `addTiming(name:)` API. The timing measure is relative to the start of the current RUM view. + +For example, you can time how long it takes for your hero image to appear: {{< tabs >}} {{% tab "Swift" %}} @@ -83,19 +86,18 @@ func onHeroImageLoaded() { {{% /tab %}} {{< /tabs >}} -Once the timing is sent, the timing will be accessible as `@view.custom_timings.` (For example, `@view.custom_timings.hero_image`). You must [create a measure][5] before graphing it in RUM analytics or in dashboards. +Once you set the timing, it is accessible as `@view.custom_timings.`. For example, `@view.custom_timings.hero_image`. +To create visualizations in your dashboards, [create a measure][4] first. ### Custom Actions -In addition to [tracking actions automatically][6], you can also track specific custom user actions (taps, clicks, scrolls, etc.) with `addUserAction(type:name:)` API. To manually register instantaneous RUM actions (e.g: `.tap`), on `Global.rum` use: -- `.addUserAction(type:name:)` +In addition to [tracking actions automatically](#automatically-track-user-actions), you can track specific custom user actions (taps, clicks, and scrolls) with the `addUserAction(type:name:)` API. + +To manually register instantaneous RUM actions such as `.tap` on `Global.rum`, use `.addUserAction(type:name:)`. For continuous RUM actions such as `.scroll`, use `.startUserAction(type:name:)` or `.stopUserAction(type:)`. -or for continuous RUM actions (e.g: `.scroll`), use: -- `.startUserAction(type:name:)` -- `.stopUserAction(type:)` +For example: -Example: {{< tabs >}} {{% tab "Swift" %}} ```swift @@ -121,17 +123,18 @@ Example: **Note**: When using `.startUserAction(type:name:)` and `.stopUserAction(type:)`, the action `type` must be the same. This is necessary for the SDK to match an action start with its completion. -Find more details and available options in `DDRUMMonitor` class. +Find more details and available options in the [`DDRUMMonitor` class][9]. ### Custom Resources -In addition to [tracking resources automatically][7], you can also track specific custom resources, such as network requests or third party provider APIs. Use the following methods on `Global.rum` to manually collect RUM resources: +In addition to [tracking resources automatically](#automatically-track-network-requests), you can also track specific custom resources such as network requests or third party provider APIs. Use the following methods on `Global.rum` to manually collect RUM resources: - `.startResourceLoading(resourceKey:request:)` - `.stopResourceLoading(resourceKey:response:)` - `.stopResourceLoadingWithError(resourceKey:error:)` - `.stopResourceLoadingWithError(resourceKey:errorMessage:)` -Example: +For example: + {{< tabs >}} {{% tab "Swift" %}} ```swift @@ -165,11 +168,11 @@ Global.rum.stopResourceLoading( **Note**: The `String` used for `resourceKey` in both calls must be unique for the resource you are calling. This is necessary for the SDK to match a resource's start with its completion. -Find more details and available options in `DDRUMMonitor` class. +Find more details and available options in the [`DDRUMMonitor` class][9]. ### Custom Errors -To track specific errors, notify `Global.rum` when an error occurs with the message, source, exception, and additional attributes. Refer to the [Error Attributes documentation][8]. +To track specific errors, notify `Global.rum` when an error occurs with the message, source, exception, and additional attributes. Refer to the [Error Attributes documentation][5]. {{< tabs >}} {{% tab "Swift" %}} @@ -184,14 +187,13 @@ Global.rum.addError(message: "error message.") {{% /tab %}} {{< /tabs >}} -For more details and available options, refer to the code documentation comments in `DDRUMMonitor` class. - +For more details and available options, refer to the code documentation comments in the [`DDRUMMonitor` class][9]. ## Track custom global attributes -In addition to the [default RUM attributes][11] captured by the mobile SDK automatically, you can choose to add additional contextual information, such as custom attributes, to your RUM events to enrich your observability within Datadog. +In addition to the [default RUM attributes][7] captured by the mobile SDK automatically, you can choose to add additional contextual information (such as custom attributes) to your RUM events to enrich your observability within Datadog. -Custom attributes allow you to filter and group information about observed user behavior (such as cart value, merchant tier, or ad campaign) with code-level information (such as backend services, session timeline, error logs, and network health). +Custom attributes allow you to filter and group information about observed user behavior (such as the cart value, merchant tier, or ad campaign) with code-level information (such as backend services, session timeline, error logs, and network health). ### Set a custom global attribute @@ -219,7 +221,9 @@ The following attributes are **optional**, you should provide **at least one** o | `usr.name` | String | User friendly name, displayed by default in the RUM UI. | | `usr.email` | String | User email, displayed in the RUM UI if the user name is not present. It is also used to fetch Gravatars. | -To identify user sessions, use the `setUserInfo(id:name:email:)` API, for example: +To identify user sessions, use the `setUserInfo(id:name:email:)` API. + +For example: {{< tabs >}} {{% tab "Swift" %}} @@ -242,10 +246,10 @@ You can use the following methods in `Datadog.Configuration.Builder` when creati : Sets the Datadog server endpoint that data is sent to. `set(batchSize: BatchSize)` -: Sets the preferred size of batched data uploaded to Datadog. This value impacts the size and number of requests performed by the SDK (small batches mean more requests, but each will be smaller in size). Available values are: `.small`, `.medium` and `.large`. +: Sets the preferred size of batched data uploaded to Datadog. This value impacts the size and number of requests performed by the SDK (small batches mean more requests, but each request becomes smaller in size). Available values include: `.small`, `.medium`, and `.large`. `set(uploadFrequency: UploadFrequency)` -: Sets the preferred frequency of uploading data to Datadog. Available values are: `.frequent`, `.average` and `.rare`. +: Sets the preferred frequency of uploading data to Datadog. Available values include: `.frequent`, `.average`, and `.rare`. ### RUM configuration @@ -253,10 +257,10 @@ You can use the following methods in `Datadog.Configuration.Builder` when creati : Enables or disables the RUM feature. `set(rumSessionsSamplingRate: Float)` -: Sets the sampling rate for RUM sessions. The `rumSessionsSamplingRate` value must be between `0.0` and `100.0`. A value of `0.0` means no sessions will be sent, `100.0` means all sessions will be sent to Datadog. If not configured, the default value of `100.0` is used. +: Sets the sampling rate for RUM sessions. The `rumSessionsSamplingRate` value must be between `0.0` and `100.0`. A value of `0.0` means no sessions are sent, `100.0` means all sessions are sent to Datadog. If not configured, the default value of `100.0` is used. `trackUIKitRUMViews(using predicate: UIKitRUMViewsPredicate)` -: Enables tracking `UIViewControllers` as RUM views. You can use default implementation of `predicate` by calling this API with no parameter (`trackUIKitRUMViews()`) or implement [your own `UIKitRUMViewsPredicate`][4] customized for your app. +: Enables tracking `UIViewControllers` as RUM views. You can use default implementation of `predicate` by calling this API with no parameter (`trackUIKitRUMViews()`) or implement [your own `UIKitRUMViewsPredicate`](#automatically-track-views) customized for your app. `trackUIKitActions(_ enabled: Bool)` : Enables tracking user interactions (taps) as RUM actions. @@ -265,16 +269,16 @@ You can use the following methods in `Datadog.Configuration.Builder` when creati : Enables tracking `URLSession` tasks (network requests) as RUM resources. The `firstPartyHosts` parameter defines hosts that are categorized as `first-party` resources (if RUM is enabled) and have tracing information injected (if tracing feature is enabled). `setRUMViewEventMapper(_ mapper: @escaping (RUMViewEvent) -> RUMViewEvent)` -: Sets the data scrubbing callback for views. This can be used to modify view events before they are sent to Datadog - see [Modify or drop RUM events][9] for more. +: Sets the data scrubbing callback for views. This can be used to modify view events before they are sent to Datadog. For more information, see [Modify or drop RUM events](#modify-or-drop-rum-events). `setRUMResourceEventMapper(_ mapper: @escaping (RUMResourceEvent) -> RUMResourceEvent?)` -: Sets the data scrubbing callback for resources. This can be used to modify or drop resource events before they are sent to Datadog - see [Modify or drop RUM events][9] for more. +: Sets the data scrubbing callback for resources. This can be used to modify or drop resource events before they are sent to Datadog. For more information, see [Modify or drop RUM events](#modify-or-drop-rum-events). `setRUMActionEventMapper(_ mapper: @escaping (RUMActionEvent) -> RUMActionEvent?)` -: Sets the data scrubbing callback for actions. This can be used to modify or drop action events before they are sent to Datadog - see [Modify or drop RUM events][9] for more. +: Sets the data scrubbing callback for actions. This can be used to modify or drop action events before they are sent to Datadog. For more information, see [Modify or drop RUM events](#modify-or-drop-rum-events). `setRUMErrorEventMapper(_ mapper: @escaping (RUMErrorEvent) -> RUMErrorEvent?)` -: Sets the data scrubbing callback for errors. This can be used to modify or drop error events before they are sent to Datadog - see [Modify or drop RUM events][9] for more. +: Sets the data scrubbing callback for errors. This can be used to modify or drop error events before they are sent to Datadog. For more information, see [Modify or drop RUM events](#modify-or-drop-rum-events). `setRUMResourceAttributesProvider(_ provider: @escaping (URLRequest, URLResponse?, Data?, Error?) -> [AttributeKey: AttributeValue]?)` : Sets a closure to provide custom attributes for intercepted resources. The `provider` closure is called for each resource collected by the SDK. This closure is called with task information and may return custom resource attributes or `nil` if no attributes should be attached. @@ -317,6 +321,7 @@ public protocol DDUIKitRUMViewsPredicate: AnyObject { Inside the `rumView(for:)` implementation, your app should decide if a given `UIViewController` instance should start the RUM view (return value) or not (return `nil`). The returned `RUMView` value must specify the `name` and may provide additional `attributes` for created RUM view. For instance, you can configure the predicate to use explicit type check for each view controller in your app: + {{< tabs >}} {{% tab "Swift" %}} ```swift @@ -357,7 +362,9 @@ class YourCustomPredicate: UIKitRUMViewsPredicate { {{% /tab %}} {{< /tabs >}} -You can even come up with a more dynamic solution depending on your app's architecture. For example, if your view controllers use `accessibilityLabel` consistently, you can name views by the value of accessibility label: +You can even come up with a more dynamic solution depending on your app's architecture. + +For example, if your view controllers use `accessibilityLabel` consistently, you can name views by the value of accessibility label: {{< tabs >}} {{% tab "Swift" %}} @@ -424,9 +431,9 @@ NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConf {{% /tab %}} {{< /tabs >}} -Also, you can configure first party hosts using `.trackURLSession(firstPartyHosts:)`. This will classify resources matching given domain as "first party" in RUM and will propagate tracing information to your backend (if Tracing feature is enabled). +Also, you can configure first party hosts using `.trackURLSession(firstPartyHosts:)`. This classifies resources that match the given domain as "first party" in RUM and propagates tracing information to your backend (if you have enabled Tracing). -For instance, you can configure `example.com` as first party host and enable both RUM and Tracing features: +For instance, you can configure `example.com` as the first party host and enable both RUM and Tracing features: {{< tabs >}} {{% tab "Swift" %}} @@ -449,6 +456,9 @@ let session = URLSession( delegateQueue: nil ) ``` + +This tracks all requests sent with the instrumented `session`. Requests matching the `example.com` domain are marked as "first party" and tracing information is sent to your backend to [connect the RUM resource with its Trace][6]. + {{% /tab %}} {{% tab "Objective-C" %}} ```objective-c @@ -470,8 +480,6 @@ DDGlobal.sharedTracer = [[DDTracer alloc] initWithConfiguration:[DDTracerConfigu {{% /tab %}} {{< /tabs >}} -This tracks all requests sent with the instrumented `session`. Requests matching the `example.com` domain are marked as "first party" and tracing information is sent to your backend to [connect the RUM resource with its Trace][10]. - To add custom attributes to resources, use the `.setRUMResourceAttributesProvider(_ :)` option when configuring SDK. By setting attributes provider closure, you can return additional attributes to be attached to tracked resource. For instance, you may want to add HTTP request and response headers to the RUM resource: @@ -483,12 +491,12 @@ For instance, you may want to add HTTP request and response headers to the RUM r "response.headers" : redactedHeaders(from: response) ] } - ``` ### Automatically track errors All "error" and "critical" logs sent with `Logger` are automatically reported as RUM errors and linked to the current RUM view: + {{< tabs >}} {{% tab "Swift" %}} ```swift @@ -508,6 +516,7 @@ DDLogger *logger = [[DDLogger builder] build]; {{< /tabs >}} Similarly, all finished spans marked as error are reported as RUM errors: + {{< tabs >}} {{% tab "Swift" %}} ```swift @@ -578,7 +587,9 @@ DDConfigurationBuilder *builder = [DDConfiguration builderWithRumApplicationID:@ {{% /tab %}} {{< /tabs >}} -Each mapper is a Swift closure with a signature of `(T) -> T?`, where `T` is a concrete RUM event type. This allows changing portions of the event before it is sent. For example, to redact sensitive information in RUM Resource's `url`, implement a custom `redacted(_:) -> String` function and use it in `RUMResourceEventMapper`: +Each mapper is a Swift closure with a signature of `(T) -> T?`, where `T` is a concrete RUM event type. This allows changing portions of the event before it is sent. + +For example, to redact sensitive information in RUM Resource's `url`, implement a custom `redacted(_:) -> String` function and use it in `RUMResourceEventMapper`: {{< tabs >}} {{% tab "Swift" %}} @@ -600,7 +611,7 @@ Each mapper is a Swift closure with a signature of `(T) -> T?`, where `T` is a c {{% /tab %}} {{< /tabs >}} -Returning `nil` from the error, resource, or action mapper drops the event entirely (it won't be sent to Datadog). The value returned from the view event mapper must be not `nil` (to drop views customize your implementation of `UIKitRUMViewsPredicate`. Read more in [tracking views automatically][4]). +Returning `nil` from the error, resource, or action mapper drops the event entirely; the event is not sent to Datadog. The value returned from the view event mapper must not be `nil` (to drop views, customize your implementation of `UIKitRUMViewsPredicate`; read more in [tracking views automatically](#automatically-track-views)). Depending on the event's type, only some specific properties can be modified: @@ -620,23 +631,25 @@ Depending on the event's type, only some specific properties can be modified: ## Set tracking consent (GDPR compliance) To be compliant with the GDPR regulation, the SDK requires the tracking consent value at initialization. + The `trackingConsent` setting can be one of the following values: 1. `.pending` - the SDK starts collecting and batching the data but does not send it to Datadog. The SDK waits for the new tracking consent value to decide what to do with the batched data. 2. `.granted` - the SDK starts collecting the data and sends it to Datadog. -3. `.notGranted` - the SDK does not collect any data: logs, traces, and RUM events are not sent to Datadog. +3. `.notGranted` - the SDK does not collect any data. No logs, traces, or RUM events are sent to Datadog. -To change the tracking consent value after the SDK is initialized, use the `Datadog.set(trackingConsent:)` API call. -The SDK changes its behavior according to the new value. For example, if the current tracking consent is `.pending`: +To change the tracking consent value after the SDK is initialized, use the `Datadog.set(trackingConsent:)` API call. The SDK changes its behavior according to the new value. -- if changed to `.granted`, the SDK will send all current and future data to Datadog; -- if changed to `.notGranted`, the SDK will wipe all current data and will not collect any future data. +For example, if the current tracking consent is `.pending`: + +- If you change the value to `.granted`, the SDK sends all current and future data to Datadog; +- If you change the value to `.notGranted`, the SDK wipes all current data and does not collect future data. ## Sample RUM sessions To control the data your application sends to Datadog RUM, you can specify a sampling rate for RUM sessions while [initializing the SDK][1] as a percentage between 0 and 100. -For instance, to only keep 50% of sessions use: +For example, to only keep 50% of sessions use: {{< tabs >}} {{% tab "Swift" %}} @@ -677,7 +690,9 @@ This means that even if users open your application while offline, no data is lo ## Configuring a custom proxy for Datadog data upload -If your app is running on devices behind a custom proxy, you can let the SDK's data uploader know about it to ensure all tracked data are uploaded with the relevant configuration. You can specify your proxy configuration (as described in the [URLSessionConfiguration.connectionProxyDictionary][12] documentation) when initializing the SDK. +If your app is running on devices behind a custom proxy, you can inform the SDK's data uploader to ensure that all tracked data is uploaded with the relevant configuration. + +When initializing the SDK, specify this in your proxy configuration. {{< tabs >}} {{% tab "Swift" %}} @@ -697,6 +712,7 @@ Datadog.initialize( .build() ) ``` + {{% /tab %}} {{% tab "Objective-C" %}} ```objective-c @@ -720,20 +736,18 @@ DDConfigurationBuilder *builder = [DDConfiguration builderWithRumApplicationID:@ {{% /tab %}} {{< /tabs >}} +For more information, see the [URLSessionConfiguration.connectionProxyDictionary][8] documentation. + ## Further Reading {{< partial name="whats-next/whats-next.html" >}} - [1]: https://app.datadoghq.com/rum/application/create -[2]: /real_user_monitoring/ios -[3]: /real_user_monitoring/ios/data_collected -[4]: #automatically-track-views -[5]: https://docs.datadoghq.com/real_user_monitoring/explorer/?tab=measures#setup-facets-and-measures -[6]: #automatically-track-user-actions -[7]: #automatically-track-network-requests -[8]: /real_user_monitoring/ios/data_collected/?tab=error#error-attributes -[9]: #modify-or-drop-rum-events -[10]: https://docs.datadoghq.com/real_user_monitoring/connect_rum_and_traces?tab=browserrum -[11]: /real_user_monitoring/ios/data_collected?tab=session#default-attributes -[12]: https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1411499-connectionproxydictionary +[2]: https://docs.datadoghq.com/real_user_monitoring/ios +[3]: https://docs.datadoghq.com/real_user_monitoring/ios/data_collected +[4]: https://docs.datadoghq.com/real_user_monitoring/explorer/?tab=measures#setup-facets-and-measures +[5]: https://docs.datadoghq.com/real_user_monitoring/ios/data_collected/?tab=error#error-attributes +[6]: https://docs.datadoghq.com/real_user_monitoring/connect_rum_and_traces?tab=browserrum +[7]: https://docs.datadoghq.com/real_user_monitoring/ios/data_collected?tab=session#default-attributes +[8]: https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1411499-connectionproxydictionary +[9]: https://github.com/DataDog/dd-sdk-ios/blob/master/Sources/Datadog/DDRUMMonitor.swift diff --git a/docs/rum_collection/crash_reporting.md b/docs/rum_collection/crash_reporting.md index e7b9352430..549a86e511 100644 --- a/docs/rum_collection/crash_reporting.md +++ b/docs/rum_collection/crash_reporting.md @@ -15,19 +15,24 @@ further_reading:

iOS Crash Reporting and Error Tracking is in beta. Upgrade to dd-sdk-ios v1.7.0+ to get access.

-Enable iOS Crash Reporting and Error Tracking to get comprehensive crash reports and error trends with Real User Monitoring. With this feature, you get access to: +Enable iOS Crash Reporting and Error Tracking to get comprehensive crash reports and error trends with Real User Monitoring. With this feature, you can access: - Aggregated iOS crash dashboards and attributes - Symbolicated iOS crash reports - Trend analysis with iOS error tracking +In order to symbolicate your stack traces, find and upload your dYSM files to Datadog. Then, verify your configuration by running a test crash and restarting your application. + +Your crash reports appear in [**Error Tracking**][8]. + ## Setup -### Add crash reporting +If you have not set up the iOS SDK yet, follow the [in-app setup instructions][1] or see the [iOS RUM setup documentation][2]. -If you have not set up the SDK yet, follow the [in-app setup instructions][1] or see the [iOS RUM setup documentation][2]. +### Add Crash Reporting + +Add the package according to your dependency manager and update your initialize snippet. -#### Dependency Manager {{< tabs >}} {{% tab "CocoaPods" %}} Add `DatadogSDKCrashReporting` to your `Podfile`: @@ -51,7 +56,7 @@ Add `github "DataDog/dd-sdk-ios"` to your `Cartfile` and link `DatadogCrashRepor {{% /tab %}} {{< /tabs >}} -Update your initialization snippet to include crash reporting: +Update your initialization snippet to include Crash Reporting: ``` import DatadogCrashReporting @@ -73,34 +78,121 @@ Datadog.initialize( Global.rum = RUMMonitor.initialize() ``` -### Symbolicate reports using Datadog CI +## Symbolicate crash reports + +Crash reports are collected in a raw format and mostly contain memory addresses. To map these addresses into legible symbol information, Datadog requires dYSM files, which are generated in your application's build or distribution process. + +### Find your dYSM file + +Every iOS application produces dYSM files for each application module. These files minimize an application's binary size and enable faster download speed. Each application version contains a set of dYSM files. + +Depending on your setup, you may need to download dSYM files from App Store Connect or find them on your local machine. + +| Bitcode Enabled | Description | +|-----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Yes | dSYM files are available once [App Store Connect][6] completes processing your application's build. | +| No | Xcode exports dSYM files to `$DWARF_DSYM_FOLDER_PATH` at the end of your application's build. Ensure that the `DEBUG_INFORMATION_FORMAT` build setting is set to **DWARF with dYSM File**. By default, Xcode projects only set `DEBUG_INFORMATION_FORMAT` to **DWARF with dSYM File** for the Release project configuration. | -If your iOS error is unsymbolicated, upload your dSYM file using [@datadog/datadog-ci][5] to symbolicate your different stack traces. For any given error, you have access to the file path, the line number, and a code snippet for each frame of the related stack trace. +### Upload your dYSM file + +By uploading your dYSM file to Datadog, you gain access to the file path, line number, and code snippet of each frame in an error's related stack trace. + +Once your application crashes and you restart the application, the iOS SDK uploads a crash report to Datadog. + +#### Datadog CI + +You can use the command line tool [@datadog/datadog-ci][5] to upload your dSYM file: ```sh export DATADOG_API_KEY="" -// if you have a zip file containing dSYMs +// if you have a zip file containing dSYM files npx @datadog/datadog-ci dsyms upload appDsyms.zip -// if you have a folder containing dSYMs +// if you have a folder containing dSYM files npx @datadog/datadog-ci dsyms upload /path/to/appDsyms/ ``` -**Note**: To configure the tool to use the EU endpoint, set the `DATADOG_SITE` environment variable to `datadoghq.eu`. To override the full URL for the intake endpoint, define the `DATADOG_DSYM_INTAKE_URL` environment variable. +**Note**: To configure the tool using the EU endpoint, set the `DATADOG_SITE` environment variable to `datadoghq.eu`. To override the full URL for the intake endpoint, define the `DATADOG_DSYM_INTAKE_URL` environment variable. + +Alternatively, if you use Fastlane or GitHub Actions in your workflows, you can leverage these integrations instead of `datadog-ci`: + +#### Fastlane Plugin + +The Datadog plugin helps you upload dSYM files to Datadog from your Fastlane configuration. + +1. Add [`fastlane-plugin-datadog`][3] to your project. + + ```sh + fastlane add_plugin datadog + ``` + +2. Configure Fastlane to upload your symbols. + + ```ruby + # download_dsyms action feeds dsym_paths automatically + lane :upload_dsym_with_download_dsyms do + download_dsyms + upload_symbols_to_datadog(api_key: "datadog-api-key") + end + ``` + +For more information, see [`fastlane-plugin-datadog`][3]. + +#### GitHub Action + +The [Datadog Upload dSYMs GitHub Action][4] allows you to upload your symbols in your GitHub Action jobs: + +```yml +name: Upload dSYM Files + +jobs: + build: + runs-on: macos-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Generate/Download dSYM Files + uses: ./release.sh + + - name: Upload dSYMs to Datadog + uses: DataDog/upload-dsyms-github-action@v1 + with: + api_key: ${{ secrets.DATADOG_API_KEY }} + site: datadoghq.com + dsym_paths: | + path/to/dsyms/folder + path/to/zip/dsyms.zip +``` + +For more information, see [dSYMs commands][7]. + +## Verify crash reports + +To verify your iOS Crash Reporting and Error Tracking configuration, issue a crash in your RUM application and confirm that the error appears in Datadog. + +1. Run your application on an iOS simulator or a real device. Ensure that the debugger is not attached. Otherwise, Xcode captures the crash before the iOS SDK does. +2. Execute the code containing the crash: -If your application has Bitcode enabled, download your app's dSYM files on [App Store Connect][7]. For more information, see [dSYMs commands][8]. + ```swift + func didTapButton() { + fatalError(“Crash the app”) + } + ``` +3. After the crash happens, restart your application and wait for the iOS SDK to upload the crash report in [**Error Tracking**][8]. ## Further Reading {{< partial name="whats-next/whats-next.html" >}} [1]: https://app.datadoghq.com/rum/application/create -[2]: /real_user_monitoring/ios -[3]: https://github.com/DataDog/dd-sdk-ios/releases -[4]: https://github.com/DataDog/datadog-ci +[2]: https://docs.datadoghq.com/real_user_monitoring/ios +[3]: https://github.com/DataDog/datadog-fastlane-plugin +[4]: https://github.com/marketplace/actions/datadog-upload-dsyms [5]: https://www.npmjs.com/package/@datadog/datadog-ci -[6]: https://www.npmjs.com/package/npx -[7]: https://appstoreconnect.apple.com/ -[8]: https://github.com/DataDog/datadog-ci/blob/master/src/commands/dsyms/README.md +[6]: https://appstoreconnect.apple.com/ +[7]: https://github.com/DataDog/datadog-ci/blob/master/src/commands/dsyms/README.md +[8]: https://app.datadoghq.com/rum/error-tracking \ No newline at end of file diff --git a/docs/rum_collection/data_collected.md b/docs/rum_collection/data_collected.md index c680bbeafb..186b9d4026 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -5,17 +5,30 @@ further_reading: - link: "https://github.com/DataDog/dd-sdk-ios" tag: "Github" text: "dd-sdk-ios Source code" - - link: "/real_user_monitoring" + - link: "/real_user_monitoring/" tag: "Documentation" text: "Datadog Real User Monitoring" --- -The RUM SDK generates events that have associated metrics and attributes. Metrics are quantifiable values that can be used for measurements related to the event. Attributes are non-quantifiable values used to slice metrics data (group by) in analytics. -Every RUM event has all of the [default attributes](#default-attributes), for example, the device type (`device.type`) and user information such as their name (`usr.name`) and their country (`geo.country`). +## Overview -There are additional [metrics and attributes that are specific to a given event type](#event-specific-metrics-and-attributes). For example, the metric `view.time_spent` is associated with "view" events and the attribute `resource.method` is associated with "resource" events. +The RUM iOS SDK generates events that have associated metrics and attributes. Metrics are quantifiable values that can be used for measurements related to the event. Attributes are non-quantifiable values used to slice metrics data (group by) in analytics. -This page provides descriptions of each of the metrics and attributes collected. +Every RUM event has all of the [default attributes](#default-attributes), for example, the device type (`device.type`) and user information such as their name (`usr.name`) and their country (`geo.country`). + +There are additional [metrics and attributes that are specific to a given event type](#event-specific-metrics-and-attributes). For example, the metric `view.time_spent` is associated with "view" events and the attribute `resource.method` is associated with "resource" events. + +| Event Type | Retention | Description | +|------------|-----------|-------------------------------------| +| Session | 30 days | A session represents a real user journey on your mobile application. It begins when the user launches the application, and the session remains live as long as the user stays active. During the user journey, all RUM events generated as part of the session share the same `session.id` attribute. **Note:** The session resets after 15 minutes of inactivity. If the application is killed by the OS, you can reset the session while the application is in the background.| +| View | 30 days | A view represents a unique screen (or screen segment) on your mobile application. A view starts and stops when the `viewDidAppear(animated:)` and `viewDidDisappear(animated:)` callbacks on the `UIViewController` class are notified. Individual `UIViewControllers` are classified as distinct views. While a user stays on a view, RUM event attributes (Errors, Resources, Actions) get attached to the view with a unique `view.id`. | +| Resource | 15 days | A resource represents network requests to first-party hosts, APIs, and third-party providers in your mobile application. All requests generated during a user session are attached to the view with a unique `resource.id`. | +| Error | 30 days | An error represents an exception or crash emitted by the mobile application attached to the view it is generated in. | +| Action | 30 days | An action represents user activity in your mobile application (for example, application launch, tap, swipe, or back). Each action is attached with a unique `action.id` attached to the view it gets generated in. | + +The following diagram illustrates the RUM event hierarchy: + +{{< img src="real_user_monitoring/data_collected/event-hierarchy.png" alt="RUM Event hierarchy" style="width:50%;border:none" >}} ## Default attributes @@ -26,7 +39,7 @@ RUM collects common attributes for all events and attributes specific to each ev | Attribute name | Type | Description | |------------------|---------|------------------------------------------------------------------------------------| -| `date` | integer | Start of the event in ms from epoch. | +| `date` | integer | Start of the event in milliseconds from epoch. | | `type` | string | The type of the event (for example, `view` or `resource`). | | `service` | string | The [unified service name][2] for this application used to corelate user sessions. | | `application.id` | string | The Datadog application ID. | @@ -37,14 +50,14 @@ The following device-related attributes are attached automatically to all events | Attribute name | Type | Description | |--------------------------------------|--------|----------------------------------------------------------------------------------------------------------| -| `device.type` | string | The device type as reported by the device (System User-Agent) | -| `device.brand` | string | The device brand as reported by the device (System User-Agent) | -| `device.model` | string | The device model as reported by the device (System User-Agent) | -| `device.name` | string | The device name as reported by the device (System User-Agent) | +| `device.type` | string | The device type as reported by the device (System User-Agent). | +| `device.brand` | string | The device brand as reported by the device (System User-Agent). | +| `device.model` | string | The device model as reported by the device (System User-Agent). | +| `device.name` | string | The device name as reported by the device (System User-Agent). | | `connectivity.status` | string | Status of device network reachability (`connected`, `not connected`, `maybe`). | -| `connectivity.interfaces` | string | The list of available network interfaces (for example, `bluetooth`, `cellular`, `ethernet`, `wifi` etc). | -| `connectivity.cellular.technology` | string | The type of a radio technology used for cellular connection | -| `connectivity.cellular.carrier_name` | string | The name of the SIM carrier | +| `connectivity.interfaces` | string | The list of available network interfaces (for example, `bluetooth`, `cellular`, `ethernet`, or `wifi`). | +| `connectivity.cellular.technology` | string | The type of a radio technology used for cellular connection. | +| `connectivity.cellular.carrier_name` | string | The name of the SIM carrier. | ### Operating system @@ -53,9 +66,9 @@ The following OS-related attributes are attached automatically to all events col | Attribute name | Type | Description | |--------------------|--------|---------------------------------------------------------------------------| -| `os.name` | string | The OS name as reported by the by the device (System User-Agent) | -| `os.version` | string | The OS version as reported by the by the device (System User-Agent) | -| `os.version_major` | string | The OS version major as reported by the by the device (System User-Agent) | +| `os.name` | string | The OS name as reported by the device (System User-Agent). | +| `os.version` | string | The OS version as reported by the device (System User-Agent). | +| `os.version_major` | string | The OS version major as reported by the device (System User-Agent). | ### Geo-location @@ -65,12 +78,12 @@ The following attributes are related to the geo-location of IP addresses: | Fullname | Type | Description | |------------------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------| | `geo.country` | string | Name of the country | -| `geo.country_iso_code` | string | ISO Code of the country (for example, `US` for the United States, `FR` for France). | +| `geo.country_iso_code` | string | ISO Code of the country (for example, `US` for the United States or `FR` for France). | | `geo.country_subdivision` | string | Name of the first subdivision level of the country (for example, `California` in the United States or the `Sarthe` department in France). | | `geo.country_subdivision_iso_code` | string | ISO Code of the first subdivision level of the country (for example, `CA` in the United States or the `SA` department in France). | | `geo.continent_code` | string | ISO code of the continent (`EU`, `AS`, `NA`, `AF`, `AN`, `SA`, `OC`). | -| `geo.continent` | string | Name of the continent (`Europe`, `Australia`, `North America`, `Africa`, `Antartica`, `South America`, `Oceania`). | -| `geo.city` | string | The name of the city (example `Paris`, `New York`). | +| `geo.continent` | string | Name of the continent (`Europe`, `Australia`, `North America`, `Africa`, `Antarctica`, `South America`, `Oceania`). | +| `geo.city` | string | The name of the city (for example, `San Francisco`, `Paris`, or `New York`). | ### Global user attributes @@ -84,21 +97,7 @@ You can enable [tracking user info][2] globally to collect and apply user attrib | `usr.email` | string | Email of the user. | -## Event specific metrics and attributes - -The Datadog Real User Monitoring SDK generates six types of events: - -| Event Type | Retention | Description | -|------------|-----------|-------------------------------------| -| Session | 30 days | Session represents a real user journey on your mobile application. It begins when the user launches the application, and the session remains live as long as the user stays active. During the user journey, all RUM events generated as part of the session will share the same `session.id` attribute. | -| View | 30 days | A view represents a unique screen (or screen segment) on your mobile application. Individual `UIViewControllers` are classified as distinct views. While a user stays on a view, RUM event attributes (Errors, Resources, Actions) get attached to the view with a unique `view.id` | -| Resource | 15 days | Resources represents network requests to first-party hosts, APIs, 3rd party providers, and libraries in your mobile application. All requests generated during a user session are attached to the view with a unique `resource.id` | -| Error | 30 days | Error represents an exception emitted by the mobile application attached to the view it is generated in. | -| Action | 30 days | Action represents user activity in your mobile application (application launch, tap, swipe, back etc). Each action is attached with a unique `action.id` attached to the view it gets generated in. | - -The following diagram illustrates the RUM event hierarchy: - -{{< img src="real_user_monitoring/data_collected/event-hierarchy.png" alt="RUM Event hierarchy" style="width:50%;border:none" >}} +## Event-specific metrics and attributes ### Session metrics @@ -118,32 +117,34 @@ The following diagram illustrates the RUM event hierarchy: |------------------------------|--------|----------------------------------------------------------------------------| | `session.id` | string | Unique ID of the session. | | `session.type` | string | Type of the session (`user`). | -| `session.is_active` | string | Indicates if the session is currently active | -| `session.initial_view.url` | string | URL of the initial view of the session | -| `ssession.initial_view.name` | string | Name of the initial view of the session | -| `session.last_view.url` | string | URL of the last view of the session | -| `session.last_view.name` | string | Name of the last view of the session | -| `session.ip` | string | IP address of the session extracted from the TCP connectiion of the intake | -| `session.useragent` | string | System user agent info to interpret device info | +| `session.is_active` | boolean | Indicates if the session is currently active. The session ends if a user navigates away from the application or closes the browser window, and expires after 4 hours of activity or 15 minutes of inactivity. | +| `session.initial_view.url` | string | URL of the initial view of the session. | +| `ssession.initial_view.name` | string | Name of the initial view of the session. | +| `session.last_view.url` | string | URL of the last view of the session. | +| `session.last_view.name` | string | Name of the last view of the session. | +| `session.ip` | string | IP address of the session extracted from the TCP connection of the intake. | +| `session.useragent` | string | System user agent info to interpret device info. | ### View metrics -RUM action, error, resource and long task events contain information about the active RUM view event at the time of collection: +RUM action, error, resource, and long task events contain information about the active RUM view event at the time of collection. | Metric | Type | Description | |-----------------------|-------------|------------------------------------------------------------------------------| -| `view.time_spent` | number (ns) | Time spent on the this view. | +| `view.time_spent` | number (ns) | Time spent on this view. | +| `view.loading_time` | number (ns) | Loading time for this view. | +| `view.long_task.count` | number | Count of all long tasks collected for this view. | | `view.error.count` | number | Count of all errors collected for this view. | | `view.resource.count` | number | Count of all resources collected for this view. | | `view.action.count` | number | Count of all actions collected for this view. | | `view.is_active` | boolean | Indicates whether the view corresponding to this event is considered active. | -### View attributes +### View attributes | Attribute name | Type | Description | |----------------|--------|-----------------------------------------------------------------| -| `view.id` | string | Unique ID of the initial view corresponding to the event.view. | +| `view.id` | string | Unique ID of the initial view corresponding to the event. | | `view.url` | string | URL of the `UIViewController` class corresponding to the event. | | `view.name` | string | Customizable name of the view corresponding to the event. | @@ -154,25 +155,25 @@ RUM action, error, resource and long task events contain information about the a |--------------------------------|----------------|-------------------------------------------------------------------------------------------------| | `resource.duration` | number | Entire time spent loading the resource. | | `resource.size` | number (bytes) | Resource size. | -| `resource.connect.duration` | number (ns) | Time spent establishing a connection to the server (connectEnd - connectStart) | +| `resource.connect.duration` | number (ns) | Time spent establishing a connection to the server (connectEnd - connectStart). | | `resource.ssl.duration` | number (ns) | Time spent for the TLS handshake. | -| `resource.dns.duration` | number (ns) | Time spent resolving the DNS name of the last request (domainLookupEnd - domainLookupStart) | -| `resource.redirect.duration` | number (ns) | Time spent on subsequent HTTP requests (redirectEnd - redirectStart) | -| `resource.first_byte.duration` | number (ns) | Time spent waiting for the first byte of response to be received (responseStart - requestStart) | -| `resource.download.duration` | number (ns) | Time spent downloading the response (responseEnd - responseStart) | +| `resource.dns.duration` | number (ns) | Time spent resolving the DNS name of the last request (domainLookupEnd - domainLookupStart). | +| `resource.redirect.duration` | number (ns) | Time spent on subsequent HTTP requests (redirectEnd - redirectStart). | +| `resource.first_byte.duration` | number (ns) | Time spent waiting for the first byte of response to be received (responseStart - requestStart). | +| `resource.download.duration` | number (ns) | Time spent downloading the response (responseEnd - responseStart). | ### Resource attributes | Attribute | Type | Description | |----------------------------|--------|------------------------------------------------------------------------------------------| | `resource.id` | string | Unique identifier of the resource. | -| `resource.type` | string | The type of resource being collected (for example, `xhr`, `image`, `font`, `css`, `js`). | -| `resource.method` | string | The HTTP method (for example `POST`, `GET` `PATCH`, `DELETE` etc). | +| `resource.type` | string | The type of resource being collected (for example, `xhr`, `image`, `font`, `css`, or `js`). | +| `resource.method` | string | The HTTP method (for example, `POST`, `GET`, `PATCH`, or `DELETE`). | | `resource.status_code` | number | The response status code. | | `resource.url` | string | The resource URL. | | `resource.provider.name` | string | The resource provider name. Default is `unknown`. | | `resource.provider.domain` | string | The resource provider domain. | -| `resource.provider.type` | string | The resource provider type (for example `first-party`, `cdn`, `ad`, `analytics`). | +| `resource.provider.type` | string | The resource provider type (for example, `first-party`, `cdn`, `ad`, or `analytics`). | ### Error attributes @@ -181,24 +182,24 @@ Front-end errors are collected with Real User Monitoring (RUM). The error messag | Attribute | Type | Description | |------------------|--------|----------------------------------------------------------------------------------| -| `error.source` | string | Where the error originates from (for example, `webview`, `logger` or `network`). | +| `error.source` | string | Where the error originates from (for example, `webview`, `logger`, or `network`). | | `error.type` | string | The error type (or error code in some cases). | | `error.message` | string | A concise, human-readable, one-line message explaining the event. | | `error.stack` | string | The stack trace or complementary information about the error. | | `error.issue_id` | string | The stack trace or complementary information about the error. | -#### Network errors +### Network errors Network errors include information about failing HTTP requests. The following facets are also collected: | Attribute | Type | Description | |----------------------------------|--------|-----------------------------------------------------------------------------------| | `error.resource.status_code` | number | The response status code. | -| `error.resource.method` | string | The HTTP method (for example `POST`, `GET`). | +| `error.resource.method` | string | The HTTP method (for example, `POST` or `GET`). | | `error.resource.url` | string | The resource URL. | | `error.resource.provider.name` | string | The resource provider name. Default is `unknown`. | | `error.resource.provider.domain` | string | The resource provider domain. | -| `error.resource.provider.type` | string | The resource provider type (for example `first-party`, `cdn`, `ad`, `analytics`). | +| `error.resource.provider.type` | string | The resource provider type (for example, `first-party`, `cdn`, `ad`, or `analytics`). | ### Action metrics @@ -206,6 +207,7 @@ Network errors include information about failing HTTP requests. The following fa | Metric | Type | Description | |-------------------------|-------------|-----------------------------------------------| | `action.loading_time` | number (ns) | The loading time of the action. | +| `action.long_task.count` | number | Count of all long tasks collected for this action. | | `action.resource.count` | number | Count of all resources issued by this action. | | `action.error.count` | number | Count of all errors issued by this action. | @@ -214,15 +216,18 @@ Network errors include information about failing HTTP requests. The following fa | Attribute | Type | Description | |----------------------|--------|---------------------------------------------------------------------------------| | `action.id` | string | UUID of the user action. | -| `action.type` | string | Type of the user action (`tap`, `application_start`). | +| `action.type` | string | Type of the user action (for example, `tap` or `application_start`). | | `action.name` | string | Name of the user action. | -| `action.target.name` | string | Element that the user interacted with. Only for automatically collected actions | +| `action.target.name` | string | Element that the user interacted with. Only for automatically collected actions. | +## Data Storage +Before data is uploaded to Datadog, it is stored in cleartext in the cache directory (`Library/Caches`) of your [application sandbox][3], which can't be read by any other app installed on the device. ## Further Reading {{< partial name="whats-next/whats-next.html" >}} -[1]: /real_user_monitoring/ios/advanced_configuration/#enrich-user-sessions -[2]: /real_user_monitoring/ios/advanced_configuration/#track-user-sessions +[1]: https://docs.datadoghq.com/real_user_monitoring/ios/advanced_configuration/#enrich-user-sessions +[2]: https://docs.datadoghq.com/real_user_monitoring/ios/advanced_configuration/#track-user-sessions +[3]: https://support.apple.com/guide/security/security-of-runtime-process-sec15bfe098e/web diff --git a/docs/rum_collection/troubleshooting.md b/docs/rum_collection/troubleshooting.md index 4d85deb073..1d1348545d 100644 --- a/docs/rum_collection/troubleshooting.md +++ b/docs/rum_collection/troubleshooting.md @@ -29,8 +29,58 @@ If all goes well you should see output similar to this saying that a batch of RU **Recommendation:** Use `Datadog.verbosityLevel` in `DEBUG` configuration, and unset it in `RELEASE`. +## Using `DDURLSessionDelegate` with your own session delegate + +If you want to [automatically track network requests][1] with `DDURLSessionDelegate` but your app already implements its own session delegate, you can use either _inheritance_ or _composition_ patterns and forward calls to `DDURLSessionDelegate`. + +When using _inheritance_, use `DDURLSessionDelegate` as a base class for your custom delegate and make sure to call the `super` implementation from your overridden methods. For example: +```swift +class YourCustomDelegateURLSessionDelegate: DDURLSessionDelegate { + override func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { + super.urlSession(session, task: task, didCompleteWithError: error) // forward to Datadog delegate + /* your custom logic */ + } +} +``` + +When using _composition_, leverage Datadog's `__URLSessionDelegateProviding` protocol to keep an internal instance of `DDURLSessionDelegate` and forward calls to `ddURLSessionDelegate`. For example: +```swift +private class YourCustomDelegateURLSessionDelegate: NSObject, URLSessionTaskDelegate, URLSessionDataDelegate, __URLSessionDelegateProviding { + // MARK: - __URLSessionDelegateProviding conformance + + let ddURLSessionDelegate = DDURLSessionDelegate() + + // MARK: - __URLSessionDelegateProviding handling + + func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) { + ddURLSessionDelegate.urlSession(session, task: task, didFinishCollecting: metrics) // forward to Datadog delegate + /* your custom logic */ + } + + func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { + ddURLSessionDelegate.urlSession(session, task: task, didCompleteWithError: error) // forward to Datadog delegate + /* your custom logic */ + } + + func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { + ddURLSessionDelegate.urlSession(session, dataTask: dataTask, didReceive: data) // forward to Datadog delegate + /* your custom logic */ + } +} +``` +**Note**: If using _composition_, `ddURLSessionDelegate` must receive all necessary calls listed in [`__URLSessionDelegateProviding` protocol comments][2]. Your delegate needs to: +* implement `URLSessionTaskDelegate` and forward: + * [`urlSession(_:task:didFinishCollecting:)`][3] + * [`urlSession(_:task:didCompleteWithError:)`][4] +* implement `URLSessionDataDelegate` and forward: + * [`urlSession(_:dataTask:didReceive:)`][5] + ## Further Reading {{< partial name="whats-next/whats-next.html" >}} -[1]:/real_user_monitoring/ios/advanced_configuration/#initialization-parameters +[1]: https://docs.datadoghq.com/real_user_monitoring/ios/advanced_configuration/?tab=swift#automatically-track-network-requests +[2]: https://github.com/DataDog/dd-sdk-ios/blob/master/Sources/Datadog/URLSessionAutoInstrumentation/DDURLSessionDelegate.swift#L12 +[3]: https://developer.apple.com/documentation/foundation/urlsessiontaskdelegate/1643148-urlsession +[4]: https://developer.apple.com/documentation/foundation/urlsessiontaskdelegate/1411610-urlsession +[5]: https://developer.apple.com/documentation/foundation/urlsessiondatadelegate/1411528-urlsession diff --git a/docs/trace_collection.md b/docs/trace_collection.md index 98296c5987..9c239c6ebe 100644 --- a/docs/trace_collection.md +++ b/docs/trace_collection.md @@ -105,221 +105,317 @@ DDConfigurationBuilder *builder = [DDConfiguration builderWithClientToken:@"}} {{< /site-region >}} - To be compliant with the GDPR regulation, the SDK requires the `trackingConsent` value at initialization. - The `trackingConsent` can be one of the following values: +{{< site-region region="us3" >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +Datadog.initialize( + appContext: .init(), + trackingConsent: trackingConsent, + configuration: Datadog.Configuration + .builderUsing(clientToken: "", environment: "") + .set(serviceName: "app-name") + .set(endpoint: .us3) + .build() +) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDConfigurationBuilder *builder = [DDConfiguration builderWithClientToken:@"" + environment:@""]; +[builder setWithServiceName:@"app-name"]; +[builder setWithEndpoint:[DDEndpoint us3]]; + +[DDDatadog initializeWithAppContext:[DDAppContext new] + trackingConsent:trackingConsent + configuration:[builder build]]; +``` +{{% /tab %}} +{{< /tabs >}} +{{< /site-region >}} + +{{< site-region region="us5" >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +Datadog.initialize( + appContext: .init(), + trackingConsent: trackingConsent, + configuration: Datadog.Configuration + .builderUsing(clientToken: "", environment: "") + .set(serviceName: "app-name") + .set(endpoint: .us5) + .build() +) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDConfigurationBuilder *builder = [DDConfiguration builderWithClientToken:@"" + environment:@""]; +[builder setWithServiceName:@"app-name"]; +[builder setWithEndpoint:[DDEndpoint us5]]; + +[DDDatadog initializeWithAppContext:[DDAppContext new] + trackingConsent:trackingConsent + configuration:[builder build]]; +``` +{{% /tab %}} +{{< /tabs >}} +{{< /site-region >}} - - `.pending` - the SDK starts collecting and batching the data but does not send it to Datadog. The SDK waits for the new tracking consent value to decide what to do with the batched data. - - `.granted` - the SDK starts collecting the data and sends it to Datadog. - - `.notGranted` - the SDK does not collect any data: logs, traces, and RUM events are not sent to Datadog. +{{< site-region region="gov" >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +Datadog.initialize( + appContext: .init(), + trackingConsent: trackingConsent, + configuration: Datadog.Configuration + .builderUsing(clientToken: "", environment: "") + .set(serviceName: "app-name") + .set(endpoint: .us1_fed) + .build() +) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDConfigurationBuilder *builder = [DDConfiguration builderWithClientToken:@"" + environment:@""]; +[builder setWithServiceName:@"app-name"]; +[builder setWithEndpoint:[DDEndpoint us1_fed]]; - To change the tracking consent value after the SDK is initialized, use the `Datadog.set(trackingConsent:)` API call. - The SDK changes its behavior according to the new value. For example, if the current tracking consent is `.pending`: +[DDDatadog initializeWithAppContext:[DDAppContext new] + trackingConsent:trackingConsent + configuration:[builder build]]; +``` +{{% /tab %}} +{{< /tabs >}} +{{< /site-region >}} + +To comply with GDPR regulations, the SDK requires the `trackingConsent` value at initialization. + +Use one of the following values for `trackingConsent`: + +- `.pending` - the SDK starts collecting and batching the data but does not send it to Datadog. The SDK waits for the new tracking consent value to decide what to do with the batched data. +- `.granted` - the SDK starts collecting the data and sends it to Datadog. +- `.notGranted` - the SDK does not collect any data. No logs, traces, or RUM events are sent to Datadog. + +To change the tracking consent value after the SDK is initialized, use the `Datadog.set(trackingConsent:)` API call. + +The SDK changes its behavior according to the new value. - - if changed to `.granted`, the SDK will send all current and future data to Datadog; - - if changed to `.notGranted`, the SDK will wipe all current data and will not collect any future data. +For example, if the current tracking consent is `.pending`: - When writing your application, you can enable development logs. All internal messages in the SDK with a priority equal to or higher than the provided level are then logged to console logs. +- If changed to `.granted`, the SDK sends all current and future data to Datadog. +- If changed to `.notGranted`, the SDK wipes all current data and does not collect future data. - {{< tabs >}} - {{% tab "Swift" %}} - ```swift - Datadog.verbosityLevel = .debug - ``` - {{% /tab %}} - {{% tab "Objective-C" %}} - DDDatadog.verbosityLevel = DDSDKVerbosityLevelDebug; - ``` - {{% /tab %}} - {{< /tabs >}} +Before data is uploaded to Datadog, it is stored in cleartext in the cache directory (`Library/Caches`) of your [application sandbox][11], which can't be read by any other app installed on the device. + +When writing your application, enable development logs to log to console all internal messages in the SDK with a priority equal to or higher than the provided level. + +{{< tabs >}} +{{% tab "Swift" %}} +```swift +Datadog.verbosityLevel = .debug +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +DDDatadog.verbosityLevel = DDSDKVerbosityLevelDebug; +``` +{{% /tab %}} +{{< /tabs >}} 3. Datadog tracer implements the [Open Tracing standard][8]. Configure and register the `Tracer` globally as Open Tracing `Global.sharedTracer`. You only need to do it once, usually in your `AppDelegate` code: - {{< tabs >}} - {{% tab "Swift" %}} - ```swift - Global.sharedTracer = Tracer.initialize( - configuration: Tracer.Configuration( - sendNetworkInfo: true - ) +{{< tabs >}} +{{% tab "Swift" %}} +```swift +Global.sharedTracer = Tracer.initialize( + configuration: Tracer.Configuration( + sendNetworkInfo: true ) - ``` - {{% /tab %}} - {{% tab "Objective-C" %}} - ```objective-c - DDTracerConfiguration *configuration = [[DDTracerConfiguration alloc] init]; - [configuration sendNetworkInfo:YES]; - DDGlobal.sharedTracer = [[DDTracer alloc] initWithConfiguration:configuration]; - ``` - {{% /tab %}} - {{< /tabs >}} +) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDTracerConfiguration *configuration = [[DDTracerConfiguration alloc] init]; +[configuration sendNetworkInfo:YES]; +DDGlobal.sharedTracer = [[DDTracer alloc] initWithConfiguration:configuration]; +``` +{{% /tab %}} +{{< /tabs >}} 4. Instrument your code using the following methods: - {{< tabs >}} - {{% tab "Swift" %}} - ```swift - let span = Global.sharedTracer.startSpan(operationName: "") - // do something you want to measure ... - // ... then, when the operation is finished: - span.finish() - ``` - {{% /tab %}} - {{% tab "Objective-C" %}} - ```objective-c - id span = [DDGlobal.sharedTracer startSpan:@""]; - // do something you want to measure ... - // ... then, when the operation is finished: - [span finish]; - ``` - {{% /tab %}} - {{< /tabs >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +let span = Global.sharedTracer.startSpan(operationName: "") +// do something you want to measure ... +// ... then, when the operation is finished: +span.finish() +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +id span = [DDGlobal.sharedTracer startSpan:@""]; +// do something you want to measure ... +// ... then, when the operation is finished: +[span finish]; +``` +{{% /tab %}} +{{< /tabs >}} 5. (Optional) - Set child-parent relationship between your spans: - {{< tabs >}} - {{% tab "Swift" %}} - ```swift - let responseDecodingSpan = Global.sharedTracer.startSpan( - operationName: "response decoding", - childOf: networkRequestSpan.context // make it a child of `networkRequestSpan` - ) - // ... decode HTTP response data ... - responseDecodingSpan.finish() - ``` - {{% /tab %}} - {{% tab "Objective-C" %}} - ```objective-c - id responseDecodingSpan = [DDGlobal.sharedTracer startSpan:@"response decoding" - childOf:networkRequestSpan.context]; - // ... decode HTTP response data ... - [responseDecodingSpan finish]; - ``` - {{% /tab %}} - {{< /tabs >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +let responseDecodingSpan = Global.sharedTracer.startSpan( + operationName: "response decoding", + childOf: networkRequestSpan.context // make it a child of `networkRequestSpan` +) +// ... decode HTTP response data ... +responseDecodingSpan.finish() +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +id responseDecodingSpan = [DDGlobal.sharedTracer startSpan:@"response decoding" + childOf:networkRequestSpan.context]; +// ... decode HTTP response data ... +[responseDecodingSpan finish]; +``` +{{% /tab %}} +{{< /tabs >}} 6. (Optional) - Provide additional tags alongside your span: - {{< tabs >}} - {{% tab "Swift" %}} - ```swift - span.setTag(key: "http.url", value: url) - ``` - {{% /tab %}} - {{% tab "Objective-C" %}} - ```objective-c - [span setTag:@"http.url" value:url]; - ``` - {{% /tab %}} - {{< /tabs >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +span.setTag(key: "http.url", value: url) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +[span setTag:@"http.url" value:url]; +``` +{{% /tab %}} +{{< /tabs >}} 7. (Optional) Attach an error to a span - you can do so by logging the error information using the [standard Open Tracing log fields][9]: - {{< tabs >}} - {{% tab "Swift" %}} - ```swift - span.log( - fields: [ - OTLogFields.event: "error", - OTLogFields.errorKind: "I/O Exception", - OTLogFields.message: "File not found", - OTLogFields.stack: "FileReader.swift:42", - ] - ) - ``` - {{% /tab %}} - {{% tab "Objective-C" %}} - ```objective-c - [span log:@{ - @"event": @"error", - @"error.kind": @"I/O Exception", - @"message": @"File not found", - @"stack": @"FileReader.swift:42", - }]; - ``` - {{% /tab %}} - {{< /tabs >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +span.log( + fields: [ + OTLogFields.event: "error", + OTLogFields.errorKind: "I/O Exception", + OTLogFields.message: "File not found", + OTLogFields.stack: "FileReader.swift:42", + ] +) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +[span log:@{ + @"event": @"error", + @"error.kind": @"I/O Exception", + @"message": @"File not found", + @"stack": @"FileReader.swift:42", +}]; +``` +{{% /tab %}} +{{< /tabs >}} 8. (Optional) To distribute traces between your environments, for example frontend - backend, you can either do it manually or leverage our auto instrumentation. - * To manually propagate the trace, inject the span context into `URLRequest` headers: - - {{< tabs >}} - {{% tab "Swift" %}} - ```swift - var request: URLRequest = ... // the request to your API - - let span = Global.sharedTracer.startSpan(operationName: "network request") - - let headersWriter = HTTPHeadersWriter() - Global.sharedTracer.inject(spanContext: span.context, writer: headersWriter) - - for (headerField, value) in headersWriter.tracePropagationHTTPHeaders { - request.addValue(value, forHTTPHeaderField: headerField) - } - ``` - {{% /tab %}} - {{% tab "Objective-C" %}} - ```objective-c - id span = [DDGlobal.sharedTracer startSpan:@"network request"]; - DDHTTPHeadersWriter *headersWriter = [[DDHTTPHeadersWriter alloc] init]; - - NSError *error = nil; - [DDGlobal.sharedTracer inject:span.context - format:OT.formatTextMap - carrier:headersWriter - error:&error]; - - for (NSString *key in headersWriter.tracePropagationHTTPHeaders) { - NSString *value = headersWriter.tracePropagationHTTPHeaders[key]; - [request addValue:value forHTTPHeaderField:key]; - } - ``` - {{% /tab %}} - {{< /tabs >}} - - This will set additional tracing headers on your request, so that your backend can extract it and continue distributed tracing. Once the request is done, within a completion handler, call `span.finish()`. If your backend is also instrumented with [Datadog APM & Distributed Tracing][10] you will see the entire front-to-back trace in Datadog dashboard. - - * To have the SDK automatically trace all network requests made to given hosts, specify the `firstPartyHosts` array during Datadog initialization and use the `DDURLSessionDelegate` as a delegate of the `URLSession` instance that you want to monitor: - - {{< tabs >}} - {{% tab "Swift" %}} - ```swift - Datadog.initialize( - appContext: .init(), - configuration: Datadog.Configuration - .builderUsing(clientToken: "", environment: "") - .trackURLSession(firstPartyHosts: ["example.com", "api.yourdomain.com"]) - .build() - ) +* To manually propagate the trace, inject the span context into `URLRequest` headers: - let session = URLSession( - configuration: .default, - delegate: DDURLSessionDelegate(), - delegateQueue: nil - ) - ``` - {{% /tab %}} - {{% tab "Objective-C" %}} - ```objective-c - DDConfigurationBuilder *builder = [DDConfiguration builderWithClientToken:@"" - environment:@""]; +{{< tabs >}} +{{% tab "Swift" %}} +```swift +var request: URLRequest = ... // the request to your API + +let span = Global.sharedTracer.startSpan(operationName: "network request") + +let headersWriter = HTTPHeadersWriter() +Global.sharedTracer.inject(spanContext: span.context, writer: headersWriter) + +for (headerField, value) in headersWriter.tracePropagationHTTPHeaders { + request.addValue(value, forHTTPHeaderField: headerField) +} +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +id span = [DDGlobal.sharedTracer startSpan:@"network request"]; +DDHTTPHeadersWriter *headersWriter = [[DDHTTPHeadersWriter alloc] init]; + +NSError *error = nil; +[DDGlobal.sharedTracer inject:span.context + format:OT.formatTextMap + carrier:headersWriter + error:&error]; + +for (NSString *key in headersWriter.tracePropagationHTTPHeaders) { + NSString *value = headersWriter.tracePropagationHTTPHeaders[key]; + [request addValue:value forHTTPHeaderField:key]; +} +``` +{{% /tab %}} +{{< /tabs >}} - [builder trackURLSessionWithFirstPartyHosts:[NSSet setWithArray:@[@"example.com", @"api.yourdomain.com"]]]; +This sets additional tracing headers on your request so your backend can extract the request and continue distributed tracing. Once the request is done, call `span.finish()` within a completion handler. If your backend is also instrumented with [Datadog APM & Distributed Tracing][10], the entire front-to-back trace appears in the Datadog dashboard. - [DDDatadog initializeWithAppContext:[DDAppContext new] - trackingConsent:trackingConsent - configuration:[builder build]]; +* In order for the SDK to automatically trace all network requests made to the given hosts, specify the `firstPartyHosts` array in the Datadog initialization and use `DDURLSessionDelegate` as a delegate of the `URLSession` instance you want to monitor: - NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] - delegate:[[DDNSURLSessionDelegate alloc] init] - delegateQueue:nil]; - ``` - {{% /tab %}} - {{< /tabs >}} +{{< tabs >}} +{{% tab "Swift" %}} +```swift +Datadog.initialize( + appContext: .init(), + configuration: Datadog.Configuration + .builderUsing(clientToken: "", environment: "") + .trackURLSession(firstPartyHosts: ["example.com", "api.yourdomain.com"]) + .build() +) + +let session = URLSession( + configuration: .default, + delegate: DDURLSessionDelegate(), + delegateQueue: nil +) +``` +{{% /tab %}} +{{% tab "Objective-C" %}} +```objective-c +DDConfigurationBuilder *builder = [DDConfiguration builderWithClientToken:@"" + environment:@""]; + +[builder trackURLSessionWithFirstPartyHosts:[NSSet setWithArray:@[@"example.com", @"api.yourdomain.com"]]]; + +[DDDatadog initializeWithAppContext:[DDAppContext new] + trackingConsent:trackingConsent + configuration:[builder build]]; + +NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] + delegate:[[DDNSURLSessionDelegate alloc] init] + delegateQueue:nil]; +``` +{{% /tab %}} +{{< /tabs >}} - This will trace all requests made with this `session` to `example.com` and `api.yourdomain.com` hosts (for example, `https://api.yourdomain.com/v2/users` or `https://subdomain.example.com/image.png`). +This traces all requests made with this `session` to `example.com` and `api.yourdomain.com` hosts (for example, `https://api.yourdomain.com/v2/users` or `https://subdomain.example.com/image.png`). - **Note**: Tracing auto instrumentation uses `URLSession` swizzling, but it is opt-in: if you do not specify `firstPartyHosts`, no swizzling is applied. +**Note**: Tracing auto-instrumentation uses `URLSession` swizzling and is opt-in. If you do not specify `firstPartyHosts`, swizzling is not applied. ## Batch collection @@ -342,3 +438,4 @@ The data on disk will automatically be discarded if it gets too old to ensure th [8]: https://opentracing.io [9]: https://github.com/opentracing/specification/blob/master/semantic_conventions.md#log-fields-table [10]: https://docs.datadoghq.com/tracing/ +[11]: https://support.apple.com/guide/security/security-of-runtime-process-sec15bfe098e/web diff --git a/tools/dogfooding/Makefile b/tools/distribution/Makefile similarity index 50% rename from tools/dogfooding/Makefile rename to tools/distribution/Makefile index e335aadb37..86e9a1fda6 100644 --- a/tools/dogfooding/Makefile +++ b/tools/distribution/Makefile @@ -1,10 +1,11 @@ .PHONY: all all: + @echo "⚙️ Ensuring that GitHub CLI is installed $(PWD)" @brew list gh &>/dev/null || brew install gh ifeq ($(wildcard venv),) @echo "⚙️ Creating Python venv in $(PWD)" python3 -m venv venv endif - venv/bin/pip3 install GitPython==3.1.14 - venv/bin/python3 dogfood.py + @echo "⚙️ Installing pip dependencies in $(PWD)/venv" + venv/bin/pip3 install -r requirements.txt diff --git a/tools/dogfooding/dogfood.py b/tools/distribution/dogfood.py similarity index 89% rename from tools/dogfooding/dogfood.py rename to tools/distribution/dogfood.py index a9d4026e08..5144cd1017 100755 --- a/tools/dogfooding/dogfood.py +++ b/tools/distribution/dogfood.py @@ -9,28 +9,15 @@ import sys import os -import contextlib import traceback from tempfile import TemporaryDirectory -from src.package_resolved import PackageResolvedFile -from src.dogfooded_commit import DogfoodedCommit -from src.repository import Repository - - -@contextlib.contextmanager -def remember_cwd(): - """ - Creates context manager for convenient work with `os.chdir()` API. - After context returns, the `os.getcwd()` is set to its previous value. - """ - previous = os.getcwd() - try: - yield - finally: - os.chdir(previous) +from src.dogfood.package_resolved import PackageResolvedFile +from src.dogfood.dogfooded_commit import DogfoodedCommit +from src.dogfood.repository import Repository +from src.utils import remember_cwd -def dogfood(dry_run: bool, repository_url: str, repository_name: str, repository_package_resolved_paths: [str]) -> int: +def dogfood(dry_run: bool, repository_url: str, repository_name: str, repository_package_resolved_paths: [str]): print(f'🐶 Dogfooding: {repository_name}...') # Read commit information: @@ -107,13 +94,13 @@ def dogfood(dry_run: bool, repository_url: str, repository_name: str, repository if __name__ == "__main__": - # Change working directory to `tools/dogfooding/` + # Change working directory to `tools/distribution/` print(f'ℹ️ Launch dir: {sys.argv[0]}') launch_dir = os.path.dirname(sys.argv[0]) launch_dir = '.' if launch_dir == '' else launch_dir - if launch_dir == 'tools/dogfooding': + if launch_dir == 'tools/distribution': print(f' → changing current directory to: {os.getcwd()}') - os.chdir('tools/dogfooding') + os.chdir('tools/distribution') try: dry_run = os.environ.get('DD_DRY_RUN') == 'yes' diff --git a/tools/distribution/release.py b/tools/distribution/release.py index 1c8254413a..34f3992dfe 100755 --- a/tools/distribution/release.py +++ b/tools/distribution/release.py @@ -13,10 +13,10 @@ import re import traceback from tempfile import TemporaryDirectory -from src.git import clone_repo -from src.assets.gh_asset import GHAsset -from src.assets.podspec import CPPodspec -from src.semver import Version +from src.release.git import clone_repo +from src.release.assets.gh_asset import GHAsset +from src.release.assets.podspec import CPPodspec +from src.release.semver import Version DD_SDK_IOS_REPO_SSH = 'git@github.com:DataDog/dd-sdk-ios.git' DD_SDK_IOS_REPO_NAME = 'dd-sdk-ios' @@ -113,9 +113,9 @@ # Publish GH Release asset: if publish_to_gh: - gh_asset = GHAsset(add_xcode_version=add_xcode_version_to_github_asset) - gh_asset.validate(git_tag=git_tag) - gh_asset.publish(git_tag=git_tag, overwrite_existing=overwrite_github, dry_run=dry_run) + gh_asset = GHAsset(add_xcode_version=add_xcode_version_to_github_asset,git_tag=git_tag) + gh_asset.validate() + gh_asset.publish(overwrite_existing=overwrite_github, dry_run=dry_run) # Publish CP podspecs: if publish_to_cp: diff --git a/tools/distribution/requirements.txt b/tools/distribution/requirements.txt new file mode 100644 index 0000000000..69ccc77bd8 --- /dev/null +++ b/tools/distribution/requirements.txt @@ -0,0 +1,3 @@ +gitdb==4.0.9 +GitPython==3.1.26 +smmap==5.0.0 diff --git a/tools/dogfooding/src/dogfooded_commit.py b/tools/distribution/src/dogfood/dogfooded_commit.py similarity index 90% rename from tools/dogfooding/src/dogfooded_commit.py rename to tools/distribution/src/dogfood/dogfooded_commit.py index 20132370a7..93bcf4cdff 100644 --- a/tools/dogfooding/src/dogfooded_commit.py +++ b/tools/distribution/src/dogfood/dogfooded_commit.py @@ -16,7 +16,7 @@ class DogfoodedCommit: """ def __init__(self): - if 'CI' in os.environ: + if os.environ.get('CI') == 'true': print('ℹ️ Running on CI') print(' → reading git author from ENV') self.author = Actor( @@ -34,3 +34,4 @@ def __init__(self): self.message = dd_sdk_ios_repo.head.commit.message self.hash_short = self.hash[0:8] + print(f' → Read git info (author: "{self.author}", hash: "{self.hash}", message: "{self.message}")') diff --git a/tools/dogfooding/src/package_resolved.py b/tools/distribution/src/dogfood/package_resolved.py similarity index 100% rename from tools/dogfooding/src/package_resolved.py rename to tools/distribution/src/dogfood/package_resolved.py diff --git a/tools/dogfooding/src/repository.py b/tools/distribution/src/dogfood/repository.py similarity index 82% rename from tools/dogfooding/src/repository.py rename to tools/distribution/src/dogfood/repository.py index 40ceebf8c5..4e578f6e64 100644 --- a/tools/dogfooding/src/repository.py +++ b/tools/distribution/src/dogfood/repository.py @@ -6,6 +6,7 @@ import os +from typing import Union from git import Repo, Actor @@ -38,7 +39,7 @@ def clone(ssh: str, repository_name: str, temp_dir: str): f'Unable to clone GH repository ({ssh}). Check GH CLI authentication status in above logs.' ) else: - print(f' → changing current directory to: {repository_name}') + print(f' → changing current directory to: {os.getcwd()}/{repository_name}') os.chdir(repository_name) return Repository(repo=Repo(path=os.getcwd())) @@ -50,13 +51,16 @@ def create_branch(self, branch_name): print(f'⚙️️️️ Creating git branch: {branch_name}') self.repo.git.checkout('HEAD', b=branch_name) - def commit(self, message: str, author: Actor): + def commit(self, message: str, author: Union[None, 'Actor'] = None): """ Creates commit with current changes. :param message: commit message - :param author: author of the commit (git.Actor object) + :param author: author of the commit (git.Actor object) or None (will be read from git config) """ - print(f'⚙️️️️ Committing changes on behalf of {author.name} ({author.email})') + if author: + print(f'⚙️️️️ Committing changes on behalf of {author.name} ({author.email})') + else: + print(f'⚙️️️️ Committing changes using git user from current git config') print(' → commit message:') print(message) self.repo.git.add(update=True) diff --git a/tools/distribution/src/assets/gh_asset.py b/tools/distribution/src/release/assets/gh_asset.py similarity index 57% rename from tools/distribution/src/assets/gh_asset.py rename to tools/distribution/src/release/assets/gh_asset.py index 7c3c0b5276..417cf6620f 100644 --- a/tools/distribution/src/assets/gh_asset.py +++ b/tools/distribution/src/release/assets/gh_asset.py @@ -11,28 +11,28 @@ import glob from tempfile import TemporaryDirectory, NamedTemporaryFile from src.utils import remember_cwd, shell, read_sdk_version, read_xcode_version -from src.directory_matcher import DirectoryMatcher -from src.semver import Version +from src.release.directory_matcher import DirectoryMatcher +from src.release.semver import Version +min_cr_version = Version.parse('1.7.0') +min_tvos_version = Version.parse('1.10.0') class XCFrameworkValidator: name: str - def should_be_included(self, in_version: Version) -> bool: - pass - - def validate(self, zip_directory: DirectoryMatcher): + def validate(self, zip_directory: DirectoryMatcher, in_version: Version) -> bool: pass class DatadogXCFrameworkValidator(XCFrameworkValidator): name = 'Datadog.xcframework' - def should_be_included(self, in_version: Version): - return True # always expect `Datadog.xcframework` + def validate(self, zip_directory: DirectoryMatcher, in_version: Version) -> bool: + # always expect `Datadog.xcframework` + + dir = zip_directory.get('Datadog.xcframework') - def validate(self, zip_directory: DirectoryMatcher): - zip_directory.get('Datadog.xcframework').assert_it_has_files([ + dir.assert_it_has_files([ 'ios-arm64', 'ios-arm64/BCSymbolMaps/*.bcsymbolmap', 'ios-arm64/dSYMs/*.dSYM', @@ -47,15 +47,35 @@ def validate(self, zip_directory: DirectoryMatcher): 'ios-arm64_x86_64-simulator/**/x86_64-apple-ios-simulator.swiftinterface', ]) + if in_version.is_older_than(min_tvos_version): + return True # Stop here: tvOS support was introduced in `1.10.0` + + dir.assert_it_has_files([ + 'tvos-arm64', + 'tvos-arm64/BCSymbolMaps/*.bcsymbolmap', + 'tvos-arm64/dSYMs/*.dSYM', + 'tvos-arm64/**/arm64.swiftinterface', + 'tvos-arm64/**/arm64-apple-ios.swiftinterface', + + 'tvos-arm64_x86_64-simulator', + 'tvos-arm64_x86_64-simulator/dSYMs/*.dSYM', + 'tvos-arm64_x86_64-simulator/**/arm64.swiftinterface', + 'tvos-arm64_x86_64-simulator/**/arm64-apple-tvos-simulator.swiftinterface', + 'tvos-arm64_x86_64-simulator/**/x86_64.swiftinterface', + 'tvos-arm64_x86_64-simulator/**/x86_64-apple-tvos-simulator.swiftinterface', + ]) + + return True + class DatadogObjcXCFrameworkValidator(XCFrameworkValidator): name = 'DatadogObjc.xcframework' - def should_be_included(self, in_version: Version): - return True # always expect `DatadogObjc.xcframework` + def validate(self, zip_directory: DirectoryMatcher, in_version: Version) -> bool: + # always expect `DatadogObjc.xcframework` - def validate(self, zip_directory: DirectoryMatcher): - zip_directory.get('DatadogObjc.xcframework').assert_it_has_files([ + dir = zip_directory.get('DatadogObjc.xcframework') + dir.assert_it_has_files([ 'ios-arm64', 'ios-arm64/BCSymbolMaps/*.bcsymbolmap', 'ios-arm64/dSYMs/*.dSYM', @@ -69,16 +89,35 @@ def validate(self, zip_directory: DirectoryMatcher): 'ios-arm64_x86_64-simulator/**/x86_64-apple-ios-simulator.swiftinterface', ]) + if in_version.is_older_than(min_tvos_version): + return True # Stop here: tvOS support was introduced in `1.10.0` + + dir.assert_it_has_files([ + 'tvos-arm64', + 'tvos-arm64/BCSymbolMaps/*.bcsymbolmap', + 'tvos-arm64/dSYMs/*.dSYM', + 'tvos-arm64/**/arm64.swiftinterface', + 'tvos-arm64/**/arm64-apple-ios.swiftinterface', + + 'tvos-arm64_x86_64-simulator', + 'tvos-arm64_x86_64-simulator/**/arm64.swiftinterface', + 'tvos-arm64_x86_64-simulator/**/arm64-apple-tvos-simulator.swiftinterface', + 'tvos-arm64_x86_64-simulator/**/x86_64.swiftinterface', + 'tvos-arm64_x86_64-simulator/**/x86_64-apple-tvos-simulator.swiftinterface', + ]) + + return True + class DatadogCrashReportingXCFrameworkValidator(XCFrameworkValidator): name = 'DatadogCrashReporting.xcframework' - def should_be_included(self, in_version: Version): - min_version = Version.parse('1.7.0') # Datadog Crash Reporting.xcframework was introduced in `1.7.0` - return in_version.is_newer_than_or_equal(min_version) + def validate(self, zip_directory: DirectoryMatcher, in_version: Version) -> bool: + if in_version.is_older_than(min_cr_version): + return False # Datadog Crash Reporting.xcframework was introduced in `1.7.0` - def validate(self, zip_directory: DirectoryMatcher): - zip_directory.get('DatadogCrashReporting.xcframework').assert_it_has_files([ + dir = zip_directory.get('DatadogCrashReporting.xcframework') + dir.assert_it_has_files([ 'ios-arm64', 'ios-arm64/BCSymbolMaps/*.bcsymbolmap', 'ios-arm64/**/arm64.swiftinterface', @@ -89,31 +128,58 @@ def validate(self, zip_directory: DirectoryMatcher): 'ios-arm64_x86_64-simulator/**/x86_64.swiftinterface', 'ios-arm64_x86_64-simulator/**/x86_64-apple-ios-simulator.swiftinterface', ]) + + if in_version.is_older_than(min_tvos_version): + return True # Stop here: tvOS support was introduced in `1.10.0` + + dir.assert_it_has_files([ + 'tvos-arm64', + 'tvos-arm64/BCSymbolMaps/*.bcsymbolmap', + 'tvos-arm64/**/arm64.swiftinterface', + 'tvos-arm64/**/arm64-apple-ios.swiftinterface', + + 'tvos-arm64_x86_64-simulator', + 'tvos-arm64_x86_64-simulator/dSYMs/*.dSYM', + 'tvos-arm64_x86_64-simulator/**/x86_64.swiftinterface', + 'tvos-arm64_x86_64-simulator/**/x86_64-apple-tvos-simulator.swiftinterface', + ]) + + return True class CrashReporterXCFrameworkValidator(XCFrameworkValidator): name = 'CrashReporter.xcframework' - def should_be_included(self, in_version: Version): - min_version = Version.parse('1.7.0') # Datadog Crash Reporting.xcframework was introduced in `1.7.0` - return in_version.is_newer_than_or_equal(min_version) + def validate(self, zip_directory: DirectoryMatcher, in_version: Version) -> bool: + if in_version.is_older_than(min_cr_version): + return False # Datadog Crash Reporting.xcframework was introduced in `1.7.0` - def validate(self, zip_directory: DirectoryMatcher): - zip_directory.get('CrashReporter.xcframework').assert_it_has_files([ + dir = zip_directory.get('CrashReporter.xcframework') + dir.assert_it_has_files([ 'ios-arm64_arm64e_armv7_armv7s', 'ios-arm64_i386_x86_64-simulator', ]) + if in_version.is_older_than(min_tvos_version): + return True # Stop here: tvOS support was introduced in `1.10.0` + + dir.assert_it_has_files([ + 'tvos-arm64', + 'tvos-arm64_x86_64-simulator', + ]) + + return True + class KronosXCFrameworkValidator(XCFrameworkValidator): name = 'Kronos.xcframework' - def should_be_included(self, in_version: Version): + def validate(self, zip_directory: DirectoryMatcher, in_version: Version) -> bool: min_version = Version.parse('1.5.0') # First version that depends on Kronos - max_version = Version.parse('1.8.99') # Last version that depends on Kronos - return in_version.is_newer_than_or_equal(min_version) and max_version.is_newer_than_or_equal(in_version) - - def validate(self, zip_directory: DirectoryMatcher): + max_version = Version.parse('1.9.0') # Version where Kronos dependency was removed + if in_version.is_older_than(min_version) or in_version.is_newer_than_or_equal(max_version): + return False + zip_directory.get('Kronos.xcframework').assert_it_has_files([ 'ios-arm64_armv7', 'ios-arm64_armv7/BCSymbolMaps/*.bcsymbolmap', @@ -132,6 +198,8 @@ def validate(self, zip_directory: DirectoryMatcher): 'ios-arm64_i386_x86_64-simulator/**/x86_64.swiftinterface', ]) + return True + xcframeworks_validators: [XCFrameworkValidator] = [ DatadogXCFrameworkValidator(), @@ -148,9 +216,10 @@ class GHAsset: It uses Carthage for building the actual `.xcframework` bundles (by recursively searching for their Xcode schemes). """ + __git_tag: str # The git tag to build assets for __path: str # The path to the asset `.zip` archive - def __init__(self, add_xcode_version: bool): + def __init__(self, add_xcode_version: bool, git_tag: str): print(f'⌛️️️ Creating the GH release asset from {os.getcwd()}') with NamedTemporaryFile(mode='w+', prefix='dd-gh-distro-', suffix='.xcconfig') as xcconfig: @@ -158,11 +227,14 @@ def __init__(self, add_xcode_version: bool): xcconfig.seek(0) # without this line, content isn't actually written os.environ['XCODE_XCCONFIG_FILE'] = xcconfig.name + this_version = Version.parse(git_tag) + platform = 'iOS' if this_version.is_older_than(min_tvos_version) else 'iOS,tvOS' + # Produce XCFrameworks with carthage: # - only checkout and `--no-build` as it will build in the next command: - shell('carthage bootstrap --platform iOS --no-build') + shell(f'carthage bootstrap --platform {platform} --no-build') # - `--no-build` as it will build in the next command: - shell('carthage build --platform iOS --use-xcframeworks --no-use-binaries --no-skip-current') + shell(f'carthage build --platform {platform} --use-xcframeworks --no-use-binaries --no-skip-current') # Create `.zip` archive: zip_archive_name = f'Datadog-{read_sdk_version()}.zip' @@ -177,22 +249,23 @@ def __init__(self, add_xcode_version: bool): shell(f'zip -q --symlinks -r {zip_archive_name} *.xcframework') self.__path = f'{os.getcwd()}/Carthage/Build/{zip_archive_name}' + self.__git_tag = git_tag print(' → GH asset created') def __repr__(self): return f'[GHAsset: path = {self.__path}]' - def validate(self, git_tag: str): # 1.5.0 + def validate(self): """ Checks the `.zip` archive integrity with given `git_tag`. """ - print(f'🔎️️ Validating {self} against: {git_tag}') + print(f'🔎️️ Validating {self} against: {self.__git_tag}') # Check if `sdk_version` matches the git tag name: sdk_version = read_sdk_version() - if sdk_version != git_tag: - raise Exception(f'The `sdk_version` ({sdk_version}) does not match git tag ({git_tag})') - print(f' → `sdk_version` ({sdk_version}) matches git tag ({git_tag})') + if sdk_version != self.__git_tag: + raise Exception(f'The `sdk_version` ({sdk_version}) does not match git tag ({self.__git_tag})') + print(f' → `sdk_version` ({sdk_version}) matches git tag ({self.__git_tag})') # Inspect the content of zip archive: with TemporaryDirectory() as unzip_dir: @@ -203,13 +276,12 @@ def validate(self, git_tag: str): # 1.5.0 print(f' - {file_path.removeprefix(unzip_dir)}') dm = DirectoryMatcher(path=unzip_dir) - this_version = Version.parse(git_tag) + this_version = Version.parse(self.__git_tag) print(f' → Validating each `XCFramework`:') validated_count = 0 for validator in xcframeworks_validators: - if validator.should_be_included(in_version=this_version): - validator.validate(zip_directory=dm) + if validator.validate(zip_directory=dm, in_version=this_version): print(f' → {validator.name} - OK') validated_count += 1 else: @@ -219,15 +291,15 @@ def validate(self, git_tag: str): # 1.5.0 print(f' → the content of `.zip` archive is correct') - def publish(self, git_tag: str, overwrite_existing: bool, dry_run: bool): + def publish(self, overwrite_existing: bool, dry_run: bool): """ Uploads the `.zip` archive to GH Release for given `git_tag`. """ - print(f'📦️️ Publishing {self} to GH Release tag {git_tag}') + print(f'📦️️ Publishing {self} to GH Release tag {self.__git_tag}') if overwrite_existing: - shell(f'gh release upload {git_tag} {self.__path} --repo DataDog/dd-sdk-ios --clobber', skip=dry_run) + shell(f'gh release upload {self.__git_tag} {self.__path} --repo DataDog/dd-sdk-ios --clobber', skip=dry_run) else: - shell(f'gh release upload {git_tag} {self.__path} --repo DataDog/dd-sdk-ios', skip=dry_run) + shell(f'gh release upload {self.__git_tag} {self.__path} --repo DataDog/dd-sdk-ios', skip=dry_run) print(f' → succeeded') diff --git a/tools/distribution/src/assets/podspec.py b/tools/distribution/src/release/assets/podspec.py similarity index 100% rename from tools/distribution/src/assets/podspec.py rename to tools/distribution/src/release/assets/podspec.py diff --git a/tools/distribution/src/directory_matcher.py b/tools/distribution/src/release/directory_matcher.py similarity index 100% rename from tools/distribution/src/directory_matcher.py rename to tools/distribution/src/release/directory_matcher.py diff --git a/tools/distribution/src/git.py b/tools/distribution/src/release/git.py similarity index 100% rename from tools/distribution/src/git.py rename to tools/distribution/src/release/git.py diff --git a/tools/distribution/src/semver.py b/tools/distribution/src/release/semver.py similarity index 97% rename from tools/distribution/src/semver.py rename to tools/distribution/src/release/semver.py index 3608da2ccc..9cf185744e 100644 --- a/tools/distribution/src/semver.py +++ b/tools/distribution/src/release/semver.py @@ -110,3 +110,6 @@ def is_newer_than(self, other_version: 'Version'): def is_newer_than_or_equal(self, other_version: 'Version'): return self.is_newer_than(other_version=other_version) or self == other_version + + def is_older_than(self, other_version: 'Version'): + return not self.is_newer_than_or_equal(other_version) diff --git a/tools/distribution/tests/test_directory_matcher.py b/tools/distribution/tests/release/test_directory_matcher.py similarity index 97% rename from tools/distribution/tests/test_directory_matcher.py rename to tools/distribution/tests/release/test_directory_matcher.py index e9b8f39c5d..9cd3cf2151 100644 --- a/tools/distribution/tests/test_directory_matcher.py +++ b/tools/distribution/tests/release/test_directory_matcher.py @@ -8,7 +8,7 @@ import unittest import os from tempfile import TemporaryDirectory -from src.directory_matcher import DirectoryMatcher, DirectoryMatcherException +from src.release.directory_matcher import DirectoryMatcher, DirectoryMatcherException class DirectoryMatcherTestCase(unittest.TestCase): diff --git a/tools/distribution/tests/test_semver.py b/tools/distribution/tests/release/test_semver.py similarity index 98% rename from tools/distribution/tests/test_semver.py rename to tools/distribution/tests/release/test_semver.py index 0144ef0a80..84a62cc4fe 100644 --- a/tools/distribution/tests/test_semver.py +++ b/tools/distribution/tests/release/test_semver.py @@ -8,7 +8,7 @@ # TODO: RUMM-1860 Share this code between both tools import unittest -from src.semver import Version, PreRelease, VersionParsingException +from src.release.semver import Version, PreRelease, VersionParsingException class VersionTestCase(unittest.TestCase): diff --git a/tools/distribution/update_upstream_sdks.py b/tools/distribution/update_upstream_sdks.py new file mode 100755 index 0000000000..ff6a458970 --- /dev/null +++ b/tools/distribution/update_upstream_sdks.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ----------------------------------------------------------- +# 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-2020 Datadog, Inc. +# ----------------------------------------------------------- + +import argparse +import os +import re +import sys +import traceback +from tempfile import TemporaryDirectory +from src.release.semver import Version +from src.dogfood.repository import Repository +from src.utils import remember_cwd, shell + + +def update_flutter_sdk(ios_sdk_git_tag: str, dry_run: bool): + """ + Updates `dd-sdk-ios` version in `dd-sdk-flutter` by changing `s.dependency` in `ios/datadog_sdk.podspec`: + ``` + s.dependency 'DatadogSDK', '1.8.0' + s.dependency 'DatadogSDKCrashReporting', '1.8.0' + ``` + """ + with TemporaryDirectory() as clone_dir: + print(f'ℹ️️ Changing current directory to: {clone_dir}') + os.chdir(clone_dir) + + # Clone repo and create branch: + flutter_repo_name = 'dd-sdk-flutter' + repository = Repository.clone( + ssh='git@github.com:DataDog/dd-sdk-flutter.git', + repository_name=flutter_repo_name, + temp_dir=clone_dir + ) + repository.create_branch(f'update/dd-sdk-ios-to-{ios_sdk_git_tag}') + + package_dir = 'packages/datadog_flutter_plugin' + print(f'ℹ️️ Changing current directory to: {clone_dir}/{flutter_repo_name}/{package_dir}') + os.chdir(package_dir) + + # Replace `dd-sdk-ios` version in `ios/datadog_sdk.podspec`: + with open('ios/datadog_flutter_plugin.podspec', 'r+') as podspec: + lines = podspec.readlines() + for idx, line in enumerate(lines): + if match := re.match(r'^(\s*)(s\.dependency\s+\'DatadogSDK\').+', line): + indent = match.group(1) + lines[idx] = f"{indent}s.dependency 'DatadogSDK', '{git_tag}'\n" + if match := re.match(r'^(\s*)(s\.dependency\s+\'DatadogSDKCrashReporting\').+', line): + indent = match.group(1) + lines[idx] = f"{indent}s.dependency 'DatadogSDKCrashReporting', '{git_tag}'\n" + pass + + podspec.seek(0) + podspec.write(''.join(lines)) + + + shell(command='pod repo update') + shell(command='flutter upgrade') + + # Run `pod update` in `example/ios` + with remember_cwd(): + print(f'ℹ️️ Changing current directory to: {clone_dir}/{flutter_repo_name}/{package_dir}/example') + os.chdir('example') + shell(command='flutter pub get') + + print(f'ℹ️️ Changing current directory to: {clone_dir}/{flutter_repo_name}/{package_dir}/example/ios') + os.chdir('ios') + shell(command='pod update') + + # Run `pod update` in `integration_test_app/ios` + with remember_cwd(): + print(f'ℹ️️ Changing current directory to: {clone_dir}/{flutter_repo_name}/{package_dir}/integration_test_app') + os.chdir('integration_test_app') + shell(command='flutter pub get') + + print(f'ℹ️️ Changing current directory to: {clone_dir}/{flutter_repo_name}/{package_dir}/integration_test_app/ios') + os.chdir('ios') + shell(command='pod update') + + # Commit changes: + repository.commit( + message=f'Update version of dd-sdk-ios to {ios_sdk_git_tag}\n\n' + f'This commit was created by automation from the dd-sdk-ios repo.' + ) + + # Push branch and create PR: + if not dry_run: + repository.push() + repository.create_pr( + title=f'⬆️ Update dd-sdk-ios to {ios_sdk_git_tag}', + description='⚙️ This is an automated PR updating the version of \`dd-sdk-ios\` to ' + + f'[{ios_sdk_git_tag}](https://github.com/DataDog/dd-sdk-ios/releases/tag/{ios_sdk_git_tag}).' + ) + + print(f'✅️️ Updated `dd-sdk-flutter`.') + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "git_tag", + help="Git tag name. Means the `dd-sdk-ios` version that will be used to update upstream SDKs." + ) + parser.add_argument( + "--dry-run", + action='store_true', + help="Run as usual, but skip pushing to git remote (and creating PR).", + default=os.environ.get('DD_RELEASE_DRY_RUN') == '1' + ) + args = parser.parse_args() + + try: + git_tag = args.git_tag + dry_run = True if args.dry_run else False + + print(f'🛠️️ ENV:\n' + f'- BITRISE_GIT_TAG = {os.environ.get("BITRISE_GIT_TAG")}\n' + f'- DD_RELEASE_GIT_TAG = {os.environ.get("DD_RELEASE_GIT_TAG")}\n' + f'- DD_RELEASE_DRY_RUN = {os.environ.get("DD_RELEASE_DRY_RUN")}') + + print(f'🛠️️ ENV and CLI arguments resolved to:\n' + f'- git_tag = {git_tag}\n' + f'- dry_run = {dry_run}.') + + _ = Version.parse(git_tag) # validate or throw + print(f'🛠️ Git tag "{git_tag}" is valid version string.') + + update_flutter_sdk(ios_sdk_git_tag=git_tag, dry_run=dry_run) + print(f'✅️️ All good.') + + except Exception as error: + print(f'❌ Failed to update upstream SDKs: {error}') + print('-' * 60) + traceback.print_exc(file=sys.stdout) + print('-' * 60) + sys.exit(1) + + sys.exit(0) diff --git a/tools/license/check-license.sh b/tools/license/check-license.sh index 30e6b8baae..0c18d022e2 100755 --- a/tools/license/check-license.sh +++ b/tools/license/check-license.sh @@ -17,7 +17,7 @@ function files { -not -path "*Carthage/Build/*" \ -not -path "*Carthage/Checkouts/*" \ -not -path "./tools/rum-models-generator/rum-events-format/*" \ - -not -path "*/tools/dogfooding/venv/*" \ + -not -path "*/tools/distribution/venv/*" \ -not -path "./instrumented-tests/DatadogSDKTesting.xcframework/*" \ -not -name "OTSpan.swift" \ -not -name "OTFormat.swift" \ diff --git a/tools/nightly-unit-tests/bitrise.yml.src b/tools/nightly-unit-tests/bitrise.yml.src index 15ddaa60fc..d2929da2f3 100644 --- a/tools/nightly-unit-tests/bitrise.yml.src +++ b/tools/nightly-unit-tests/bitrise.yml.src @@ -6,7 +6,7 @@ project_type: other app: envs: - PROJECT_PATH: Datadog.xcworkspace - - PROJECT_SCHEME: Datadog + - PROJECT_SCHEME: Datadog iOS workflows: run_all: diff --git a/tools/rum-models-generator/Package.swift b/tools/rum-models-generator/Package.swift index ea10e94615..0bd4388d10 100644 --- a/tools/rum-models-generator/Package.swift +++ b/tools/rum-models-generator/Package.swift @@ -23,6 +23,8 @@ let package = Package( ), .testTarget( name: "rum-models-generator-coreTests", - dependencies: ["RUMModelsGeneratorCore", "Difference"]), + dependencies: ["RUMModelsGeneratorCore", "Difference"], + resources: [.copy("Fixtures")] + ), ] ) diff --git a/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/Input/JSON/JSONSchema.swift b/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/Input/JSON/JSONSchema.swift index 79ef2313fa..23f868f641 100644 --- a/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/Input/JSON/JSONSchema.swift +++ b/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/Input/JSON/JSONSchema.swift @@ -24,6 +24,7 @@ internal class JSONSchema: Decodable { case items = "items" case readOnly = "readOnly" case ref = "$ref" + case oneOf = "oneOf" case allOf = "allOf" } @@ -77,6 +78,7 @@ internal class JSONSchema: Decodable { self.readOnly = try keyedContainer.decodeIfPresent(Bool.self, forKey: .readOnly) self.ref = try keyedContainer.decodeIfPresent(String.self, forKey: .ref) self.allOf = try keyedContainer.decodeIfPresent([JSONSchema].self, forKey: .allOf) + self.oneOf = try keyedContainer.decodeIfPresent([JSONSchema].self, forKey: .oneOf) } catch let keyedContainerError as DecodingError { // If data in this `decoder` cannot be represented as keyed container, perhaps it encodes // a single value. Check known schema values: @@ -146,45 +148,71 @@ internal class JSONSchema: Decodable { private var ref: String? /// Subschemas to be resolved. - /// https://json-schema.org/draft/2019-09/json-schema-core.html#allOf + /// https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9.2.1.1 private var allOf: [JSONSchema]? - /// All child schemas, used when traversing the schema for `$ref` and `allOf` resolution. - private var allChildSchemas: [JSONSchema] { - var schemas: [JSONSchema] = [] - items.ifNotNil { schemas.append($0) } - allOf.ifNotNil { schemas.append(contentsOf: $0) } - properties.ifNotNil { schemas.append(contentsOf: $0.values.map { $0 }) } - return schemas - } + /// Subschemas to be resolved. + /// https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9.2.1.3 + private var oneOf: [JSONSchema]? + + // MARK: - Resolving Schema References + + /// Resolves `$ref` recursively. + /// + /// All sub-schemas with `$ref`, including `self` will be resolved. + /// Only `allOf` references will be merged with `self` while `oneOf` + /// are kept as orphan objects + /// + /// - Parameters: + /// - directory: The directory in which to look for referred schemas. + /// - reader: The schema file reader. + func resolveReferences(in directory: URL, using reader: JSONSchemaReader) throws { + // resolve `properties.$ref` + try properties?.map(\.value).forEach { + try $0.resolveReferences(in: directory, using: reader) + } - // MARK: - Resolving Schema Reference + // resolve `items.$ref` + try items.map { + try $0.resolveReferences(in: directory, using: reader) + } - /// Recursively traverses this schema to find the references to `otherSchema`. If the reference is found - /// the `otherSchema` gets merged at the level of `$ref` applicator. - func resolveReference(to otherSchema: JSONSchema) throws { - let referencedID = try otherSchema.id.unwrapOrThrow(.inconsistency("Schema without `$id` cannot be referenced.")) - let reference = findReference(to: referencedID) - reference?.merge(with: otherSchema) - } + // resolve `oneOf[].$ref` + // `oneOf` schemas are kept as orphans + try oneOf?.forEach { + try $0.resolveReferences(in: directory, using: reader) + } - /// Recursively searches all child schemas to find the one which contains `$ref` to given `referencedID`. - private func findReference(to referencedID: String) -> JSONSchema? { - if ref == referencedID { - return self - } else { - return allChildSchemas.compactMap { $0.findReference(to: referencedID) }.first + // resolve `allOf[].$ref` + // merge `allOf` schemas with `self` + try allOf?.forEach { + try $0.resolveReferences(in: directory, using: reader) + merge(with: $0) + } + + // resolve `$ref` + try ref.map { ref in + let url = directory.appendingPathComponent(ref) + let schema = try reader.read(url) + merge(with: schema) } } // MARK: - Resolving Subschemas - func resolveSubschemas() { - // Resolve all subschemas (head recursion guarantees that leaf schemas are resolved first). - allChildSchemas.forEach { $0.resolveSubschemas() } + /// Find all sub-schemas recursively, including self for types `object` and `array`. + var subschemas: [JSONSchema] { + let root: [JSONSchema] + + if type == .object, let props = properties, !props.isEmpty { + root = [self] + } else if type == .array, let items = items { + root = [items] + } else { + root = [] + } - // Merge this schema with each subschema from `allOf` array. - allOf?.forEach { merge(with: $0) } + return oneOf?.reduce(root) { $0 + $1.subschemas } ?? root } // MARK: - Schemas Merging @@ -201,6 +229,9 @@ internal class JSONSchema: Decodable { // Description can be overwritten self.description = self.description ?? otherSchema.description + // Type can be inferred + self.type = self.type ?? otherSchema.type + // Properties are accumulated and if both schemas have a property with the same name, property // schemas are merged. if let selfProperties = self.properties, let otherProperties = otherSchema.properties { @@ -245,5 +276,12 @@ internal class JSONSchema: Decodable { } else { self.readOnly = self.readOnly ?? otherSchema.readOnly } + + // Accumulate `oneOf` schemas + if let selfOneOf = oneOf, let otherOneOf = otherSchema.oneOf { + self.oneOf = selfOneOf + otherOneOf + } else if let otherOneOf = otherSchema.oneOf { + self.oneOf = otherOneOf + } } } diff --git a/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/Input/JSON/JSONSchemaReader.swift b/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/Input/JSON/JSONSchemaReader.swift index 8c8999730d..8286801c60 100644 --- a/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/Input/JSON/JSONSchemaReader.swift +++ b/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/Input/JSON/JSONSchemaReader.swift @@ -8,31 +8,25 @@ import Foundation /// Reads `JSONSchema` from file. internal class JSONSchemaReader { - private let jsonDecoder = JSONDecoder() + private let decoder: JSONDecoder - func readJSONSchemas(from schemaFiles: [File], resolvingAgainst referencedSchemaFiles: [File]) throws -> [JSONSchema] { - return try schemaFiles.map { schemaFile in - return try readJSONSchema(from: schemaFile, resolvingAgainst: referencedSchemaFiles) - } + init(decoder: JSONDecoder = .init()) { + self.decoder = decoder } - func readJSONSchema(from schemaFile: File, resolvingAgainst referencedSchemaFiles: [File]) throws -> JSONSchema { - let schema = try withErrorContext(context: "Error while decoding \(schemaFile.name)") { - try jsonDecoder.decode(JSONSchema.self, from: schemaFile.content) + func read(_ file: URL) throws -> JSONSchema { + let schema: JSONSchema = try withErrorContext(context: "Error while decoding \(file)") { + let data = try Data(contentsOf: file) + return try decoder.decode(JSONSchema.self, from: data) } - let referencedSchemas = try referencedSchemaFiles - .map { schemaFile in - return try withErrorContext(context: "Error while decoding \(schemaFile.name)") { - try jsonDecoder.decode(JSONSchema.self, from: schemaFile.content) - } - } - - // Resolve references to other schemas - try referencedSchemas.forEach { try schema.resolveReference(to: $0) } - // Resolve subschemas - schema.resolveSubschemas() + try schema.resolveReferences(in: file.deletingLastPathComponent(), using: self) return schema } + + func readAll(from file: URL) throws -> [JSONSchema] { + let schema = try read(file) + return schema.subschemas + } } diff --git a/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/RUM/RUMSwiftTypeTransformer.swift b/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/RUM/RUMSwiftTypeTransformer.swift index 19048d7fb0..5ccff47e84 100644 --- a/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/RUM/RUMSwiftTypeTransformer.swift +++ b/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/RUM/RUMSwiftTypeTransformer.swift @@ -10,7 +10,7 @@ import Foundation internal class RUMSwiftTypeTransformer: TypeTransformer { /// Types which will shared between all input `types`. Sharing means detaching those types from nested declaration /// and putting them at the root level of the resultant `types` array, so the type can be printed without being nested. - private let sharedTypeNames = ["RUMConnectivity", "RUMUser", "RUMMethod", "RUMEventAttributes"] + private let sharedTypeNames = ["RUMConnectivity", "RUMUser", "RUMMethod", "RUMEventAttributes", "RUMCITest"] /// `RUMDataModel` protocol, implemented by all RUM models. private let rumDataModelProtocol = SwiftProtocol(name: "RUMDataModel", conformance: [codableProtocol]) @@ -172,6 +172,10 @@ internal class RUMSwiftTypeTransformer: TypeTransformer { fixedName = "RUMEventAttributes" } + if fixedName == "CiTest" { + fixedName = "RUMCITest" + } + return fixedName } diff --git a/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/RUMModelsGenerator.swift b/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/RUMModelsGenerator.swift index 4bf6b280f5..9856a86c80 100644 --- a/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/RUMModelsGenerator.swift +++ b/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/RUMModelsGenerator.swift @@ -6,40 +6,6 @@ import Foundation -public struct File { - internal let name: String - internal let content: Data -} - -public extension File { - init(url: URL) throws { - self.name = url.lastPathComponent - self.content = try Data(contentsOf: url) - } -} - -public struct RUMJSONSchemaFiles { - internal let commonSchema: File - internal let actionSchema: File - internal let errorSchema: File - internal let longTaskSchema: File - internal let resourceSchema: File - internal let viewSchema: File -} - -public extension RUMJSONSchemaFiles { - init(folder url: URL) throws { - self.init( - commonSchema: try File(url: url.appendingPathComponent("_common-schema.json")), - actionSchema: try File(url: url.appendingPathComponent("action-schema.json")), - errorSchema: try File(url: url.appendingPathComponent("error-schema.json")), - longTaskSchema: try File(url: url.appendingPathComponent("long_task-schema.json")), - resourceSchema: try File(url: url.appendingPathComponent("resource-schema.json")), - viewSchema: try File(url: url.appendingPathComponent("view-schema.json")) - ) - } -} - public class RUMModelsGenerator { public enum Printer { /// Swift code printer. @@ -51,22 +17,10 @@ public class RUMModelsGenerator { public init() {} public func printRUMModels( - for schemaFiles: RUMJSONSchemaFiles, + path file: URL, using printer: Printer ) throws -> String { - let mainSchemaFiles = [ - schemaFiles.viewSchema, - schemaFiles.resourceSchema, - schemaFiles.actionSchema, - schemaFiles.errorSchema, - schemaFiles.longTaskSchema, - ] - - // Read ambiguous JSON schemas from `*.json` files - let jsonSchemas = try JSONSchemaReader().readJSONSchemas( - from: mainSchemaFiles, - resolvingAgainst: [schemaFiles.commonSchema] - ) + let jsonSchemas = try JSONSchemaReader().readAll(from: file) // Transform into type-safe JSONObjects let jsonObjects = try JSONSchemaToJSONTypeTransformer().transform(jsonSchemas: jsonSchemas) diff --git a/tools/rum-models-generator/Sources/rum-models-generator/main.swift b/tools/rum-models-generator/Sources/rum-models-generator/main.swift index ca18270251..cd2a6e4720 100644 --- a/tools/rum-models-generator/Sources/rum-models-generator/main.swift +++ b/tools/rum-models-generator/Sources/rum-models-generator/main.swift @@ -28,10 +28,9 @@ private struct RootCommand: ParsableCommand { func run() { do { - let schemasFolderURL = URL(fileURLWithPath: path) - let schemas = try RUMJSONSchemaFiles(folder: schemasFolderURL) + let path = URL(fileURLWithPath: path) let generator = RUMModelsGenerator() - print(try generator.printRUMModels(for: schemas, using: .swift)) + print(try generator.printRUMModels(path: path, using: .swift)) } catch { print("Failed to generate Swift models: \(error)") } @@ -49,10 +48,9 @@ private struct RootCommand: ParsableCommand { func run() { do { - let schemasFolderURL = URL(fileURLWithPath: path) - let schemas = try RUMJSONSchemaFiles(folder: schemasFolderURL) + let path = URL(fileURLWithPath: path) let generator = RUMModelsGenerator() - print(try generator.printRUMModels(for: schemas, using: .objcInterop)) + print(try generator.printRUMModels(path: path, using: .objcInterop)) } catch { print("Failed to generate Objc models: \(error)") } diff --git a/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer.json b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer.json new file mode 100644 index 0000000000..1f03b7a6e3 --- /dev/null +++ b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer.json @@ -0,0 +1,10 @@ +{ + "$id": "fixture-json-schema-to-json-type-transformer.json", + "type": "object", + "description": "Fixture schema", + "oneOf": [ + { + "$ref": "fixture-json-schema-to-json-type-transformer/main.json" + } + ] + } \ No newline at end of file diff --git a/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer/main.json b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer/main.json new file mode 100644 index 0000000000..46633cb28b --- /dev/null +++ b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer/main.json @@ -0,0 +1,50 @@ +{ + "type": "object", + "title": "Foo", + "description": "Description of Foo.", + "allOf": [ + { "$ref": "schema-1.json" }, + { "$ref": "schema-2.json" }, + { + "properties": { + "stringEnumProperty": { + "type": "string", + "description": "Description of Foo's `stringEnumProperty`.", + "enum": ["case1", "case2", "case3", "case4"], + "const": "case2" + }, + "integerEnumProperty": { + "type": "number", + "description": "Description of Foo's `integerEnumProperty`.", + "enum": [1, 2, 3, 4], + "const": 3 + }, + "arrayProperty": { + "type": "array", + "description": "Description of Foo's `arrayProperty`.", + "items": { + "type": "string", + "enum": ["option1", "option2", "option3", "option4"] + }, + "readOnly": false + }, + "propertyWithAdditionalProperties": { + "type": "object", + "description": "Description of a property with nested additional properties.", + "additionalProperties": { + "type": "integer", + "minimum": 0, + "readOnly": true + }, + "readOnly": true + } + }, + "additionalProperties": { + "type": "string", + "description": "Additional properties of Foo.", + "readOnly": true + }, + "required": ["stringEnumProperty"], + } + ] +} \ No newline at end of file diff --git a/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer/schema-1.json b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer/schema-1.json new file mode 100644 index 0000000000..d8ca9b66bb --- /dev/null +++ b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer/schema-1.json @@ -0,0 +1,17 @@ +{ + "$id": "schema-1.json", + "type": "object", + "properties": { + "bar": { + "type": "object", + "description": "Description of Bar.", + "properties": { + "property1": { + "type": "string", + "description": "Description of Bar's `property1`.", + "readOnly": true + } + } + } + } +} \ No newline at end of file diff --git a/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer/schema-2.json b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer/schema-2.json new file mode 100644 index 0000000000..7ff4f003a0 --- /dev/null +++ b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer/schema-2.json @@ -0,0 +1,18 @@ +{ + "$id": "schema-2.json", + "type": "object", + "properties": { + "bar": { + "type": "object", + "description": "Description of Bar.", + "properties": { + "property2": { + "type": "string", + "description": "Description of Bar's `property2`.", + "readOnly": false + } + }, + "required": ["property2"] + } + } +} \ No newline at end of file diff --git a/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-reading-schema-with-additional-properties-with-no-type.json b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-reading-schema-with-additional-properties-with-no-type.json new file mode 100644 index 0000000000..5cf0396014 --- /dev/null +++ b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-reading-schema-with-additional-properties-with-no-type.json @@ -0,0 +1,13 @@ +{ + "additionalProperties": true, + "properties": { + "foo": { + "type": "string", + "readOnly": true + }, + "bar": { + "type": "object", + "additionalProperties": true + } + } +} \ No newline at end of file diff --git a/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-reading-schema-with-typed-additional-properties.json b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-reading-schema-with-typed-additional-properties.json new file mode 100644 index 0000000000..e791a3487d --- /dev/null +++ b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-reading-schema-with-typed-additional-properties.json @@ -0,0 +1,44 @@ +{ + "$id": "Schema ID", + "type": "object", + "title": "Schema title", + "description": "Schema description.", + "properties": { + "stringEnumProperty": { + "type": "string", + "description": "Description of `stringEnumProperty`.", + "enum": ["case1", "case2", "case3", "case4"], + "const": "case2" + }, + "integerEnumProperty": { + "type": "number", + "description": "Description of `integerEnumProperty`.", + "enum": [1, 2, 3, 4], + "const": 3 + }, + "arrayProperty": { + "type": "array", + "description": "Description of `arrayProperty`.", + "items": { + "type": "string", + "enum": ["option1", "option2", "option3", "option4"] + }, + "readOnly": false + }, + "propertyWithAdditionalProperties": { + "type": "object", + "description": "Description of a property with nested additional properties.", + "additionalProperties": { + "type": "integer", + "readOnly": true + }, + "readOnly": true + } + }, + "additionalProperties": { + "type": "string", + "description": "Additional properties of main schema.", + "readOnly": true + }, + "required": ["property1"] +} \ No newline at end of file diff --git a/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Input/JSONSchemaReaderTests.swift b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Input/JSONSchemaReaderTests.swift index 7084ae7944..5da97a0123 100644 --- a/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Input/JSONSchemaReaderTests.swift +++ b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Input/JSONSchemaReaderTests.swift @@ -9,58 +9,9 @@ import XCTest final class JSONSchemaReaderTests: XCTestCase { func testReadingSchemaWithTypedAdditionalProperties() throws { - let mainSchema = """ - { - "$id": "Schema ID", - "type": "object", - "title": "Schema title", - "description": "Schema description.", - "properties": { - "stringEnumProperty": { - "type": "string", - "description": "Description of `stringEnumProperty`.", - "enum": ["case1", "case2", "case3", "case4"], - "const": "case2" - }, - "integerEnumProperty": { - "type": "number", - "description": "Description of `integerEnumProperty`.", - "enum": [1, 2, 3, 4], - "const": 3 - }, - "arrayProperty": { - "type": "array", - "description": "Description of `arrayProperty`.", - "items": { - "type": "string", - "enum": ["option1", "option2", "option3", "option4"] - }, - "readOnly": false - }, - "propertyWithAdditionalProperties": { - "type": "object", - "description": "Description of a property with nested additional properties.", - "additionalProperties": { - "type": "integer", - "readOnly": true - }, - "readOnly": true - } - }, - "additionalProperties": { - "type": "string", - "description": "Additional properties of main schema.", - "readOnly": true - }, - "required": ["property1"] - } - """ - - let schema = try JSONSchemaReader() - .readJSONSchema( - from: File(name: "main-schema", content: mainSchema.data(using: .utf8)!), - resolvingAgainst: [] - ) + let file = Bundle.module.url(forResource: "Fixtures/fixture-reading-schema-with-typed-additional-properties", withExtension: "json")! + + let schema = try JSONSchemaReader().read(file) XCTAssertEqual(schema.id, "Schema ID") XCTAssertEqual(schema.title, "Schema title") @@ -102,28 +53,9 @@ final class JSONSchemaReaderTests: XCTestCase { } func testReadingSchemaWithAdditionalPropertiesWithNoType() throws { - let mainSchema = """ - { - "additionalProperties": true, - "properties": { - "foo": { - "type": "string", - "readOnly": true - }, - "bar": { - "type": "object", - "additionalProperties": true - } - } - } - """ - - let schema = try JSONSchemaReader() - .readJSONSchema( - from: File(name: "main-schema", content: mainSchema.data(using: .utf8)!), - resolvingAgainst: [] - ) + let file = Bundle.module.url(forResource: "Fixtures/fixture-reading-schema-with-additional-properties-with-no-type", withExtension: "json")! + let schema = try JSONSchemaReader().read(file) XCTAssertEqual(schema.properties?.count, 2) XCTAssertNotNil(schema.properties?["foo"]) diff --git a/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Input/JSONSchemaToJSONTypeTransformerTests.swift b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Input/JSONSchemaToJSONTypeTransformerTests.swift index 9b51b95b7f..1754eccba4 100644 --- a/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Input/JSONSchemaToJSONTypeTransformerTests.swift +++ b/tools/rum-models-generator/Tests/rum-models-generator-coreTests/Input/JSONSchemaToJSONTypeTransformerTests.swift @@ -9,100 +9,6 @@ import XCTest final class JSONSchemaToJSONTypeTransformerTests: XCTestCase { func testTransformingJSONSchemaIntoJSONObject() throws { - let referencedSchema1 = """ - { - "$id": "referenced-schema1.json", - "type": "object", - "properties": { - "bar": { - "type": "object", - "description": "Description of Bar.", - "properties": { - "property1": { - "type": "string", - "description": "Description of Bar's `property1`.", - "readOnly": true - } - } - } - } - } - """ - - let referencedSchema2 = """ - { - "$id": "referenced-schema2.json", - "type": "object", - "properties": { - "bar": { - "type": "object", - "description": "Description of Bar.", - "properties": { - "property2": { - "type": "string", - "description": "Description of Bar's `property2`.", - "readOnly": false - } - }, - "required": ["property2"] - } - } - } - """ - - let mainSchema = """ - { - "type": "object", - "title": "Foo", - "description": "Description of Foo.", - "allOf": [ - { "$ref": "referenced-schema1.json" }, - { "$ref": "referenced-schema2.json" }, - { - "properties": { - "stringEnumProperty": { - "type": "string", - "description": "Description of Foo's `stringEnumProperty`.", - "enum": ["case1", "case2", "case3", "case4"], - "const": "case2" - }, - "integerEnumProperty": { - "type": "number", - "description": "Description of Foo's `integerEnumProperty`.", - "enum": [1, 2, 3, 4], - "const": 3 - }, - "arrayProperty": { - "type": "array", - "description": "Description of Foo's `arrayProperty`.", - "items": { - "type": "string", - "enum": ["option1", "option2", "option3", "option4"] - }, - "readOnly": false - }, - "propertyWithAdditionalProperties": { - "type": "object", - "description": "Description of a property with nested additional properties.", - "additionalProperties": { - "type": "integer", - "minimum": 0, - "readOnly": true - }, - "readOnly": true - } - }, - "additionalProperties": { - "type": "string", - "description": "Additional properties of Foo.", - "readOnly": true - }, - "required": ["stringEnumProperty"], - } - ] - } - """ - let expected = JSONObject( name: "Foo", comment: "Description of Foo.", @@ -200,16 +106,11 @@ final class JSONSchemaToJSONTypeTransformerTests: XCTestCase { ) ) - let jsonSchema = try JSONSchemaReader() - .readJSONSchema( - from: File(name: "main-schema", content: mainSchema.data(using: .utf8)!), - resolvingAgainst: [ - File(name: "referenced-schema-1", content: referencedSchema1.data(using: .utf8)!), - File(name: "referenced-schema-2", content: referencedSchema2.data(using: .utf8)!), - ] - ) + let file = Bundle.module.url(forResource: "Fixtures/fixture-json-schema-to-json-type-transformer", withExtension: "json")! + + let jsonSchemas = try JSONSchemaReader().readAll(from: file) - let actual = try JSONSchemaToJSONTypeTransformer().transform(jsonSchemas: [jsonSchema]) + let actual = try JSONSchemaToJSONTypeTransformer().transform(jsonSchemas: jsonSchemas) XCTAssertEqual(actual.count, 1) XCTAssertEqual(expected, actual[0]) diff --git a/tools/rum-models-generator/run.sh b/tools/rum-models-generator/run.sh index c77b8a799d..51f25041fb 100755 --- a/tools/rum-models-generator/run.sh +++ b/tools/rum-models-generator/run.sh @@ -71,13 +71,13 @@ GENERATOR=".build/x86_64-apple-macosx/release/rum-models-generator" # Generate RUM models (Swift) file in temporary location mkdir -p ".temp" GENERATED_SWIFT_FILE=".temp/RUMDataModels.swift" -$GENERATOR generate-swift --path "rum-events-format/schemas" > $GENERATED_SWIFT_FILE +$GENERATOR generate-swift --path "rum-events-format/rum-events-format.json" > $GENERATED_SWIFT_FILE echo "// Generated from https://github.com/DataDog/rum-events-format/tree/$SHA" >> $GENERATED_SWIFT_FILE # Generate RUM models (Objc) file in temporary location mkdir -p ".temp" GENERATED_OBJC_FILE=".temp/RUMDataModels+objc.swift" -$GENERATOR generate-objc --path "rum-events-format/schemas" > $GENERATED_OBJC_FILE +$GENERATOR generate-objc --path "rum-events-format/rum-events-format.json" > $GENERATED_OBJC_FILE echo "// Generated from https://github.com/DataDog/rum-events-format/tree/$SHA" >> $GENERATED_OBJC_FILE if [[ $MODE == $MODE_VERIFY ]]; then diff --git a/xcconfigs/Base.xcconfig b/xcconfigs/Base.xcconfig index 51c2262969..2eb2856c61 100644 --- a/xcconfigs/Base.xcconfig +++ b/xcconfigs/Base.xcconfig @@ -1,5 +1,9 @@ // Base configuration file for all targets. // Note: all configuration here will be applied to `Datadog*.framework` produced by Carthage. +DD_SWIFT_SDK_PRODUCT_NAME=Datadog +DD_OBJC_SDK_PRODUCT_NAME=DatadogObjc +DD_CR_SDK_PRODUCT_NAME=DatadogCrashReporting + // Include internal base config (git-ignored, so excluded from Carthage build) #include? "Base.local.xcconfig" diff --git a/xcconfigs/Datadog.xcconfig b/xcconfigs/Datadog.xcconfig index 6be081ae6d..952aa01e46 100644 --- a/xcconfigs/Datadog.xcconfig +++ b/xcconfigs/Datadog.xcconfig @@ -11,5 +11,9 @@ DATADOG_CLIENT_TOKEN=// use your own Client Token, generated for RUM_APPLICATION E2E_RUM_APPLICATION_ID=// use your own RUM Application ID obtained on datadoghq.com E2E_DATADOG_CLIENT_TOKEN=// use your own Client Token, generated for E2E_RUM_APPLICATION_ID +CUSTOM_LOGS_URL=// Do NOT add https! example: foo.com/api/v2/logs +CUSTOM_TRACE_URL=// Do NOT add https! example: foo.com/api/v2/spans +CUSTOM_RUM_URL=// Do NOT add https! example: foo.com/api/v2/rum + // Overwrite with secrets #include? "Datadog.local.xcconfig"