From 512624babf567dcc4cdb920c304b47481a11789a Mon Sep 17 00:00:00 2001 From: Austin Lai Date: Fri, 28 Jan 2022 12:23:12 -0800 Subject: [PATCH 001/104] DOCS-3052 Implements absolute URLs for the doc site and copy nits. --- docs/README.md | 6 +- docs/rum_collection/_index.md | 4 +- docs/rum_collection/advanced_configuration.md | 104 ++++++++++-------- docs/rum_collection/crash_reporting.md | 2 +- docs/rum_collection/data_collected.md | 4 +- docs/rum_collection/troubleshooting.md | 2 +- 6 files changed, 68 insertions(+), 54 deletions(-) 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/rum_collection/_index.md b/docs/rum_collection/_index.md index c737baf7e4..af7bf7d2fb 100644 --- a/docs/rum_collection/_index.md +++ b/docs/rum_collection/_index.md @@ -136,5 +136,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 c2bc218012..96da31979b 100644 --- a/docs/rum_collection/advanced_configuration.md +++ b/docs/rum_collection/advanced_configuration.md @@ -18,12 +18,13 @@ 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: + ```swift // in your `UIViewController`: @@ -37,6 +38,7 @@ override func viewDidDisappear(_ animated: Bool) { Global.rum.stopView(viewController: self) } ``` + Find more details and available options in `DDRUMMonitor` class. ### Add your own performance timing @@ -49,19 +51,16 @@ func onHeroImageLoaded() { } ``` -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. -or for continuous RUM actions (e.g: `.scroll`), use: -- `.startUserAction(type:name:)` -- `.stopUserAction(type:)` +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:)`. + +For example: -Example: ```swift // in your `UIViewController`: @@ -79,7 +78,7 @@ Find more details and available options in `DDRUMMonitor` class. ### 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:)` @@ -106,7 +105,7 @@ Find more details and available options in `DDRUMMonitor` class. ### 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]. ```swift Global.rum.addError(message: "error message.") @@ -114,10 +113,9 @@ Global.rum.addError(message: "error message.") For more details and available options, refer to the code documentation comments in `DDRUMMonitor` class. - ## 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][6] 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). @@ -147,7 +145,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: ```swift Datadog.setUserInfo(id: "1234", name: "John Doe", email: "john@doe.com") @@ -161,10 +161,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 @@ -172,10 +172,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. @@ -184,16 +184,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. @@ -224,6 +224,7 @@ public protocol UIKitRUMViewsPredicate { 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: + ```swift class YourCustomPredicate: UIKitRUMViewsPredicate { @@ -238,6 +239,7 @@ class YourCustomPredicate: UIKitRUMViewsPredicate { ``` 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: + ```swift class YourCustomPredicate: UIKitRUMViewsPredicate { @@ -260,6 +262,7 @@ To automatically track user tap actions, use the `.trackUIKitActions()` option w ### Automatically track network requests To automatically track resources (network requests) and get their timing information such as time to first byte or DNS resolution, use the `.trackURLSession()` option when configuring the SDK and set `DDURLSessionDelegate` for the `URLSession` that you want to monitor: + ```swift let session = URLSession( configuration: .default, @@ -268,9 +271,10 @@ let session = URLSession( ) ``` -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 the first party host and enable both RUM and Tracing features: -For instance, you can configure `example.com` as first party host and enable both RUM and Tracing features: ```swift Datadog.initialize( // ... @@ -290,11 +294,13 @@ 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][10]. + +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][7]. 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: + ```swift .setRUMResourceAttributesProvider { request, response, data, error in return [ @@ -302,12 +308,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: + ```swift let logger = Logger.builder.build() @@ -316,6 +322,7 @@ logger.critical("message") ``` Similarly, all finished spans marked as error are reported as RUM errors: + ```swift let span = Global.sharedTracer.startSpan(operationName: "operation") // ... capture the `error` @@ -326,6 +333,7 @@ span.finish() ## Modify or drop RUM events To modify attributes of a RUM event before it is sent to Datadog or to drop an event entirely, use the event mappers API when configuring the SDK: + ```swift Datadog.Configuration .builderUsing(...) @@ -343,6 +351,7 @@ Datadog.Configuration } .build() ``` + 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`: ```swift @@ -353,7 +362,7 @@ Each mapper is a Swift closure with a signature of `(T) -> T?`, where `T` is a c } ``` -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 (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](#automatically-track-views)). Depending on the event's type, only some specific properties can be modified: @@ -373,23 +382,26 @@ 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. -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`: +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. +- 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: + ```swift Datadog.initialize( // ... @@ -411,7 +423,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. ```swift Datadog.initialize( @@ -430,21 +444,17 @@ Datadog.initialize( ) ``` +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 diff --git a/docs/rum_collection/crash_reporting.md b/docs/rum_collection/crash_reporting.md index e7b9352430..daa600d2b8 100644 --- a/docs/rum_collection/crash_reporting.md +++ b/docs/rum_collection/crash_reporting.md @@ -97,7 +97,7 @@ If your application has Bitcode enabled, download your app's dSYM files on [App {{< partial name="whats-next/whats-next.html" >}} [1]: https://app.datadoghq.com/rum/application/create -[2]: /real_user_monitoring/ios +[2]: https://docs.datadoghq.com/real_user_monitoring/ios [3]: https://github.com/DataDog/dd-sdk-ios/releases [4]: https://github.com/DataDog/datadog-ci [5]: https://www.npmjs.com/package/@datadog/datadog-ci diff --git a/docs/rum_collection/data_collected.md b/docs/rum_collection/data_collected.md index c680bbeafb..67b3ba8917 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -224,5 +224,5 @@ Network errors include information about failing HTTP requests. The following fa {{< 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 diff --git a/docs/rum_collection/troubleshooting.md b/docs/rum_collection/troubleshooting.md index 4d85deb073..200d049706 100644 --- a/docs/rum_collection/troubleshooting.md +++ b/docs/rum_collection/troubleshooting.md @@ -33,4 +33,4 @@ If all goes well you should see output similar to this saying that a batch of RU {{< 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/#initialization-parameters From c756a753050b2556fe41350de8593ba64510953c Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 1 Feb 2022 10:35:54 +0100 Subject: [PATCH 002/104] RUMM-1769 Fix logs doc rendering --- docs/log_collection.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/log_collection.md b/docs/log_collection.md index 26442324f2..859f73fc26 100644 --- a/docs/log_collection.md +++ b/docs/log_collection.md @@ -107,20 +107,20 @@ 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: +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. +- `.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`: +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. +- 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. - 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. + 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. {{< tabs >}} {{% tab "Swift" %}} From 5c7d72a9c2d96dd11f9c5f901bb625d4566d77b6 Mon Sep 17 00:00:00 2001 From: Austin Lai <76412946+alai97@users.noreply.github.com> Date: Wed, 2 Feb 2022 09:05:43 -0800 Subject: [PATCH 003/104] SME Review Co-authored-by: Maciek Grzybowski --- docs/rum_collection/advanced_configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rum_collection/advanced_configuration.md b/docs/rum_collection/advanced_configuration.md index 96da31979b..f51b4d9911 100644 --- a/docs/rum_collection/advanced_configuration.md +++ b/docs/rum_collection/advanced_configuration.md @@ -115,7 +115,7 @@ For more details and available options, refer to the code documentation comments ## Track custom global attributes -In addition to the [default RUM attributes][6] 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). @@ -295,7 +295,7 @@ let session = URLSession( ) ``` -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][7]. +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]. 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. From 8f28c68f75147172650c5b3d5ed736586c7c4ea1 Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Thu, 3 Feb 2022 14:07:22 +0100 Subject: [PATCH 004/104] RUMM-1964 Update `distribution` tool to separate release-related classes so we can share some of this code with dogfooding tool. --- tools/distribution/release.py | 8 ++++---- tools/distribution/src/{ => release}/assets/gh_asset.py | 6 +++--- tools/distribution/src/{ => release}/assets/podspec.py | 2 +- tools/distribution/src/{ => release}/directory_matcher.py | 0 tools/distribution/src/{ => release}/git.py | 0 tools/distribution/src/{ => release}/semver.py | 0 tools/distribution/src/{ => release}/utils.py | 0 .../tests/{ => release}/test_directory_matcher.py | 2 +- tools/distribution/tests/{ => release}/test_semver.py | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) rename tools/distribution/src/{ => release}/assets/gh_asset.py (98%) rename tools/distribution/src/{ => release}/assets/podspec.py (98%) rename tools/distribution/src/{ => release}/directory_matcher.py (100%) rename tools/distribution/src/{ => release}/git.py (100%) rename tools/distribution/src/{ => release}/semver.py (100%) rename tools/distribution/src/{ => release}/utils.py (100%) rename tools/distribution/tests/{ => release}/test_directory_matcher.py (97%) rename tools/distribution/tests/{ => release}/test_semver.py (98%) diff --git a/tools/distribution/release.py b/tools/distribution/release.py index 1c8254413a..a2fb247c9b 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' diff --git a/tools/distribution/src/assets/gh_asset.py b/tools/distribution/src/release/assets/gh_asset.py similarity index 98% rename from tools/distribution/src/assets/gh_asset.py rename to tools/distribution/src/release/assets/gh_asset.py index 7c3c0b5276..23c03ab93a 100644 --- a/tools/distribution/src/assets/gh_asset.py +++ b/tools/distribution/src/release/assets/gh_asset.py @@ -10,9 +10,9 @@ import os 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.utils import remember_cwd, shell, read_sdk_version, read_xcode_version +from src.release.directory_matcher import DirectoryMatcher +from src.release.semver import Version class XCFrameworkValidator: diff --git a/tools/distribution/src/assets/podspec.py b/tools/distribution/src/release/assets/podspec.py similarity index 98% rename from tools/distribution/src/assets/podspec.py rename to tools/distribution/src/release/assets/podspec.py index 24fd1812cc..3b7469b095 100644 --- a/tools/distribution/src/assets/podspec.py +++ b/tools/distribution/src/release/assets/podspec.py @@ -11,7 +11,7 @@ import re import time import random -from src.utils import shell, read_sdk_version +from src.release.utils import shell, read_sdk_version class CPPodspec: 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 100% rename from tools/distribution/src/semver.py rename to tools/distribution/src/release/semver.py diff --git a/tools/distribution/src/utils.py b/tools/distribution/src/release/utils.py similarity index 100% rename from tools/distribution/src/utils.py rename to tools/distribution/src/release/utils.py 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): From 773f39429f8b29bf4f70572830b5636fb857de21 Mon Sep 17 00:00:00 2001 From: Mert Buran Date: Thu, 3 Feb 2022 14:55:53 +0100 Subject: [PATCH 005/104] RUMM-1931 stopTrackingDatadogEvents added to avoid memory leaks Without removing ScriptMessageHandlers explicitly, they stay alive in memory even after deallocation of the webview --- .../WKUserContentController+Datadog.swift | 16 ++++++++++ ...WKUserContentController+DatadogTests.swift | 31 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift b/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift index 10922285cd..336eee974d 100644 --- a/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift +++ b/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift @@ -27,6 +27,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.") diff --git a/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift b/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift index 22181cfeb3..cabbc9bbc3 100644 --- a/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift @@ -23,6 +23,12 @@ final class DDUserContentController: WKUserContentController { } } +final class MockMessageHandler: NSObject, WKScriptMessageHandler { + func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { + return + } +} + final class MockScriptMessage: WKScriptMessage { let mockBody: Any @@ -96,6 +102,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.. Date: Thu, 3 Feb 2022 14:48:31 +0100 Subject: [PATCH 006/104] RUMM-1964 Merge `dogfood` tool into `distribution` so we can share some of their concepts. --- tools/{dogfooding => distribution}/dogfood.py | 6 +++--- .../src => distribution/src/dogfood}/dogfooded_commit.py | 0 .../src => distribution/src/dogfood}/package_resolved.py | 0 .../src => distribution/src/dogfood}/repository.py | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename tools/{dogfooding => distribution}/dogfood.py (97%) rename tools/{dogfooding/src => distribution/src/dogfood}/dogfooded_commit.py (100%) rename tools/{dogfooding/src => distribution/src/dogfood}/package_resolved.py (100%) rename tools/{dogfooding/src => distribution/src/dogfood}/repository.py (100%) diff --git a/tools/dogfooding/dogfood.py b/tools/distribution/dogfood.py similarity index 97% rename from tools/dogfooding/dogfood.py rename to tools/distribution/dogfood.py index a9d4026e08..3ee5fb656a 100755 --- a/tools/dogfooding/dogfood.py +++ b/tools/distribution/dogfood.py @@ -12,9 +12,9 @@ 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 +from src.dogfood.package_resolved import PackageResolvedFile +from src.dogfood.dogfooded_commit import DogfoodedCommit +from src.dogfood.repository import Repository @contextlib.contextmanager diff --git a/tools/dogfooding/src/dogfooded_commit.py b/tools/distribution/src/dogfood/dogfooded_commit.py similarity index 100% rename from tools/dogfooding/src/dogfooded_commit.py rename to tools/distribution/src/dogfood/dogfooded_commit.py 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 100% rename from tools/dogfooding/src/repository.py rename to tools/distribution/src/dogfood/repository.py From 554a0ba5f2c091b66391faf50feb0e6a854c10d1 Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Fri, 4 Feb 2022 13:04:01 +0100 Subject: [PATCH 007/104] RUMM-1964 Add Makefile for preparing ENV for `distribution` tool --- tools/distribution/Makefile | 11 +++++++++++ tools/distribution/requirements.txt | 3 +++ 2 files changed, 14 insertions(+) create mode 100644 tools/distribution/Makefile create mode 100644 tools/distribution/requirements.txt diff --git a/tools/distribution/Makefile b/tools/distribution/Makefile new file mode 100644 index 0000000000..86e9a1fda6 --- /dev/null +++ b/tools/distribution/Makefile @@ -0,0 +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 + @echo "⚙️ Installing pip dependencies in $(PWD)/venv" + venv/bin/pip3 install -r requirements.txt 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 From 4596d0c998eff32d26e74bab8fcadda6c618bed6 Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Fri, 4 Feb 2022 13:16:36 +0100 Subject: [PATCH 008/104] RUMM-1964 Share utility code between `dogfooding` and `release` commands --- tools/distribution/dogfood.py | 23 ++++--------------- .../src/release/assets/gh_asset.py | 2 +- .../src/release/assets/podspec.py | 2 +- tools/distribution/src/{release => }/utils.py | 0 4 files changed, 7 insertions(+), 20 deletions(-) rename tools/distribution/src/{release => }/utils.py (100%) diff --git a/tools/distribution/dogfood.py b/tools/distribution/dogfood.py index 3ee5fb656a..5144cd1017 100755 --- a/tools/distribution/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.dogfood.package_resolved import PackageResolvedFile from src.dogfood.dogfooded_commit import DogfoodedCommit from src.dogfood.repository import Repository +from src.utils import remember_cwd -@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) - - -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/src/release/assets/gh_asset.py b/tools/distribution/src/release/assets/gh_asset.py index 23c03ab93a..fff6c6e66f 100644 --- a/tools/distribution/src/release/assets/gh_asset.py +++ b/tools/distribution/src/release/assets/gh_asset.py @@ -10,7 +10,7 @@ import os import glob from tempfile import TemporaryDirectory, NamedTemporaryFile -from src.release.utils import remember_cwd, shell, read_sdk_version, read_xcode_version +from src.utils import remember_cwd, shell, read_sdk_version, read_xcode_version from src.release.directory_matcher import DirectoryMatcher from src.release.semver import Version diff --git a/tools/distribution/src/release/assets/podspec.py b/tools/distribution/src/release/assets/podspec.py index 3b7469b095..24fd1812cc 100644 --- a/tools/distribution/src/release/assets/podspec.py +++ b/tools/distribution/src/release/assets/podspec.py @@ -11,7 +11,7 @@ import re import time import random -from src.release.utils import shell, read_sdk_version +from src.utils import shell, read_sdk_version class CPPodspec: diff --git a/tools/distribution/src/release/utils.py b/tools/distribution/src/utils.py similarity index 100% rename from tools/distribution/src/release/utils.py rename to tools/distribution/src/utils.py From fbc3bc8caa838f7be2bcdb8280f00f3e58e6a389 Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Fri, 4 Feb 2022 17:00:25 +0100 Subject: [PATCH 009/104] RUMM-1964 Add tool for updating dd-sdk-ios version in dependant SDK projects --- tools/distribution/src/dogfood/repository.py | 12 +- tools/distribution/update_upstream_sdks.py | 133 +++++++++++++++++++ 2 files changed, 141 insertions(+), 4 deletions(-) create mode 100755 tools/distribution/update_upstream_sdks.py diff --git a/tools/distribution/src/dogfood/repository.py b/tools/distribution/src/dogfood/repository.py index 40ceebf8c5..4e578f6e64 100644 --- a/tools/distribution/src/dogfood/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/update_upstream_sdks.py b/tools/distribution/update_upstream_sdks.py new file mode 100755 index 0000000000..62fe2f9893 --- /dev/null +++ b/tools/distribution/update_upstream_sdks.py @@ -0,0 +1,133 @@ +#!/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}') + + # Replace `dd-sdk-ios` version in `ios/datadog_sdk.podspec`: + with open('ios/datadog_sdk.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') + + # Run `pod update` in `example/ios` + with remember_cwd(): + print(f'ℹ️️ Changing current directory to: {clone_dir}/{flutter_repo_name}/example/ios') + os.chdir('example/ios') + + shell(command='flutter pub get') + 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}/integration_test_app/ios') + os.chdir('integration_test_app/ios') + + shell(command='flutter pub get') + 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_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_DRY_RUN = {os.environ.get("DD_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) From 47cc241126329a6d6e2b9f4efaee9f03161a98d0 Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Mon, 7 Feb 2022 12:04:39 +0100 Subject: [PATCH 010/104] RUMM-1964 Unify the way distribution scripts are launched --- Makefile | 3 -- bitrise.yml | 33 ++++++++++++++++--- .../src/dogfood/dogfooded_commit.py | 3 +- tools/dogfooding/Makefile | 10 ------ tools/license/check-license.sh | 2 +- 5 files changed, 32 insertions(+), 19 deletions(-) delete mode 100644 tools/dogfooding/Makefile diff --git a/Makefile b/Makefile index df3204a32a..ee9c436942 100644 --- a/Makefile +++ b/Makefile @@ -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/bitrise.yml b/bitrise.yml index 1e5df34600..9302f35930 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -274,9 +274,11 @@ workflows: title: Create PR to Datadog mobile app project inputs: - content: |- - #!/usr/bin/env bash + #!/usr/bin/env zsh set -e - make dogfood ci=${CI} + + cd tools/distribution && make + venv/bin/python3 dogfood.py run_e2e_tests: description: |- @@ -330,7 +332,8 @@ workflows: # Use 'DD_RELEASE_GIT_TAG' ENV if available, otherwise 'BITRISE_GIT_TAG' ENV GIT_TAG="${DD_RELEASE_GIT_TAG:-$(echo "${BITRISE_GIT_TAG}")}" - ./tools/distribution/release.py "$GIT_TAG" --only-github + cd tools/distribution && make + venv/bin/python3 release.py "$GIT_TAG" --only-github publish_cocoapods_podspecs: before_run: @@ -350,4 +353,26 @@ workflows: # Use 'DD_RELEASE_GIT_TAG' ENV if available, otherwise 'BITRISE_GIT_TAG' ENV GIT_TAG="${DD_RELEASE_GIT_TAG:-$(echo "${BITRISE_GIT_TAG}")}" - ./tools/distribution/release.py "$GIT_TAG" --only-cocoapods + cd tools/distribution && make + venv/bin/python3 release.py "$GIT_TAG" --only-cocoapods + + update_upstream_sdks: + before_run: + - _make_dependencies # install tooling + after_run: + - _notify_failure_on_slack + description: |- + Updates dd-sdk-ios version in upstream SDKs. + steps: + - script: + title: Run tools/distribution/update_upstream_sdks.py + inputs: + - content: |- + #!/usr/bin/env zsh + set -e + + # Use 'DD_RELEASE_GIT_TAG' ENV if available, otherwise 'BITRISE_GIT_TAG' ENV + GIT_TAG="${DD_RELEASE_GIT_TAG:-$(echo "${BITRISE_GIT_TAG}")}" + + cd tools/distribution && make + venv/bin/python3 update_upstream_sdks.py "$GIT_TAG" diff --git a/tools/distribution/src/dogfood/dogfooded_commit.py b/tools/distribution/src/dogfood/dogfooded_commit.py index 20132370a7..93bcf4cdff 100644 --- a/tools/distribution/src/dogfood/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/Makefile b/tools/dogfooding/Makefile deleted file mode 100644 index e335aadb37..0000000000 --- a/tools/dogfooding/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -.PHONY: all - -all: - @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 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" \ From 92f93745f5a18d46edb3878ddcf8c56a737b60d6 Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Mon, 7 Feb 2022 12:14:35 +0100 Subject: [PATCH 011/104] RUMM-1964 Run `update_upstream_sdks` CI job asynchronously after `publish_cocoapods_podspecs` --- bitrise.yml | 9 +++++++++ tools/distribution/update_upstream_sdks.py | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/bitrise.yml b/bitrise.yml index 9302f35930..23baa38716 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -355,6 +355,15 @@ workflows: cd tools/distribution && make venv/bin/python3 release.py "$GIT_TAG" --only-cocoapods + - build-router-start: + title: Start new CI jobs for running 'update_upstream_sdks'. + inputs: + - access_token: "$BITRISE_PERSONAL_ACCESS_TOKEN" + - workflows: |- + update_upstream_sdks + - environment_key_list: |- + DD_RELEASE_GIT_TAG + DD_RELEASE_DRY_RUN update_upstream_sdks: before_run: diff --git a/tools/distribution/update_upstream_sdks.py b/tools/distribution/update_upstream_sdks.py index 62fe2f9893..7c1bf757e8 100755 --- a/tools/distribution/update_upstream_sdks.py +++ b/tools/distribution/update_upstream_sdks.py @@ -100,7 +100,7 @@ def update_flutter_sdk(ios_sdk_git_tag: str, dry_run: bool): "--dry-run", action='store_true', help="Run as usual, but skip pushing to git remote (and creating PR).", - default=os.environ.get('DD_DRY_RUN') == '1' + default=os.environ.get('DD_RELEASE_DRY_RUN') == '1' ) args = parser.parse_args() @@ -111,7 +111,7 @@ def update_flutter_sdk(ios_sdk_git_tag: str, dry_run: bool): 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_DRY_RUN = {os.environ.get("DD_DRY_RUN")}') + 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' From 814b8d869c7a3000c6a7b90807d536ddb25d0990 Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Mon, 7 Feb 2022 13:48:07 +0100 Subject: [PATCH 012/104] RUMM-1964 Run `flutter upgrade` before `flutter pub get` to ensure that the version of Flutter in `dd-sdk-ios` CI env is equal or ahead of the version in `dd-sdk-flutter`. This is to let Flutter's example and integration tests project resolve its dependencies. --- tools/distribution/update_upstream_sdks.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tools/distribution/update_upstream_sdks.py b/tools/distribution/update_upstream_sdks.py index 7c1bf757e8..7b434a86c3 100755 --- a/tools/distribution/update_upstream_sdks.py +++ b/tools/distribution/update_upstream_sdks.py @@ -55,21 +55,26 @@ def update_flutter_sdk(ios_sdk_git_tag: str, dry_run: bool): 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}/example/ios') - os.chdir('example/ios') - + print(f'ℹ️️ Changing current directory to: {clone_dir}/{flutter_repo_name}/example') + os.chdir('example') shell(command='flutter pub get') + + print(f'ℹ️️ Changing current directory to: {clone_dir}/{flutter_repo_name}/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}/integration_test_app/ios') - os.chdir('integration_test_app/ios') - + print(f'ℹ️️ Changing current directory to: {clone_dir}/{flutter_repo_name}/integration_test_app') + os.chdir('integration_test_app') shell(command='flutter pub get') + + print(f'ℹ️️ Changing current directory to: {clone_dir}/{flutter_repo_name}/integration_test_app/ios') + os.chdir('ios') shell(command='pod update') # Commit changes: From b4ce921c235e6d343d0bd0e30da6dee7a62414c5 Mon Sep 17 00:00:00 2001 From: Austin Lai <76412946+alai97@users.noreply.github.com> Date: Mon, 7 Feb 2022 14:08:14 -0800 Subject: [PATCH 013/104] DOCS-3099 Adds a link to the source code for the `DDRUMMonitor` class + addresses copy nits. --- docs/rum_collection/advanced_configuration.md | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/docs/rum_collection/advanced_configuration.md b/docs/rum_collection/advanced_configuration.md index 3ea712e4e9..017e34adc8 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]. @@ -25,9 +25,6 @@ In addition to [tracking views automatically](#automatically-track-views), you c For example: -======= -Example: - {{< tabs >}} {{% tab "Swift" %}} ```swift @@ -64,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" %}} @@ -87,7 +86,9 @@ func onHeroImageLoaded() { {{% /tab %}} {{< /tabs >}} -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. +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 @@ -122,7 +123,7 @@ For 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 @@ -167,7 +168,7 @@ 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 @@ -186,13 +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][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. +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 @@ -361,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" %}} @@ -584,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" %}} @@ -606,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](#automatically-track-views)). +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 be not `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: @@ -731,7 +736,7 @@ DDConfigurationBuilder *builder = [DDConfiguration builderWithRumApplicationID:@ {{% /tab %}} {{< /tabs >}} -For more information, see the [URLSessionConfiguration.connectionProxyDictionary][8] documentation). +For more information, see the [URLSessionConfiguration.connectionProxyDictionary][8] documentation. ## Further Reading @@ -745,3 +750,4 @@ For more information, see the [URLSessionConfiguration.connectionProxyDictionary [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 From 67860d29d0b5d1a4312a2c759228d6f41ae8e544 Mon Sep 17 00:00:00 2001 From: Austin Lai <76412946+alai97@users.noreply.github.com> Date: Mon, 7 Feb 2022 16:40:11 -0800 Subject: [PATCH 014/104] Doc Review Co-authored-by: May Lee --- docs/rum_collection/advanced_configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rum_collection/advanced_configuration.md b/docs/rum_collection/advanced_configuration.md index 017e34adc8..afb7b4ffad 100644 --- a/docs/rum_collection/advanced_configuration.md +++ b/docs/rum_collection/advanced_configuration.md @@ -611,7 +611,7 @@ For example, to redact sensitive information in RUM Resource's `url`, implement {{% /tab %}} {{< /tabs >}} -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 be not `nil` (to drop views customize your implementation of `UIKitRUMViewsPredicate`. Read more in [tracking views automatically](#automatically-track-views)). +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: From 64845fa678f586cd07bd4c1946c756fb4daf741e Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Tue, 8 Feb 2022 12:57:42 +0100 Subject: [PATCH 015/104] RUMM-1964 CR feedback - rename the upstream repo branch --- tools/distribution/update_upstream_sdks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/distribution/update_upstream_sdks.py b/tools/distribution/update_upstream_sdks.py index 7b434a86c3..2199d2bde9 100755 --- a/tools/distribution/update_upstream_sdks.py +++ b/tools/distribution/update_upstream_sdks.py @@ -37,7 +37,7 @@ def update_flutter_sdk(ios_sdk_git_tag: str, dry_run: bool): repository_name=flutter_repo_name, temp_dir=clone_dir ) - repository.create_branch(f'update-dd-sdk-ios-to-{ios_sdk_git_tag}') + repository.create_branch(f'update/dd-sdk-ios-to-{ios_sdk_git_tag}') # Replace `dd-sdk-ios` version in `ios/datadog_sdk.podspec`: with open('ios/datadog_sdk.podspec', 'r+') as podspec: From 35c8a9fd16fa133c1bf221be4def820f212863c9 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 8 Feb 2022 14:38:16 +0100 Subject: [PATCH 016/104] RUMM-1956 Fix tracing indentation --- docs/trace_collection.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/trace_collection.md b/docs/trace_collection.md index 98296c5987..73c27a4f58 100644 --- a/docs/trace_collection.md +++ b/docs/trace_collection.md @@ -105,20 +105,20 @@ 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: +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. +- `.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`: +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. +- 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. - 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. +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. {{< tabs >}} {{% tab "Swift" %}} From 15cc663bb30bd9cf1af06899f802245b3485bd5f Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 8 Feb 2022 14:39:47 +0100 Subject: [PATCH 017/104] RUMM-1956 Fix RUM configuration snippets --- docs/rum_collection/_index.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/rum_collection/_index.md b/docs/rum_collection/_index.md index 5481703206..db89c94361 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,7 @@ 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]]; From db8ec6dd7fbf21ea3a93123d94fa14f2959b930d Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 8 Feb 2022 14:41:21 +0100 Subject: [PATCH 018/104] RUMM-1956 Document all regions in setup instructions --- docs/log_collection.md | 94 ++++++++++++++++++++++++++ docs/rum_collection/_index.md | 123 ++++++++++++++++++++++++++++++++++ docs/trace_collection.md | 90 +++++++++++++++++++++++++ 3 files changed, 307 insertions(+) diff --git a/docs/log_collection.md b/docs/log_collection.md index 859f73fc26..c94661cffb 100644 --- a/docs/log_collection.md +++ b/docs/log_collection.md @@ -107,6 +107,100 @@ DDConfigurationBuilder *builder = [DDConfiguration builderWithClientToken:@"}} {{< /site-region >}} +{{< 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 >}} + +{{< 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]]; + +[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: diff --git a/docs/rum_collection/_index.md b/docs/rum_collection/_index.md index db89c94361..2540d812e1 100644 --- a/docs/rum_collection/_index.md +++ b/docs/rum_collection/_index.md @@ -132,6 +132,129 @@ DDConfigurationBuilder *builder = [DDConfiguration builderWithRumApplicationID:@ {{< /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]]; + +[DDDatadog initializeWithAppContext:[DDAppContext new] + trackingConsent:trackingConsent + configuration:[builder build]]; +``` +{{% /tab %}} +{{< /tabs >}} +{{< /site-region >}} + The RUM SDK automatically tracks user sessions depending on options provided at the SDK initialization. To add GDPR compliance for your EU users and other [initialization parameters][9] to the SDK configuration, see the [Set tracking consent documentation][8]. ### Initialize RUM Monitor and `DDURLSessionDelegate` diff --git a/docs/trace_collection.md b/docs/trace_collection.md index 73c27a4f58..b911fa7fc0 100644 --- a/docs/trace_collection.md +++ b/docs/trace_collection.md @@ -105,6 +105,96 @@ DDConfigurationBuilder *builder = [DDConfiguration builderWithClientToken:@"}} {{< /site-region >}} +{{< 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 >}} + +{{< 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]]; + +[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: From deb2ddd9730b2be37782c72890ff1b7d43846a90 Mon Sep 17 00:00:00 2001 From: Mert Buran Date: Tue, 8 Feb 2022 15:03:43 +0100 Subject: [PATCH 019/104] RUMM-1931 PR comments addressed --- .../WebViewTrackingFixtureViewController.swift | 17 +++++++++++------ .../WKUserContentController+Datadog.swift | 2 +- .../WKUserContentController+DatadogTests.swift | 4 +--- 3 files changed, 13 insertions(+), 10 deletions(-) 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/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift b/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift index 336eee974d..7b270b1841 100644 --- a/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift +++ b/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift @@ -30,7 +30,7 @@ public extension WKUserContentController { /// 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. + /// - Note: This method **must** be called when the webview can be deinitialized. func stopTrackingDatadogEvents() { removeScriptMessageHandler(forName: DatadogMessageHandler.name) diff --git a/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift b/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift index cabbc9bbc3..62d1eb953b 100644 --- a/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift @@ -24,9 +24,7 @@ final class DDUserContentController: WKUserContentController { } final class MockMessageHandler: NSObject, WKScriptMessageHandler { - func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { - return - } + func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { } } final class MockScriptMessage: WKScriptMessage { From b6e503a2d3282c05f67297b55fdcdda61c44cbd1 Mon Sep 17 00:00:00 2001 From: Austin Lai <76412946+alai97@users.noreply.github.com> Date: Tue, 8 Feb 2022 09:15:08 -0800 Subject: [PATCH 020/104] Update docs/rum_collection/advanced_configuration.md Co-authored-by: Maciek Grzybowski --- docs/rum_collection/advanced_configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rum_collection/advanced_configuration.md b/docs/rum_collection/advanced_configuration.md index afb7b4ffad..3813840b9a 100644 --- a/docs/rum_collection/advanced_configuration.md +++ b/docs/rum_collection/advanced_configuration.md @@ -611,7 +611,7 @@ For example, to redact sensitive information in RUM Resource's `url`, implement {{% /tab %}} {{< /tabs >}} -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)). +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: From e6eb02d0e3e2748b2c39b38f5b0b9a9d933d996d Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 9 Feb 2022 10:55:22 +0100 Subject: [PATCH 021/104] RUMM-1956 Apply suggestions from doc review Co-authored-by: Austin Lai <76412946+alai97@users.noreply.github.com> --- docs/trace_collection.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/trace_collection.md b/docs/trace_collection.md index b911fa7fc0..de91a5f30b 100644 --- a/docs/trace_collection.md +++ b/docs/trace_collection.md @@ -195,18 +195,22 @@ 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: +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: logs, traces, and RUM events are not sent 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. 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. +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 sends all current and future data to Datadog. +- If changed to `.notGranted`, the SDK wipes all current data and does not collect future data. 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. From c24cd75d77f3c32d2d303c0e1b748f363ea7e6b5 Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Wed, 9 Feb 2022 12:00:51 +0100 Subject: [PATCH 022/104] RUMS-481 Add integration tests for using DD session delegate through composition and inheritance --- .../URLSession/URLSessionScenarios.swift | 71 ++++++++++++++++--- .../DDURLSessionDelegate.swift | 2 +- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift b/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift index 17f457017f..1a3a180351 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 = .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/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) From 4141a5a0eee21f631582ed932b532a0fdc58d109 Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Wed, 9 Feb 2022 12:28:54 +0100 Subject: [PATCH 023/104] RUMS-481 Add troubleshooting guide to explain advanced use of Datadog URL session delegate --- docs/rum_collection/troubleshooting.md | 52 +++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/docs/rum_collection/troubleshooting.md b/docs/rum_collection/troubleshooting.md index 200d049706..fcd8f7db76 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 `super` implementation from your overrided 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 our `__URLSessionDelegateProviding` protocol to keep 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]: https://docs.datadoghq.com/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 From 2b709d4013aad73b2a88e8af290f17fa37894577 Mon Sep 17 00:00:00 2001 From: Ignacio Bonafonte Date: Wed, 9 Feb 2022 15:05:39 +0100 Subject: [PATCH 024/104] Update to version 1.1.1 of testing framework --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ee9c436942..4c750b6d47 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ 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 From b2e7e0bfd3321374b1658bcf91906e69bf2f0ec6 Mon Sep 17 00:00:00 2001 From: Mert Buran Date: Wed, 9 Feb 2022 17:35:58 +0100 Subject: [PATCH 025/104] RUMM-1806 Custom Logs/RUM endpoints are read from xcconfig --- Datadog/Example/AppConfiguration.swift | 9 +++++++++ Datadog/Example/Environment.swift | 13 +++++++++++++ Datadog/TargetSupport/Example/Info.plist | 4 ++++ 3 files changed, 26 insertions(+) diff --git a/Datadog/Example/AppConfiguration.swift b/Datadog/Example/AppConfiguration.swift index 4947e4aed7..8f08b5ff4e 100644 --- a/Datadog/Example/AppConfiguration.swift +++ b/Datadog/Example/AppConfiguration.swift @@ -41,6 +41,15 @@ struct ExampleAppConfiguration: AppConfiguration { .set(batchSize: .small) .set(uploadFrequency: .frequent) + if let customLogsURL = Environment.readCustomLogsURL(), + let constructedURL = URL(string: customLogsURL) { + _ = configuration.set(customLogsEndpoint: constructedURL) + } + if let customRUMURL = Environment.readCustomRUMURL(), + let constructedURL = URL(string: customRUMURL) { + _ = configuration.set(customRUMEndpoint: constructedURL) + } + #if DD_SDK_ENABLE_INTERNAL_MONITORING _ = configuration .enableInternalMonitoring(clientToken: Environment.readClientToken()) diff --git a/Datadog/Example/Environment.swift b/Datadog/Example/Environment.swift index 4deeba034b..17b07c0edd 100644 --- a/Datadog/Example/Environment.swift +++ b/Datadog/Example/Environment.swift @@ -47,6 +47,9 @@ internal struct Environment { struct InfoPlistKey { static let clientToken = "DatadogClientToken" static let rumApplicationID = "RUMApplicationID" + + static let customLogsURL = "CustomLogsURL" + static let customRUMURL = "CustomRUMURL" } // MARK: - Launch Arguments @@ -106,4 +109,14 @@ internal struct Environment { } return rumApplicationID } + + static func readCustomLogsURL() -> String? { + let customLogsURL = Bundle.main.infoDictionary![InfoPlistKey.customLogsURL] as? String + return customLogsURL?.isEmpty == true ? nil : customLogsURL + } + + static func readCustomRUMURL() -> String? { + let customRUMURL = Bundle.main.infoDictionary![InfoPlistKey.customRUMURL] as? String + return customRUMURL?.isEmpty == true ? nil : customRUMURL + } } diff --git a/Datadog/TargetSupport/Example/Info.plist b/Datadog/TargetSupport/Example/Info.plist index 7429cd7f40..edb5305ba8 100644 --- a/Datadog/TargetSupport/Example/Info.plist +++ b/Datadog/TargetSupport/Example/Info.plist @@ -2,6 +2,10 @@ + CustomLogsURL + https://$(CUSTOM_LOGS_URL) + CustomRUMURL + https://$(CUSTOM_RUM_URL) CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable From 8fe996f7b13f00f1818dadab727de04e73fcdea1 Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Thu, 10 Feb 2022 09:46:55 +0100 Subject: [PATCH 026/104] Apply suggestions from code review RUMS-481 CR feedback - doc review Co-authored-by: Ursula Chen <58821586+urseberry@users.noreply.github.com> --- docs/rum_collection/troubleshooting.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rum_collection/troubleshooting.md b/docs/rum_collection/troubleshooting.md index fcd8f7db76..1d1348545d 100644 --- a/docs/rum_collection/troubleshooting.md +++ b/docs/rum_collection/troubleshooting.md @@ -33,7 +33,7 @@ If all goes well you should see output similar to this saying that a batch of RU 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 `super` implementation from your overrided methods. For example: +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?) { @@ -43,7 +43,7 @@ class YourCustomDelegateURLSessionDelegate: DDURLSessionDelegate { } ``` -When using _composition_, leverage our `__URLSessionDelegateProviding` protocol to keep internal instance of `DDURLSessionDelegate` and forward calls to `ddURLSessionDelegate`. For example: +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 From 31f5d70655c64a53d2584028d9adc97db69af260 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Thu, 10 Feb 2022 13:38:42 +0100 Subject: [PATCH 027/104] Fix test flakiness --- .../TrackingConsent/TrackingConsentScenarioTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 { From 20d4a52774af7d115eafd49c3eb7bc567eeeb749 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Thu, 10 Feb 2022 14:10:55 +0100 Subject: [PATCH 028/104] RUMM-1935 Make `consolePrint` public --- Sources/Datadog/Utils/Globals.swift | 4 +--- .../Logging/LogOutputs/LogConsoleOutputTests.swift | 10 ++++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) 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/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 = "" From afd181771f08e810eea47217451557a83691ed35 Mon Sep 17 00:00:00 2001 From: Mert Buran Date: Thu, 10 Feb 2022 16:17:14 +0100 Subject: [PATCH 029/104] RUMM-1806 PR comments addressed --- Datadog/Example/AppConfiguration.swift | 13 +++++----- Datadog/Example/Environment.swift | 31 ++++++++++++++++++------ Datadog/TargetSupport/Example/Info.plist | 6 +++-- xcconfigs/Datadog.xcconfig | 4 +++ 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/Datadog/Example/AppConfiguration.swift b/Datadog/Example/AppConfiguration.swift index 8f08b5ff4e..36cf7645ee 100644 --- a/Datadog/Example/AppConfiguration.swift +++ b/Datadog/Example/AppConfiguration.swift @@ -41,13 +41,14 @@ struct ExampleAppConfiguration: AppConfiguration { .set(batchSize: .small) .set(uploadFrequency: .frequent) - if let customLogsURL = Environment.readCustomLogsURL(), - let constructedURL = URL(string: customLogsURL) { - _ = configuration.set(customLogsEndpoint: constructedURL) + if let customLogsURL = Environment.readCustomLogsURL() { + _ = configuration.set(customLogsEndpoint: customLogsURL) } - if let customRUMURL = Environment.readCustomRUMURL(), - let constructedURL = URL(string: customRUMURL) { - _ = configuration.set(customRUMEndpoint: constructedURL) + if let customTraceURL = Environment.readCustomTraceURL() { + _ = configuration.set(customTracesEndpoint: customTraceURL) + } + if let customRUMURL = Environment.readCustomRUMURL() { + _ = configuration.set(customRUMEndpoint: customRUMURL) } #if DD_SDK_ENABLE_INTERNAL_MONITORING diff --git a/Datadog/Example/Environment.swift b/Datadog/Example/Environment.swift index 17b07c0edd..652bfd8996 100644 --- a/Datadog/Example/Environment.swift +++ b/Datadog/Example/Environment.swift @@ -48,8 +48,9 @@ internal struct Environment { static let clientToken = "DatadogClientToken" static let rumApplicationID = "RUMApplicationID" - static let customLogsURL = "CustomLogsURL" - static let customRUMURL = "CustomRUMURL" + static let customLogsURL = "CustomLogsURL" + static let customTraceURL = "CustomTraceURL" + static let customRUMURL = "CustomRUMURL" } // MARK: - Launch Arguments @@ -110,13 +111,27 @@ internal struct Environment { return rumApplicationID } - static func readCustomLogsURL() -> String? { - let customLogsURL = Bundle.main.infoDictionary![InfoPlistKey.customLogsURL] as? String - return customLogsURL?.isEmpty == true ? nil : customLogsURL + 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() -> String? { - let customRUMURL = Bundle.main.infoDictionary![InfoPlistKey.customRUMURL] as? String - return customRUMURL?.isEmpty == true ? nil : customRUMURL + 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/TargetSupport/Example/Info.plist b/Datadog/TargetSupport/Example/Info.plist index edb5305ba8..c7fe99ec2e 100644 --- a/Datadog/TargetSupport/Example/Info.plist +++ b/Datadog/TargetSupport/Example/Info.plist @@ -3,9 +3,11 @@ CustomLogsURL - https://$(CUSTOM_LOGS_URL) + $(CUSTOM_LOGS_URL) + CustomTraceURL + $(CUSTOM_TRACE_URL) CustomRUMURL - https://$(CUSTOM_RUM_URL) + $(CUSTOM_RUM_URL) CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable 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" From 13afdc3da21366dda519f85aabd0e6638ab863ba Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 9 Feb 2022 15:45:59 +0100 Subject: [PATCH 030/104] RUMM-1945 Add Fastlane Plugin and GH Action to crash reporting doc --- docs/rum_collection/crash_reporting.md | 66 ++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/docs/rum_collection/crash_reporting.md b/docs/rum_collection/crash_reporting.md index daa600d2b8..706218243f 100644 --- a/docs/rum_collection/crash_reporting.md +++ b/docs/rum_collection/crash_reporting.md @@ -73,9 +73,60 @@ Datadog.initialize( Global.rum = RUMMonitor.initialize() ``` -### Symbolicate reports using Datadog CI +### Symbolicate reports -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. +If your iOS error is unsymbolicated, upload your dSYM file using one of the following tools 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. + +#### Fastlane Plugin + +Datadog plugin helps you uploading dSYM files to Datadog from your fastlane configuration. + +1. Add [`fastlane-plugin-datadog`][3] to your project +```sh +fastlane add_plugin datadog +``` + +2. Then configure fastlane to upload your symbols, e.g.: +```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 +``` +> See [`fastlane-plugin-datadog`][3] for more instructions. + +#### Github Action + +The [Datadog Upload dSYMs GitHub Action][4] let you upload your symbols during 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 +``` + +#### Datadog CI + +You can also use the command line tool [@datadog/datadog-ci][5] to upload your dSYM file: ```sh export DATADOG_API_KEY="" @@ -89,7 +140,7 @@ 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. -If your application has Bitcode enabled, download your app's dSYM files on [App Store Connect][7]. For more information, see [dSYMs commands][8]. +If your application has Bitcode enabled, download your app's dSYM files on [App Store Connect][6]. For more information, see [dSYMs commands][7]. ## Further Reading @@ -98,9 +149,8 @@ If your application has Bitcode enabled, download your app's dSYM files on [App [1]: https://app.datadoghq.com/rum/application/create [2]: https://docs.datadoghq.com/real_user_monitoring/ios -[3]: https://github.com/DataDog/dd-sdk-ios/releases -[4]: https://github.com/DataDog/datadog-ci +[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 From 3b63a64beac29837a0160e5b711679db52ae6626 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Thu, 10 Feb 2022 09:34:55 +0100 Subject: [PATCH 031/104] RUMM-1945 Update docs/rum_collection/crash_reporting.md Co-authored-by: Ursula Chen <58821586+urseberry@users.noreply.github.com> --- docs/rum_collection/crash_reporting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rum_collection/crash_reporting.md b/docs/rum_collection/crash_reporting.md index 706218243f..1b4b19c40d 100644 --- a/docs/rum_collection/crash_reporting.md +++ b/docs/rum_collection/crash_reporting.md @@ -79,7 +79,7 @@ If your iOS error is unsymbolicated, upload your dSYM file using one of the foll #### Fastlane Plugin -Datadog plugin helps you uploading dSYM files to Datadog from your fastlane configuration. +The Datadog plugin helps you upload dSYM files to Datadog from your fastlane configuration. 1. Add [`fastlane-plugin-datadog`][3] to your project ```sh From b2853df8ba0813efbf5b2a7dd04eb8c1d415622b Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Mon, 14 Feb 2022 11:27:07 +0100 Subject: [PATCH 032/104] RUMS-481 Fix `cannot infer contextual base in reference to member 'allCases'` for Xcode 12.x --- Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift b/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift index 1a3a180351..141177742d 100644 --- a/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift +++ b/Datadog/Example/Scenarios/URLSession/URLSessionScenarios.swift @@ -89,7 +89,7 @@ class URLSessionBaseScenario: NSObject { private var ddURLSessionDelegate: DDURLSessionDelegate? override init() { - instrumentationMethod = .allCases.randomElement()! + instrumentationMethod = InstrumentationMethod.allCases.randomElement()! lazyInitURLSession = .random() if ProcessInfo.processInfo.arguments.contains("IS_RUNNING_UI_TESTS") { From 6747a6cf9ff2f6b74dd5c33c5b28bbcac88477d1 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Mon, 14 Feb 2022 09:54:52 +0100 Subject: [PATCH 033/104] RUMM-1939 Document data storage regarding encryption --- docs/log_collection.md | 4 +++- docs/rum_collection/data_collected.md | 2 ++ docs/trace_collection.md | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/log_collection.md b/docs/log_collection.md index c94661cffb..30055b94b1 100644 --- a/docs/log_collection.md +++ b/docs/log_collection.md @@ -214,7 +214,9 @@ The SDK changes its behavior according to the new value. For example, if the cur - 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. - 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. +Before uploading to Datadog, data is stored in cleartext in the cache directory (`Library/Caches`) of your application sandbox. + +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. {{< tabs >}} {{% tab "Swift" %}} diff --git a/docs/rum_collection/data_collected.md b/docs/rum_collection/data_collected.md index 67b3ba8917..51844957ac 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -218,7 +218,9 @@ Network errors include information about failing HTTP requests. The following fa | `action.name` | string | Name of the user action. | | `action.target.name` | string | Element that the user interacted with. Only for automatically collected actions | +## Data Storage +Before uploading to Datadog, data is stored in cleartext in the cache directory (`Library/Caches`) of your application sandbox. ## Further Reading diff --git a/docs/trace_collection.md b/docs/trace_collection.md index de91a5f30b..a5c90ee316 100644 --- a/docs/trace_collection.md +++ b/docs/trace_collection.md @@ -212,6 +212,8 @@ For example, if the current tracking consent is `.pending`: - 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. +Before uploading to Datadog, data is stored in cleartext in the cache directory (`Library/Caches`) of your application sandbox. + 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. {{< tabs >}} From 5578086fe7e96165e606f8558878d76485232e42 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Mon, 14 Feb 2022 16:18:33 +0100 Subject: [PATCH 034/104] RUMM-1939 Apply doc suggestions --- docs/log_collection.md | 4 ++-- docs/rum_collection/data_collected.md | 2 +- docs/trace_collection.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/log_collection.md b/docs/log_collection.md index 30055b94b1..7e94885f3d 100644 --- a/docs/log_collection.md +++ b/docs/log_collection.md @@ -214,9 +214,9 @@ The SDK changes its behavior according to the new value. For example, if the cur - 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 uploading to Datadog, data is stored in cleartext in the cache directory (`Library/Caches`) of your application sandbox. +Before data is uploaded to Datadog, it is stored in cleartext in the cache directory (`Library/Caches`) of your application sandbox. -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. +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" %}} diff --git a/docs/rum_collection/data_collected.md b/docs/rum_collection/data_collected.md index 51844957ac..6f93269d79 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -220,7 +220,7 @@ Network errors include information about failing HTTP requests. The following fa ## Data Storage -Before uploading to Datadog, data is stored in cleartext in the cache directory (`Library/Caches`) of your application sandbox. +Before data is uploaded to Datadog, it is stored in cleartext in the cache directory (`Library/Caches`) of your application sandbox. ## Further Reading diff --git a/docs/trace_collection.md b/docs/trace_collection.md index a5c90ee316..3bd6b79684 100644 --- a/docs/trace_collection.md +++ b/docs/trace_collection.md @@ -212,9 +212,9 @@ For example, if the current tracking consent is `.pending`: - 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. -Before uploading to Datadog, data is stored in cleartext in the cache directory (`Library/Caches`) of your application sandbox. +Before data is uploaded to Datadog, it is stored in cleartext in the cache directory (`Library/Caches`) of your application sandbox. -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. +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" %}} From 0e24fb1c9562417a3ba0e3d5ab53683164064aa8 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 16 Feb 2022 11:46:58 +0100 Subject: [PATCH 035/104] RUMM-2013 Remove tabs in doc --- docs/log_collection.md | 130 +++++++-------- docs/trace_collection.md | 350 +++++++++++++++++++-------------------- 2 files changed, 240 insertions(+), 240 deletions(-) diff --git a/docs/log_collection.md b/docs/log_collection.md index 7e94885f3d..495af40cae 100644 --- a/docs/log_collection.md +++ b/docs/log_collection.md @@ -218,80 +218,80 @@ Before data is uploaded to Datadog, it is stored in cleartext in the cache direc 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 >}} +{{< 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 >}} +{{< 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 diff --git a/docs/trace_collection.md b/docs/trace_collection.md index 3bd6b79684..cada8f4c93 100644 --- a/docs/trace_collection.md +++ b/docs/trace_collection.md @@ -216,206 +216,206 @@ Before data is uploaded to Datadog, it is stored in cleartext in the cache direc 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 >}} +{{< 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 - [builder trackURLSessionWithFirstPartyHosts:[NSSet setWithArray:@[@"example.com", @"api.yourdomain.com"]]]; +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 >}} - [DDDatadog initializeWithAppContext:[DDAppContext new] - trackingConsent:trackingConsent - configuration:[builder build]]; +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. - NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] - delegate:[[DDNSURLSessionDelegate alloc] init] - delegateQueue:nil]; - ``` - {{% /tab %}} - {{< /tabs >}} +* 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() +) + +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 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`). - **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, but it is opt-in: if you do not specify `firstPartyHosts`, no swizzling is applied. ## Batch collection From 41dfdbf521488a0750c92eb27595652e5411d4cc Mon Sep 17 00:00:00 2001 From: Austin Lai <76412946+alai97@users.noreply.github.com> Date: Wed, 16 Feb 2022 13:03:24 -0800 Subject: [PATCH 036/104] Doc Review --- docs/trace_collection.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/trace_collection.md b/docs/trace_collection.md index cada8f4c93..54fd5a28a8 100644 --- a/docs/trace_collection.md +++ b/docs/trace_collection.md @@ -373,9 +373,9 @@ for (NSString *key in headersWriter.tracePropagationHTTPHeaders) { {{% /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. +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. -* 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: +* 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: {{< tabs >}} {{% tab "Swift" %}} @@ -413,9 +413,9 @@ NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConf {{% /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 From 5168e7df7baff6c383d9ff2f6f8617906cd8c0c6 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Fri, 18 Feb 2022 11:55:52 +0100 Subject: [PATCH 037/104] Fix integration test flakiness --- .../CrashReporting/CrashReportingWithLoggingScenarioTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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() } } From a4ecaecb2daf961fd8ea9dffdfa95c627ba001ef Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Fri, 18 Feb 2022 09:50:25 +0100 Subject: [PATCH 038/104] RUMM-1998 Add Unreleased section to CHANGELOG --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96adb783dd..aadf7836a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# Unreleased + +* [FEATURE] Web-view tracking. See [#729][] +* [BUGFIX] Strip query parameters from span resource. See [#728][] + # 1.9.0 / 01-26-2022 ### Changes @@ -317,6 +322,8 @@ [#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 [@00FA9A]: https://github.com/00FA9A [@Britton-Earnin]: https://github.com/Britton-Earnin [@Hengyu]: https://github.com/Hengyu From 05515de9620ffe09942c7fa9e64e2514a140a666 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Fri, 18 Feb 2022 09:53:58 +0100 Subject: [PATCH 039/104] RUMM-1998 Add CHANGELOG.md attribute --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes 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 From 27d89ea98570308b5842bfc7306418c07421c4a5 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Fri, 18 Feb 2022 10:11:28 +0100 Subject: [PATCH 040/104] RUMM-1998 Update PR template checklist --- .github/PULL_REQUEST_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) 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. From 75f6f9ac5af30792f6d80edc008027d3c83be478 Mon Sep 17 00:00:00 2001 From: Ignacio Bonafonte Date: Tue, 22 Feb 2022 09:08:14 +0100 Subject: [PATCH 041/104] Integration with CI Visibility tests RUM is now able to detect if its being run inside a test instrumented with CI Visibility and perform the following changes then: * Sets `session.type` to `ci_test` * Injects `ci_visibility.test_execution_id` to every event * Set `_dd.origin` to `ciapp-test` so that APM traces from RUM in CI Visibility mode can be distinguished. * Send a message to a Mach Port initialized in the CI Visibility framework (TestMachPort) to notify RUM is enabled * Creates a new Mach Port (RUMMachPort) that will receive a message when the test ends. RUM will flush the RUM events when the message is received. --- Datadog/Datadog.xcodeproj/project.pbxproj | 4 + Sources/Datadog/Core/Feature.swift | 8 +- .../Datadog/Core/FeaturesConfiguration.swift | 3 + .../Core/Persistence/DataOrchestrator.swift | 4 +- .../Core/Persistence/FilesOrchestrator.swift | 4 +- .../Writing/ArbitraryDataWriter.swift | 4 +- .../Writing/ConsentAwareDataWriter.swift | 4 +- .../Core/Persistence/Writing/Writer.swift | 2 - .../Core/Swizzling/MethodSwizzler.swift | 8 +- .../Core/Upload/DataUploadWorker.swift | 8 +- .../CrashReporting/CrashReporter.swift | 4 +- .../CrashReportingFeature.swift | 4 +- Sources/Datadog/Datadog.swift | 8 +- .../CITestIntegration.swift | 81 +++++++++++++++++++ .../CrashReportingWithRUMIntegration.swift | 29 +++++-- .../InternalMonitoringFeature.swift | 6 +- Sources/Datadog/Logging/LoggingFeature.swift | 6 +- .../Actions/UIKit/UIApplicationSwizzler.swift | 4 +- .../Instrumentation/RUMInstrumentation.swift | 4 +- .../UIKit/UIViewControllerSwizzler.swift | 4 +- Sources/Datadog/RUM/RUMFeature.swift | 6 +- .../RUMMonitor/Scopes/RUMResourceScope.swift | 29 ++++++- .../Scopes/RUMUserActionScope.swift | 15 +++- .../RUM/RUMMonitor/Scopes/RUMViewScope.swift | 74 +++++++++++++---- Sources/Datadog/RUMMonitor.swift | 5 +- Sources/Datadog/Tracer.swift | 1 + .../Tracing/Span/SpanEventBuilder.swift | 3 + .../Tracing/Span/SpanEventEncoder.swift | 6 ++ Sources/Datadog/Tracing/TracingFeature.swift | 6 +- .../URLSessionAutoInstrumentation.swift | 4 +- .../URLSessionSwizzler.swift | 4 +- 31 files changed, 254 insertions(+), 98 deletions(-) create mode 100644 Sources/Datadog/FeaturesIntegration/CITestIntegration.swift diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index 717a2aeac1..9925c37b7a 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -559,6 +559,7 @@ 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 */; }; @@ -1259,6 +1260,7 @@ 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 = ""; }; @@ -1978,6 +1980,7 @@ 6156CB9B24E18224008CB2B2 /* TracingWithRUMIntegration.swift */, 61FC5F4425CC23C9006BB4DE /* RUMWithCrashContextIntegration.swift */, E13A880B257922EC004FB174 /* EnvironmentSpanIntegration.swift */, + E11625D727B681D200E428C6 /* CITestIntegration.swift */, 9EB4B860274E79620041CD03 /* WebView */, 6112B11C25C84E7F00B37771 /* CrashReporting */, ); @@ -4131,6 +4134,7 @@ 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 */, 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..12a15ee5c5 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]? } @@ -151,6 +152,7 @@ extension FeaturesConfiguration { } let source = (configuration.additionalConfiguration[CrossPlatformAttributes.ddsource] as? String) ?? Datadog.Constants.ddsource + let origin = CITestIntegration.origin ?? source let sdkVersion = (configuration.additionalConfiguration[CrossPlatformAttributes.sdkVersion] as? String) ?? __sdkVersion let debugOverride = appContext.processInfo.arguments.contains(Datadog.LaunchArguments.Debug) @@ -171,6 +173,7 @@ extension FeaturesConfiguration { bundleType: appContext.bundleType ), source: source, + origin: 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/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/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/CrashReporting/CrashReporter.swift b/Sources/Datadog/CrashReporting/CrashReporter.swift index 2aa97200ed..6e9c93ed94 100644 --- a/Sources/Datadog/CrashReporting/CrashReporter.swift +++ b/Sources/Datadog/CrashReporting/CrashReporter.swift @@ -169,10 +169,8 @@ internal class CrashReporter { } } -#if DD_SDK_COMPILED_FOR_TESTING - func deinitialize() { + internal func deinitialize() { // Await asynchronous operations completion to safely sink all pending tasks. queue.sync {} } -#endif } diff --git a/Sources/Datadog/CrashReporting/CrashReportingFeature.swift b/Sources/Datadog/CrashReporting/CrashReportingFeature.swift index 6b8f3b5309..7122cba183 100644 --- a/Sources/Datadog/CrashReporting/CrashReportingFeature.swift +++ b/Sources/Datadog/CrashReporting/CrashReportingFeature.swift @@ -51,9 +51,7 @@ internal final class CrashReportingFeature { self.appStateListener = commonDependencies.appStateListener } -#if DD_SDK_COMPILED_FOR_TESTING - func deinitialize() { + internal func deinitialize() { CrashReportingFeature.instance = nil } -#endif } diff --git a/Sources/Datadog/Datadog.swift b/Sources/Datadog/Datadog.swift index 6174469eb1..9a1da7f4d2 100644 --- a/Sources/Datadog/Datadog.swift +++ b/Sources/Datadog/Datadog.swift @@ -338,13 +338,18 @@ public class Datadog { InternalMonitoringFeature.instance?.logsStorage.clearAllData() } -#if DD_SDK_COMPILED_FOR_TESTING /// Flushes all authorised data for each feature, tears down and deinitializes the SDK. /// - It flushes all data authorised for each feature by performing its arbitrary upload (without retrying). /// - It completes all pending asynchronous work in each feature. /// /// This is highly experimental API and only supported in tests. +#if DD_SDK_COMPILED_FOR_TESTING public static func flushAndDeinitialize() { + internalFlushAndDeinitialize() + } +#endif + + internal static func internalFlushAndDeinitialize() { assert(Datadog.instance != nil, "SDK must be first initialized.") // Tear down and deinitialize all features: @@ -370,7 +375,6 @@ public class Datadog { // Reset internal loggers: userLogger = createNoOpSDKUserLogger() } -#endif } /// Convenience typealias. diff --git a/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift b/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift new file mode 100644 index 0000000000..aa83497aae --- /dev/null +++ b/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift @@ -0,0 +1,81 @@ +/* + * 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 customTags: Int32 = 0x1111 + static let enableRUM: Int32 = 0x2222 + static let forceFlush: Int32 = 0x3333 +} + +internal enum CITestIntegration { + /// CI context to be attached to RUM events that identifies it was started by a CI test, + static var ciTestExecutionID: String? { + return ProcessInfo.processInfo.environment["CI_VISIBILITY_TEST_EXECUTION_ID"] + } + + /// Convinence function to check if RUM was started in a CIApp test + static func isEnabled() -> Bool { + return ciTestExecutionID != nil + } + + /// Origin value that must be set to Spans and headers to indicate that the trace was initiated by a CIApp test + static var origin: String? { + if isEnabled() { + return "ciapp-test" + } + return nil + } + + /// Entry point for running all the tasks needed for CIApp integration + static 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 static func notifyRUMSession() { + let timeout: CFTimeInterval = 1.0 + guard let remotePort = CFMessagePortCreateRemote(nil, "DatadogTestingPort" as CFString) else { + return + } + let status = CFMessagePortSendRequest( + remotePort, + DDCFMessageID.enableRUM, // Message ID for notifying the test that rum is enabled + nil, + timeout, + timeout, + nil, + nil + ) + if status == kCFMessagePortSuccess { + } else {} + } + + /// 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 static func startMessageListener() { + func attributeCallback(port: CFMessagePort?, msgid: Int32, data: CFData?, info: UnsafeMutableRawPointer?) -> Unmanaged? { + switch msgid { + case DDCFMessageID.forceFlush: + Datadog.internalFlushAndDeinitialize() + default: + break + } + return nil + } + + let port = CFMessagePortCreateLocal(nil, "DatadogRUMTestingPort" as CFString, attributeCallback, nil, nil) + if port == nil { + print("DatadogTestingPort CFMessagePortCreateLocal failed") + 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..cdeed2e20e 100644 --- a/Sources/Datadog/FeaturesIntegration/CrashReporting/CrashReportingWithRUMIntegration.swift +++ b/Sources/Datadog/FeaturesIntegration/CrashReporting/CrashReportingWithRUMIntegration.swift @@ -224,6 +224,13 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { errorAttributes[DDError.meta] = crashReport.meta errorAttributes[DDError.wasTruncated] = crashReport.wasTruncated + let ciTest: RUMErrorEvent.CiTest? = { + if let testID = CITestIntegration.ciTestExecutionID { + return RUMErrorEvent.CiTest(testExecutionId: testID) + } + return nil + }() + let event = RUMErrorEvent( dd: .init( browserSdkVersion: nil, @@ -231,7 +238,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { ), action: nil, application: .init(id: lastRUMView.application.id), - ciTest: nil, + ciTest: ciTest, connectivity: lastRUMView.connectivity, context: nil, date: crashDate.timeIntervalSince1970.toInt64Milliseconds, @@ -251,7 +258,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { session: .init( hasReplay: lastRUMView.session.hasReplay, id: lastRUMView.session.id, - type: .user + type: ciTest != nil ? .ciTest : .user ), source: .ios, synthetics: nil, @@ -279,7 +286,12 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { session: .init(plan: .plan1) ), application: original.application, - ciTest: nil, + ciTest: { + if let testID = CITestIntegration.ciTestExecutionID { + return RUMViewEvent.CiTest(testExecutionId: testID) + } + return nil + }(), connectivity: original.connectivity, context: original.context, date: crashDate.timeIntervalSince1970.toInt64Milliseconds - 1, // -1ms to put the crash after view in RUM session @@ -335,6 +347,13 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { ) -> RUMViewEvent { let viewUUID = rumConfiguration.uuidGenerator.generateUnique() + let ciTest: RUMViewEvent.CiTest? = { + if let testID = CITestIntegration.ciTestExecutionID { + return RUMViewEvent.CiTest(testExecutionId: testID) + } + return nil + }() + return RUMViewEvent( dd: .init( browserSdkVersion: nil, @@ -344,7 +363,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { application: .init( id: rumConfiguration.applicationID ), - ciTest: nil, + ciTest: ciTest, connectivity: RUMConnectivity( networkInfo: crashContext.lastNetworkConnectionInfo, carrierInfo: crashContext.lastCarrierInfo @@ -355,7 +374,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { session: .init( hasReplay: nil, id: sessionUUID.toRUMDataFormat, - type: .user + type: ciTest != nil ? .ciTest : .user ), source: .ios, synthetics: nil, diff --git a/Sources/Datadog/InternalMonitoring/InternalMonitoringFeature.swift b/Sources/Datadog/InternalMonitoring/InternalMonitoringFeature.swift index da58e7b919..cb104e4c01 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), .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/Logging/LoggingFeature.swift b/Sources/Datadog/Logging/LoggingFeature.swift index f32088083d..ba852f8777 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), .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/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/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/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..7a695a13ba 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), .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/RUMResourceScope.swift b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMResourceScope.swift index 25cc393749..b4e7f08e03 100644 --- a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMResourceScope.swift +++ b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMResourceScope.swift @@ -128,6 +128,13 @@ internal class RUMResourceScope: RUMScope { } let resourceType: RUMResourceType = resourceKindBasedOnRequest ?? command.kind + let ciTest: RUMResourceEvent.CiTest? = { + if let testID = CITestIntegration.ciTestExecutionID { + return RUMResourceEvent.CiTest(testExecutionId: testID) + } + return nil + }() + let eventData = RUMResourceEvent( dd: .init( browserSdkVersion: nil, @@ -139,7 +146,7 @@ internal class RUMResourceScope: RUMScope { .init(id: rumUUID.toRUMDataFormat) }, application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: resourceStartTime).timeIntervalSince1970.toInt64Milliseconds, @@ -190,7 +197,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: ciTest != nil ? .ciTest : .user + ), source: .ios, synthetics: nil, usr: dependencies.userInfoProvider.current, @@ -211,6 +222,12 @@ internal class RUMResourceScope: RUMScope { private func sendErrorEvent(on command: RUMStopResourceWithErrorCommand) -> Bool { attributes.merge(rumCommandAttributes: command.attributes) + let ciTest: RUMErrorEvent.CiTest? = { + if let testID = CITestIntegration.ciTestExecutionID { + return RUMErrorEvent.CiTest(testExecutionId: testID) + } + return nil + }() let eventData = RUMErrorEvent( dd: .init( @@ -221,7 +238,7 @@ internal class RUMResourceScope: RUMScope { .init(id: rumUUID.toRUMDataFormat) }, application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: command.time).timeIntervalSince1970.toInt64Milliseconds, @@ -243,7 +260,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: 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..ffc2332780 100644 --- a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMUserActionScope.swift +++ b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMUserActionScope.swift @@ -132,6 +132,13 @@ internal class RUMUserActionScope: RUMScope, RUMContextProvider { attributes.merge(rumCommandAttributes: commandAttributes) } + let ciTest: RUMActionEvent.CiTest? = { + if let testID = CITestIntegration.ciTestExecutionID { + return RUMActionEvent.CiTest(testExecutionId: testID) + } + return nil + }() + let eventData = RUMActionEvent( dd: .init( browserSdkVersion: nil, @@ -148,12 +155,16 @@ internal class RUMUserActionScope: RUMScope, RUMContextProvider { type: actionType.toRUMDataFormat ), application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: 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: 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..0acff4fee5 100644 --- a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift +++ b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift @@ -123,7 +123,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 +284,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 +303,13 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { // MARK: - Sending RUM Events private func sendApplicationStartAction() -> Bool { + let ciTest: RUMActionEvent.CiTest? = { + if let testID = CITestIntegration.ciTestExecutionID { + return RUMActionEvent.CiTest(testExecutionId: testID) + } + return nil + }() + let eventData = RUMActionEvent( dd: .init( browserSdkVersion: nil, @@ -319,12 +326,16 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { type: .applicationStart ), application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: 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: ciTest != nil ? .ciTest : .user + ), source: .ios, synthetics: nil, usr: dependencies.userInfoProvider.current, @@ -357,6 +368,13 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { let refreshRateInfo = vitalInfoSampler.refreshRate let isSlowRendered = refreshRateInfo.meanValue.flatMap { $0 < Constants.slowRenderingThresholdFPS } + let ciTest: RUMViewEvent.CiTest? = { + if let testID = CITestIntegration.ciTestExecutionID { + return RUMViewEvent.CiTest(testExecutionId: testID) + } + return nil + }() + let eventData = RUMViewEvent( dd: .init( browserSdkVersion: nil, @@ -364,12 +382,16 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { session: .init(plan: .plan1) ), application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: 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: ciTest != nil ? .ciTest : .user + ), source: .ios, synthetics: nil, usr: dependencies.userInfoProvider.current, @@ -424,6 +446,13 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { private func sendErrorEvent(on command: RUMAddCurrentViewErrorCommand) -> Bool { attributes.merge(rumCommandAttributes: command.attributes) + let ciTest: RUMErrorEvent.CiTest? = { + if let testID = CITestIntegration.ciTestExecutionID { + return RUMErrorEvent.CiTest(testExecutionId: testID) + } + return nil + }() + let eventData = RUMErrorEvent( dd: .init( browserSdkVersion: nil, @@ -433,7 +462,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { .init(id: rumUUID.toRUMDataFormat) }, application: .init(id: context.rumApplicationID), - ciTest: nil, + ciTest: ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: command.time).timeIntervalSince1970.toInt64Milliseconds, @@ -450,7 +479,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: ciTest != nil ? .ciTest : .user + ), source: .ios, synthetics: nil, usr: dependencies.userInfoProvider.current, @@ -476,20 +509,31 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { let taskDurationInNs = command.duration.toInt64Nanoseconds let isFrozenFrame = taskDurationInNs > Constants.frozenFrameThresholdInNs + let ciTest: RUMLongTaskEvent.CiTest? = { + if let testID = CITestIntegration.ciTestExecutionID { + return RUMLongTaskEvent.CiTest(testExecutionId: testID) + } + return nil + }() + 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: 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: 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..3307c46c43 100644 --- a/Sources/Datadog/RUMMonitor.swift +++ b/Sources/Datadog/RUMMonitor.swift @@ -221,7 +221,10 @@ public class RUMMonitor: DDRUMMonitor, RUMCommandSubscriber { if Datadog.debugRUM { self.enableRUMDebugging(true) } - } + + if CITestIntegration.isEnabled() { + CITestIntegration.startIntegration() } + } // MARK: - Public DDRUMMonitor conformance diff --git a/Sources/Datadog/Tracer.swift b/Sources/Datadog/Tracer.swift index 6b69fdc52a..edf7583c63 100644 --- a/Sources/Datadog/Tracer.swift +++ b/Sources/Datadog/Tracer.swift @@ -108,6 +108,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( 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..28b0d31d56 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), .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/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 From 2906cfc5742701e85894af655c6e000d05b90eea Mon Sep 17 00:00:00 2001 From: Ignacio Bonafonte Date: Tue, 22 Feb 2022 17:00:03 +0100 Subject: [PATCH 042/104] Change origin field to be optional, and handle the `ddEVPOriginHeader` value when setting instead of in initialisation. Fix some tests --- Sources/Datadog/Core/FeaturesConfiguration.swift | 4 ++-- .../InternalMonitoring/InternalMonitoringFeature.swift | 2 +- Sources/Datadog/Logging/LoggingFeature.swift | 2 +- Sources/Datadog/RUM/RUMFeature.swift | 2 +- Sources/Datadog/Tracing/TracingFeature.swift | 2 +- .../InternalMonitoring/InternalMonitoringFeatureTests.swift | 4 +++- Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift | 4 +++- Tests/DatadogTests/Datadog/Mocks/CoreMocks.swift | 2 ++ Tests/DatadogTests/Datadog/Mocks/TracingFeatureMocks.swift | 5 +++++ Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift | 4 +++- Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift | 4 +++- 11 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Sources/Datadog/Core/FeaturesConfiguration.swift b/Sources/Datadog/Core/FeaturesConfiguration.swift index 12a15ee5c5..22b6a1c375 100644 --- a/Sources/Datadog/Core/FeaturesConfiguration.swift +++ b/Sources/Datadog/Core/FeaturesConfiguration.swift @@ -19,7 +19,7 @@ internal struct FeaturesConfiguration { let environment: String let performance: PerformancePreset let source: String - let origin: String + let origin: String? let sdkVersion: String let proxyConfiguration: [AnyHashable: Any]? } @@ -152,7 +152,7 @@ extension FeaturesConfiguration { } let source = (configuration.additionalConfiguration[CrossPlatformAttributes.ddsource] as? String) ?? Datadog.Constants.ddsource - let origin = CITestIntegration.origin ?? source + let origin = CITestIntegration.origin let sdkVersion = (configuration.additionalConfiguration[CrossPlatformAttributes.sdkVersion] as? String) ?? __sdkVersion let debugOverride = appContext.processInfo.arguments.contains(Datadog.LaunchArguments.Debug) diff --git a/Sources/Datadog/InternalMonitoring/InternalMonitoringFeature.swift b/Sources/Datadog/InternalMonitoring/InternalMonitoringFeature.swift index cb104e4c01..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.origin), + .ddEVPOriginHeader(source: configuration.common.origin ?? configuration.common.source), .ddEVPOriginVersionHeader(sdkVersion: configuration.common.sdkVersion), .ddRequestIDHeader(), ], diff --git a/Sources/Datadog/Logging/LoggingFeature.swift b/Sources/Datadog/Logging/LoggingFeature.swift index ba852f8777..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.origin), + .ddEVPOriginHeader(source: configuration.common.origin ?? configuration.common.source), .ddEVPOriginVersionHeader(sdkVersion: configuration.common.sdkVersion), .ddRequestIDHeader(), ], diff --git a/Sources/Datadog/RUM/RUMFeature.swift b/Sources/Datadog/RUM/RUMFeature.swift index 7a695a13ba..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.origin), + .ddEVPOriginHeader(source: configuration.common.origin ?? configuration.common.source), .ddEVPOriginVersionHeader(sdkVersion: configuration.common.sdkVersion), .ddRequestIDHeader(), ], diff --git a/Sources/Datadog/Tracing/TracingFeature.swift b/Sources/Datadog/Tracing/TracingFeature.swift index 28b0d31d56..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.origin), + .ddEVPOriginHeader(source: configuration.common.origin ?? configuration.common.source), .ddEVPOriginVersionHeader(sdkVersion: configuration.common.sdkVersion), .ddRequestIDHeader(), ], diff --git a/Tests/DatadogTests/Datadog/InternalMonitoring/InternalMonitoringFeatureTests.swift b/Tests/DatadogTests/Datadog/InternalMonitoring/InternalMonitoringFeatureTests.swift index 745ab0f431..012d14dc25 100644 --- a/Tests/DatadogTests/Datadog/InternalMonitoring/InternalMonitoringFeatureTests.swift +++ b/Tests/DatadogTests/Datadog/InternalMonitoring/InternalMonitoringFeatureTests.swift @@ -28,6 +28,7 @@ class InternalMonitoringFeatureTests: XCTestCase { let randomApplicationName: String = .mockRandom() 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/Logging/LoggingFeatureTests.swift b/Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift index c2a667a83d..31e30d14d0 100644 --- a/Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift +++ b/Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift @@ -28,6 +28,7 @@ class LoggingFeatureTests: XCTestCase { let randomApplicationName: String = .mockRandom() 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..d6bfb6346c 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 ) 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/RUMFeatureTests.swift b/Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift index d145c656eb..e0bd18e56f 100644 --- a/Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift @@ -30,6 +30,7 @@ class RUMFeatureTests: XCTestCase { 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/Tracing/TracingFeatureTests.swift b/Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift index b2853bd49b..8001a44bfc 100644 --- a/Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift +++ b/Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift @@ -28,6 +28,7 @@ class TracingFeatureTests: XCTestCase { let randomApplicationName: String = .mockRandom() 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) } From ad51785d084c8ecc4ff70fd09c20d4efcbf615e6 Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Wed, 23 Feb 2022 10:50:13 +0100 Subject: [PATCH 043/104] Generate shared CI Test model in RUM events --- .../RUM/DataModels/RUMDataModels.swift | 70 ++++--------------- .../DatadogObjc/RUM/RUMDataModels+objc.swift | 30 ++++---- .../RUM/RUMSwiftTypeTransformer.swift | 6 +- 3 files changed, 35 insertions(+), 71 deletions(-) diff --git a/Sources/Datadog/RUM/DataModels/RUMDataModels.swift b/Sources/Datadog/RUM/DataModels/RUMDataModels.swift index fba88de49a..6bc4b9d32e 100644 --- a/Sources/Datadog/RUM/DataModels/RUMDataModels.swift +++ b/Sources/Datadog/RUM/DataModels/RUMDataModels.swift @@ -17,7 +17,7 @@ public struct RUMViewEvent: RUMDataModel { public let application: Application /// CI Visibility properties - public let ciTest: CiTest? + public let ciTest: RUMCITest? /// Device connectivity properties public let connectivity: RUMConnectivity? @@ -113,16 +113,6 @@ public struct RUMViewEvent: 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 @@ -408,7 +398,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? @@ -523,16 +513,6 @@ public struct RUMResourceEvent: 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" - } - } - /// Resource properties public struct Resource: Codable { /// Connect phase properties @@ -817,7 +797,7 @@ public struct RUMActionEvent: RUMDataModel { public let application: Application /// CI Visibility properties - public let ciTest: CiTest? + public let ciTest: RUMCITest? /// Device connectivity properties public let connectivity: RUMConnectivity? @@ -1009,16 +989,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 @@ -1110,7 +1080,7 @@ public struct RUMErrorEvent: RUMDataModel { public let application: Application /// CI Visibility properties - public let ciTest: CiTest? + public let ciTest: RUMCITest? /// Device connectivity properties public let connectivity: RUMConnectivity? @@ -1217,16 +1187,6 @@ public struct RUMErrorEvent: 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" - } - } - /// Error properties public struct Error: Codable { /// Whether the error has been handled manually in the source code or not @@ -1448,7 +1408,7 @@ public struct RUMLongTaskEvent: RUMDataModel { public let application: Application /// CI Visibility properties - public let ciTest: CiTest? + public let ciTest: RUMCITest? /// Device connectivity properties public let connectivity: RUMConnectivity? @@ -1555,16 +1515,6 @@ 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 @@ -1658,6 +1608,16 @@ public struct RUMLongTaskEvent: RUMDataModel { } } +/// 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 diff --git a/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift b/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift index 001b65d7db..b67b3fcce5 100644 --- a/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift +++ b/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift @@ -28,8 +28,8 @@ public class DDRUMViewEvent: NSObject { DDRUMViewEventApplication(root: root) } - @objc public var ciTest: DDRUMViewEventCiTest? { - root.swiftModel.ciTest != nil ? DDRUMViewEventCiTest(root: root) : nil + @objc public var ciTest: DDRUMViewEventRUMCITest? { + root.swiftModel.ciTest != nil ? DDRUMViewEventRUMCITest(root: root) : nil } @objc public var connectivity: DDRUMViewEventRUMConnectivity? { @@ -145,7 +145,7 @@ public class DDRUMViewEventApplication: NSObject { } @objc -public class DDRUMViewEventCiTest: NSObject { +public class DDRUMViewEventRUMCITest: NSObject { internal let root: DDRUMViewEvent internal init(root: DDRUMViewEvent) { @@ -692,8 +692,8 @@ public class DDRUMResourceEvent: NSObject { DDRUMResourceEventApplication(root: root) } - @objc public var ciTest: DDRUMResourceEventCiTest? { - root.swiftModel.ciTest != nil ? DDRUMResourceEventCiTest(root: root) : nil + @objc public var ciTest: DDRUMResourceEventRUMCITest? { + root.swiftModel.ciTest != nil ? DDRUMResourceEventRUMCITest(root: root) : nil } @objc public var connectivity: DDRUMResourceEventRUMConnectivity? { @@ -830,7 +830,7 @@ public class DDRUMResourceEventApplication: NSObject { } @objc -public class DDRUMResourceEventCiTest: NSObject { +public class DDRUMResourceEventRUMCITest: NSObject { internal let root: DDRUMResourceEvent internal init(root: DDRUMResourceEvent) { @@ -1458,8 +1458,8 @@ public class DDRUMActionEvent: NSObject { DDRUMActionEventApplication(root: root) } - @objc public var ciTest: DDRUMActionEventCiTest? { - root.swiftModel.ciTest != nil ? DDRUMActionEventCiTest(root: root) : nil + @objc public var ciTest: DDRUMActionEventRUMCITest? { + root.swiftModel.ciTest != nil ? DDRUMActionEventRUMCITest(root: root) : nil } @objc public var connectivity: DDRUMActionEventRUMConnectivity? { @@ -1713,7 +1713,7 @@ public class DDRUMActionEventApplication: NSObject { } @objc -public class DDRUMActionEventCiTest: NSObject { +public class DDRUMActionEventRUMCITest: NSObject { internal let root: DDRUMActionEvent internal init(root: DDRUMActionEvent) { @@ -2015,8 +2015,8 @@ public class DDRUMErrorEvent: NSObject { DDRUMErrorEventApplication(root: root) } - @objc public var ciTest: DDRUMErrorEventCiTest? { - root.swiftModel.ciTest != nil ? DDRUMErrorEventCiTest(root: root) : nil + @objc public var ciTest: DDRUMErrorEventRUMCITest? { + root.swiftModel.ciTest != nil ? DDRUMErrorEventRUMCITest(root: root) : nil } @objc public var connectivity: DDRUMErrorEventRUMConnectivity? { @@ -2145,7 +2145,7 @@ public class DDRUMErrorEventApplication: NSObject { } @objc -public class DDRUMErrorEventCiTest: NSObject { +public class DDRUMErrorEventRUMCITest: NSObject { internal let root: DDRUMErrorEvent internal init(root: DDRUMErrorEvent) { @@ -2726,8 +2726,8 @@ public class DDRUMLongTaskEvent: NSObject { DDRUMLongTaskEventApplication(root: root) } - @objc public var ciTest: DDRUMLongTaskEventCiTest? { - root.swiftModel.ciTest != nil ? DDRUMLongTaskEventCiTest(root: root) : nil + @objc public var ciTest: DDRUMLongTaskEventRUMCITest? { + root.swiftModel.ciTest != nil ? DDRUMLongTaskEventRUMCITest(root: root) : nil } @objc public var connectivity: DDRUMLongTaskEventRUMConnectivity? { @@ -2856,7 +2856,7 @@ public class DDRUMLongTaskEventApplication: NSObject { } @objc -public class DDRUMLongTaskEventCiTest: NSObject { +public class DDRUMLongTaskEventRUMCITest: NSObject { internal let root: DDRUMLongTaskEvent internal init(root: DDRUMLongTaskEvent) { 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 } From bbe0749d9d4305f2d02b81c1fc1edb1330640fce Mon Sep 17 00:00:00 2001 From: Ignacio Bonafonte Date: Wed, 23 Feb 2022 16:15:15 +0100 Subject: [PATCH 044/104] Add changes from code review: - Modify CITestIntegration to be object oriented - Change a messageID value to be a bit more descriptive - Fix some tests --- .../Datadog/Core/FeaturesConfiguration.swift | 3 +- .../CITestIntegration.swift | 37 +++++++-------- .../CrashReportingWithRUMIntegration.swift | 29 +++--------- .../Scopes/RUMApplicationScope.swift | 2 + .../RUMMonitor/Scopes/RUMResourceScope.swift | 21 ++------- .../Scopes/RUMUserActionScope.swift | 11 +---- .../RUM/RUMMonitor/Scopes/RUMViewScope.swift | 45 ++++--------------- Sources/Datadog/RUMMonitor.swift | 6 +-- .../Datadog/Mocks/RUMFeatureMocks.swift | 4 ++ 9 files changed, 49 insertions(+), 109 deletions(-) diff --git a/Sources/Datadog/Core/FeaturesConfiguration.swift b/Sources/Datadog/Core/FeaturesConfiguration.swift index 22b6a1c375..bb2efefb4a 100644 --- a/Sources/Datadog/Core/FeaturesConfiguration.swift +++ b/Sources/Datadog/Core/FeaturesConfiguration.swift @@ -152,7 +152,6 @@ extension FeaturesConfiguration { } let source = (configuration.additionalConfiguration[CrossPlatformAttributes.ddsource] as? String) ?? Datadog.Constants.ddsource - let origin = CITestIntegration.origin let sdkVersion = (configuration.additionalConfiguration[CrossPlatformAttributes.sdkVersion] as? String) ?? __sdkVersion let debugOverride = appContext.processInfo.arguments.contains(Datadog.LaunchArguments.Debug) @@ -173,7 +172,7 @@ extension FeaturesConfiguration { bundleType: appContext.bundleType ), source: source, - origin: origin, + origin: CITestIntegration.active?.origin, sdkVersion: sdkVersion, proxyConfiguration: configuration.proxyConfiguration ) diff --git a/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift b/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift index aa83497aae..53c0bee9c5 100644 --- a/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift +++ b/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift @@ -7,39 +7,40 @@ import Foundation private enum DDCFMessageID { - static let customTags: Int32 = 0x1111 + static let setCustomTags: Int32 = 0x1111 static let enableRUM: Int32 = 0x2222 static let forceFlush: Int32 = 0x3333 } -internal enum CITestIntegration { - /// CI context to be attached to RUM events that identifies it was started by a CI test, - static var ciTestExecutionID: String? { - return ProcessInfo.processInfo.environment["CI_VISIBILITY_TEST_EXECUTION_ID"] - } +internal class CITestIntegration { + /// Current and active integration with CIApp. + /// `nil` if the integration is not enabled. + static let active: CITestIntegration? = CITestIntegration() - /// Convinence function to check if RUM was started in a CIApp test - static func isEnabled() -> Bool { - return ciTestExecutionID != nil - } + /// CI context to be attached to RUM events that identifies that they were created in a CIApp test, + let ciTestExecutionID: String + /// RUMCITest model to be attached to events + let rumCITest: RUMCITest + /// Tag that must be added to spans and headers when running inside a CIApp test + let origin = "ciapp-test" - /// Origin value that must be set to Spans and headers to indicate that the trace was initiated by a CIApp test - static var origin: String? { - if isEnabled() { - return "ciapp-test" + private init?(processInfo: ProcessInfo = .processInfo) { + guard let testID = processInfo.environment["CI_VISIBILITY_TEST_EXECUTION_ID"] else { + return nil } - return nil + self.ciTestExecutionID = testID + self.rumCITest = RUMCITest(testExecutionId: ciTestExecutionID) } /// Entry point for running all the tasks needed for CIApp integration - static func startIntegration() { + 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 static func notifyRUMSession() { + private func notifyRUMSession() { let timeout: CFTimeInterval = 1.0 guard let remotePort = CFMessagePortCreateRemote(nil, "DatadogTestingPort" as CFString) else { return @@ -59,7 +60,7 @@ internal enum CITestIntegration { /// 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 static func startMessageListener() { + private func startMessageListener() { func attributeCallback(port: CFMessagePort?, msgid: Int32, data: CFData?, info: UnsafeMutableRawPointer?) -> Unmanaged? { switch msgid { case DDCFMessageID.forceFlush: diff --git a/Sources/Datadog/FeaturesIntegration/CrashReporting/CrashReportingWithRUMIntegration.swift b/Sources/Datadog/FeaturesIntegration/CrashReporting/CrashReportingWithRUMIntegration.swift index cdeed2e20e..0da340e949 100644 --- a/Sources/Datadog/FeaturesIntegration/CrashReporting/CrashReportingWithRUMIntegration.swift +++ b/Sources/Datadog/FeaturesIntegration/CrashReporting/CrashReportingWithRUMIntegration.swift @@ -224,13 +224,6 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { errorAttributes[DDError.meta] = crashReport.meta errorAttributes[DDError.wasTruncated] = crashReport.wasTruncated - let ciTest: RUMErrorEvent.CiTest? = { - if let testID = CITestIntegration.ciTestExecutionID { - return RUMErrorEvent.CiTest(testExecutionId: testID) - } - return nil - }() - let event = RUMErrorEvent( dd: .init( browserSdkVersion: nil, @@ -238,7 +231,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { ), action: nil, application: .init(id: lastRUMView.application.id), - ciTest: ciTest, + ciTest: lastRUMView.ciTest, connectivity: lastRUMView.connectivity, context: nil, date: crashDate.timeIntervalSince1970.toInt64Milliseconds, @@ -258,7 +251,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { session: .init( hasReplay: lastRUMView.session.hasReplay, id: lastRUMView.session.id, - type: ciTest != nil ? .ciTest : .user + type: lastRUMView.ciTest != nil ? .ciTest : .user ), source: .ios, synthetics: nil, @@ -286,12 +279,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { session: .init(plan: .plan1) ), application: original.application, - ciTest: { - if let testID = CITestIntegration.ciTestExecutionID { - return RUMViewEvent.CiTest(testExecutionId: testID) - } - return 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 @@ -347,13 +335,6 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { ) -> RUMViewEvent { let viewUUID = rumConfiguration.uuidGenerator.generateUnique() - let ciTest: RUMViewEvent.CiTest? = { - if let testID = CITestIntegration.ciTestExecutionID { - return RUMViewEvent.CiTest(testExecutionId: testID) - } - return nil - }() - return RUMViewEvent( dd: .init( browserSdkVersion: nil, @@ -363,7 +344,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { application: .init( id: rumConfiguration.applicationID ), - ciTest: ciTest, + ciTest: CITestIntegration.active?.rumCITest, connectivity: RUMConnectivity( networkInfo: crashContext.lastNetworkConnectionInfo, carrierInfo: crashContext.lastCarrierInfo @@ -374,7 +355,7 @@ internal struct CrashReportingWithRUMIntegration: CrashReportingIntegration { session: .init( hasReplay: nil, id: sessionUUID.toRUMDataFormat, - type: ciTest != nil ? .ciTest : .user + type: CITestIntegration.active != nil ? .ciTest : .user ), source: .ios, synthetics: nil, 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 b4e7f08e03..a71f53bfd2 100644 --- a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMResourceScope.swift +++ b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMResourceScope.swift @@ -128,13 +128,6 @@ internal class RUMResourceScope: RUMScope { } let resourceType: RUMResourceType = resourceKindBasedOnRequest ?? command.kind - let ciTest: RUMResourceEvent.CiTest? = { - if let testID = CITestIntegration.ciTestExecutionID { - return RUMResourceEvent.CiTest(testExecutionId: testID) - } - return nil - }() - let eventData = RUMResourceEvent( dd: .init( browserSdkVersion: nil, @@ -146,7 +139,7 @@ internal class RUMResourceScope: RUMScope { .init(id: rumUUID.toRUMDataFormat) }, application: .init(id: context.rumApplicationID), - ciTest: ciTest, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: resourceStartTime).timeIntervalSince1970.toInt64Milliseconds, @@ -200,7 +193,7 @@ internal class RUMResourceScope: RUMScope { session: .init( hasReplay: nil, id: context.sessionID.toRUMDataFormat, - type: ciTest != nil ? .ciTest : .user + type: dependencies.ciTest != nil ? .ciTest : .user ), source: .ios, synthetics: nil, @@ -222,12 +215,6 @@ internal class RUMResourceScope: RUMScope { private func sendErrorEvent(on command: RUMStopResourceWithErrorCommand) -> Bool { attributes.merge(rumCommandAttributes: command.attributes) - let ciTest: RUMErrorEvent.CiTest? = { - if let testID = CITestIntegration.ciTestExecutionID { - return RUMErrorEvent.CiTest(testExecutionId: testID) - } - return nil - }() let eventData = RUMErrorEvent( dd: .init( @@ -238,7 +225,7 @@ internal class RUMResourceScope: RUMScope { .init(id: rumUUID.toRUMDataFormat) }, application: .init(id: context.rumApplicationID), - ciTest: ciTest, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: command.time).timeIntervalSince1970.toInt64Milliseconds, @@ -263,7 +250,7 @@ internal class RUMResourceScope: RUMScope { session: .init( hasReplay: nil, id: context.sessionID.toRUMDataFormat, - type: ciTest != nil ? .ciTest : .user + type: dependencies.ciTest != nil ? .ciTest : .user ), source: .ios, synthetics: nil, diff --git a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMUserActionScope.swift b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMUserActionScope.swift index ffc2332780..733b3548bf 100644 --- a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMUserActionScope.swift +++ b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMUserActionScope.swift @@ -132,13 +132,6 @@ internal class RUMUserActionScope: RUMScope, RUMContextProvider { attributes.merge(rumCommandAttributes: commandAttributes) } - let ciTest: RUMActionEvent.CiTest? = { - if let testID = CITestIntegration.ciTestExecutionID { - return RUMActionEvent.CiTest(testExecutionId: testID) - } - return nil - }() - let eventData = RUMActionEvent( dd: .init( browserSdkVersion: nil, @@ -155,7 +148,7 @@ internal class RUMUserActionScope: RUMScope, RUMContextProvider { type: actionType.toRUMDataFormat ), application: .init(id: context.rumApplicationID), - ciTest: ciTest, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: actionStartTime).timeIntervalSince1970.toInt64Milliseconds, @@ -163,7 +156,7 @@ internal class RUMUserActionScope: RUMScope, RUMContextProvider { session: .init( hasReplay: nil, id: context.sessionID.toRUMDataFormat, - type: ciTest != nil ? .ciTest : .user + type: dependencies.ciTest != nil ? .ciTest : .user ), source: .ios, synthetics: nil, diff --git a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift index 0acff4fee5..d940607cd8 100644 --- a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift +++ b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift @@ -303,12 +303,6 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { // MARK: - Sending RUM Events private func sendApplicationStartAction() -> Bool { - let ciTest: RUMActionEvent.CiTest? = { - if let testID = CITestIntegration.ciTestExecutionID { - return RUMActionEvent.CiTest(testExecutionId: testID) - } - return nil - }() let eventData = RUMActionEvent( dd: .init( @@ -326,7 +320,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { type: .applicationStart ), application: .init(id: context.rumApplicationID), - ciTest: ciTest, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: viewStartTime).timeIntervalSince1970.toInt64Milliseconds, @@ -334,7 +328,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { session: .init( hasReplay: nil, id: context.sessionID.toRUMDataFormat, - type: ciTest != nil ? .ciTest : .user + type: dependencies.ciTest != nil ? .ciTest : .user ), source: .ios, synthetics: nil, @@ -368,13 +362,6 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { let refreshRateInfo = vitalInfoSampler.refreshRate let isSlowRendered = refreshRateInfo.meanValue.flatMap { $0 < Constants.slowRenderingThresholdFPS } - let ciTest: RUMViewEvent.CiTest? = { - if let testID = CITestIntegration.ciTestExecutionID { - return RUMViewEvent.CiTest(testExecutionId: testID) - } - return nil - }() - let eventData = RUMViewEvent( dd: .init( browserSdkVersion: nil, @@ -382,7 +369,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { session: .init(plan: .plan1) ), application: .init(id: context.rumApplicationID), - ciTest: ciTest, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: viewStartTime).timeIntervalSince1970.toInt64Milliseconds, @@ -390,7 +377,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { session: .init( hasReplay: nil, id: context.sessionID.toRUMDataFormat, - type: ciTest != nil ? .ciTest : .user + type: dependencies.ciTest != nil ? .ciTest : .user ), source: .ios, synthetics: nil, @@ -446,13 +433,6 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { private func sendErrorEvent(on command: RUMAddCurrentViewErrorCommand) -> Bool { attributes.merge(rumCommandAttributes: command.attributes) - let ciTest: RUMErrorEvent.CiTest? = { - if let testID = CITestIntegration.ciTestExecutionID { - return RUMErrorEvent.CiTest(testExecutionId: testID) - } - return nil - }() - let eventData = RUMErrorEvent( dd: .init( browserSdkVersion: nil, @@ -462,7 +442,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { .init(id: rumUUID.toRUMDataFormat) }, application: .init(id: context.rumApplicationID), - ciTest: ciTest, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: command.time).timeIntervalSince1970.toInt64Milliseconds, @@ -482,7 +462,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { session: .init( hasReplay: nil, id: context.sessionID.toRUMDataFormat, - type: ciTest != nil ? .ciTest : .user + type: dependencies.ciTest != nil ? .ciTest : .user ), source: .ios, synthetics: nil, @@ -508,14 +488,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { let taskDurationInNs = command.duration.toInt64Nanoseconds let isFrozenFrame = taskDurationInNs > Constants.frozenFrameThresholdInNs - - let ciTest: RUMLongTaskEvent.CiTest? = { - if let testID = CITestIntegration.ciTestExecutionID { - return RUMLongTaskEvent.CiTest(testExecutionId: testID) - } - return nil - }() - + let eventData = RUMLongTaskEvent( dd: .init( browserSdkVersion: nil, @@ -523,7 +496,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { ), action: context.activeUserActionID.flatMap { RUMLongTaskEvent.Action(id: $0.toRUMDataFormat) }, application: .init(id: context.rumApplicationID), - ciTest: ciTest, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: command.time - command.duration).timeIntervalSince1970.toInt64Milliseconds, @@ -532,7 +505,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { session: .init( hasReplay: nil, id: context.sessionID.toRUMDataFormat, - type: ciTest != nil ? .ciTest : .user + type: dependencies.ciTest != nil ? .ciTest : .user ), source: .ios, synthetics: nil, diff --git a/Sources/Datadog/RUMMonitor.swift b/Sources/Datadog/RUMMonitor.swift index 3307c46c43..18e51abf16 100644 --- a/Sources/Datadog/RUMMonitor.swift +++ b/Sources/Datadog/RUMMonitor.swift @@ -195,6 +195,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, @@ -222,9 +223,8 @@ public class RUMMonitor: DDRUMMonitor, RUMCommandSubscriber { self.enableRUMDebugging(true) } - if CITestIntegration.isEnabled() { - CITestIntegration.startIntegration() } - } + CITestIntegration.active?.startIntegration() + } // MARK: - Public DDRUMMonitor conformance diff --git a/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift b/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift index 084b579721..0b0ad553b0 100644 --- a/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift @@ -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(), From 098b48801837bfa94437eafb90f7bd3d20398864 Mon Sep 17 00:00:00 2001 From: Ignacio Bonafonte Date: Wed, 23 Feb 2022 16:38:21 +0100 Subject: [PATCH 045/104] Fix lint issues --- Sources/Datadog/RUM/RUMMonitor/Scopes/RUMResourceScope.swift | 2 +- Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMResourceScope.swift b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMResourceScope.swift index a71f53bfd2..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: dependencies.ciTest, + ciTest: dependencies.ciTest, connectivity: dependencies.connectivityInfoProvider.current, context: .init(contextInfo: attributes), date: dateCorrection.applying(to: resourceStartTime).timeIntervalSince1970.toInt64Milliseconds, diff --git a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift index d940607cd8..e104281dcc 100644 --- a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift +++ b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift @@ -303,7 +303,6 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { // MARK: - Sending RUM Events private func sendApplicationStartAction() -> Bool { - let eventData = RUMActionEvent( dd: .init( browserSdkVersion: nil, @@ -488,7 +487,6 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { let taskDurationInNs = command.duration.toInt64Nanoseconds let isFrozenFrame = taskDurationInNs > Constants.frozenFrameThresholdInNs - let eventData = RUMLongTaskEvent( dd: .init( browserSdkVersion: nil, From e598d324040d36fbbfef5e6853418fcbd055824a Mon Sep 17 00:00:00 2001 From: Ignacio Bonafonte Date: Wed, 23 Feb 2022 16:53:59 +0100 Subject: [PATCH 046/104] Fix compilation on a benchmark test --- .../DataStorage/TracingStorageBenchmarkTests.swift | 1 + 1 file changed, 1 insertion(+) 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( From 94445ea4601f256424f0670328939e09c0c2f6dc Mon Sep 17 00:00:00 2001 From: Xavier Gouchet Date: Fri, 25 Feb 2022 09:38:02 +0100 Subject: [PATCH 047/104] RUMM-1939 add link to Apple's sandbox documentation --- docs/log_collection.md | 5 +++-- docs/rum_collection/data_collected.md | 13 +++++++------ docs/trace_collection.md | 5 +++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/log_collection.md b/docs/log_collection.md index 495af40cae..4a8c825380 100644 --- a/docs/log_collection.md +++ b/docs/log_collection.md @@ -214,9 +214,9 @@ The SDK changes its behavior according to the new value. For example, if the cur - 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. +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. +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" %}} @@ -412,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/data_collected.md b/docs/rum_collection/data_collected.md index 6f93269d79..58a63e51ae 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -9,11 +9,11 @@ further_reading: 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. +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`). +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. +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. This page provides descriptions of each of the metrics and attributes collected. @@ -139,7 +139,7 @@ RUM action, error, resource and long task events contain information about the a | `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 | |----------------|--------|-----------------------------------------------------------------| @@ -187,7 +187,7 @@ Front-end errors are collected with Real User Monitoring (RUM). The error messag | `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: @@ -220,7 +220,7 @@ Network errors include information about failing HTTP requests. The following fa ## Data Storage -Before data is uploaded to Datadog, it is stored in cleartext in the cache directory (`Library/Caches`) of your application sandbox. +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 @@ -228,3 +228,4 @@ Before data is uploaded to Datadog, it is stored in cleartext in the cache direc [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/trace_collection.md b/docs/trace_collection.md index 54fd5a28a8..cfeff3bd53 100644 --- a/docs/trace_collection.md +++ b/docs/trace_collection.md @@ -205,14 +205,14 @@ Use one of the following values for `trackingConsent`: 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. +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 sends all current and future data to Datadog. - If changed to `.notGranted`, the SDK wipes all current data and does not collect future data. -Before data is uploaded to Datadog, it is stored in cleartext in the cache directory (`Library/Caches`) of your application sandbox. +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. @@ -438,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 From 08b7b9c90842247889f50e686db39919c10bbec0 Mon Sep 17 00:00:00 2001 From: Xavier Gouchet Date: Fri, 25 Feb 2022 14:33:07 +0100 Subject: [PATCH 048/104] RUMM-2010 Sanitize app name in User Agent --- .../Datadog/Core/Upload/RequestBuilder.swift | 10 +++++++++- .../Core/Upload/RequestBuilderTests.swift | 20 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) 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.. Date: Fri, 4 Mar 2022 13:35:37 +0100 Subject: [PATCH 049/104] Clean up some code Add a test to validate CITestIntegration is off by default --- Datadog/Datadog.xcodeproj/project.pbxproj | 4 ++++ .../CITestIntegration.swift | 18 +++++------------- .../CITestIntegrationTests.swift | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 Tests/DatadogTests/Datadog/FeaturesIntegration/CITestIntegrationTests.swift diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index 9925c37b7a..3abf3d580a 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -563,6 +563,7 @@ 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 */; }; @@ -1264,6 +1265,7 @@ 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 = ""; }; @@ -1991,6 +1993,7 @@ isa = PBXGroup; children = ( 61D980BB24E293F600E03345 /* RUMIntegrationsTests.swift */, + E143CCAE27D236F600F4018A /* CITestIntegrationTests.swift */, 61216279247D21FE00AC5D67 /* LoggingForTracingAdapterTests.swift */, 61FC5F4D25CC2920006BB4DE /* RUMWithCrashContextIntegrationTests.swift */, 6182374125D3DFB8006A375B /* CrashReporting */, @@ -4363,6 +4366,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 */, diff --git a/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift b/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift index 53c0bee9c5..7a362252e0 100644 --- a/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift +++ b/Sources/Datadog/FeaturesIntegration/CITestIntegration.swift @@ -16,10 +16,7 @@ internal class CITestIntegration { /// Current and active integration with CIApp. /// `nil` if the integration is not enabled. static let active: CITestIntegration? = CITestIntegration() - - /// CI context to be attached to RUM events that identifies that they were created in a CIApp test, - let ciTestExecutionID: String - /// RUMCITest model to be attached to events + /// 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" @@ -28,8 +25,7 @@ internal class CITestIntegration { guard let testID = processInfo.environment["CI_VISIBILITY_TEST_EXECUTION_ID"] else { return nil } - self.ciTestExecutionID = testID - self.rumCITest = RUMCITest(testExecutionId: ciTestExecutionID) + self.rumCITest = RUMCITest(testExecutionId: testID) } /// Entry point for running all the tasks needed for CIApp integration @@ -45,7 +41,7 @@ internal class CITestIntegration { guard let remotePort = CFMessagePortCreateRemote(nil, "DatadogTestingPort" as CFString) else { return } - let status = CFMessagePortSendRequest( + CFMessagePortSendRequest( remotePort, DDCFMessageID.enableRUM, // Message ID for notifying the test that rum is enabled nil, @@ -54,8 +50,6 @@ internal class CITestIntegration { nil, nil ) - if status == kCFMessagePortSuccess { - } else {} } /// Creates a CFMessagePort that is used by the CIApp framework to notify that a test is going to finish, so all @@ -64,16 +58,14 @@ internal class CITestIntegration { func attributeCallback(port: CFMessagePort?, msgid: Int32, data: CFData?, info: UnsafeMutableRawPointer?) -> Unmanaged? { switch msgid { case DDCFMessageID.forceFlush: - Datadog.internalFlushAndDeinitialize() + Datadog.internalFlushAndDeinitialize() default: break } return nil } - let port = CFMessagePortCreateLocal(nil, "DatadogRUMTestingPort" as CFString, attributeCallback, nil, nil) - if port == nil { - print("DatadogTestingPort CFMessagePortCreateLocal failed") + guard let port = CFMessagePortCreateLocal(nil, "DatadogRUMTestingPort" as CFString, attributeCallback, nil, nil) else { return } let runLoopSource = CFMessagePortCreateRunLoopSource(nil, port, 0) 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) + } +} From cad4ea7f3447be907dd89164a46e8204f10b83b6 Mon Sep 17 00:00:00 2001 From: Austin Lai Date: Mon, 7 Mar 2022 15:21:24 -0800 Subject: [PATCH 050/104] DOCS-2567 Updates iOS Crash Reporting and Error Tracking page with improved information architecture and copy. --- docs/rum_collection/crash_reporting.md | 112 +++++++++++++++++-------- 1 file changed, 77 insertions(+), 35 deletions(-) diff --git a/docs/rum_collection/crash_reporting.md b/docs/rum_collection/crash_reporting.md index 1b4b19c40d..fa88a3b1ed 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]. + +### Add Crash Reporting -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 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,32 +78,70 @@ Datadog.initialize( Global.rum = RUMMonitor.initialize() ``` -### Symbolicate reports +## Symbolicate crash reports -If your iOS error is unsymbolicated, upload your dSYM file using one of the following tools 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. +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. -#### Fastlane Plugin +### Find your dYSM file + +Every iOS application produces dYSM files for each application module. Each application version contains a set of dYSM files. -The Datadog plugin helps you upload dSYM files to Datadog from your fastlane configuration. +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** in release. | + +### Upload your dYSM file + +dYSM files minimize an application's binary size and enable faster download speed. 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: -1. Add [`fastlane-plugin-datadog`][3] to your project ```sh -fastlane add_plugin datadog -``` +export DATADOG_API_KEY="" -2. Then configure fastlane to upload your symbols, e.g.: -```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 +// if you have a zip file containing dSYM files +npx @datadog/datadog-ci dsyms upload appDsyms.zip + +// if you have a folder containing dSYM files +npx @datadog/datadog-ci dsyms upload /path/to/appDsyms/ ``` -> See [`fastlane-plugin-datadog`][3] for more instructions. -#### Github Action +**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. -The [Datadog Upload dSYMs GitHub Action][4] let you upload your symbols during your GitHub Action jobs: +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 @@ -124,24 +167,22 @@ jobs: path/to/zip/dsyms.zip ``` -#### Datadog CI - -You can also use the command line tool [@datadog/datadog-ci][5] to upload your dSYM file: +For more information, see [dSYMs commands][7]. -```sh -export DATADOG_API_KEY="" +## Verify crash reports -// if you have a zip file containing dSYMs -npx @datadog/datadog-ci dsyms upload appDsyms.zip - -// if you have a folder containing dSYMs -npx @datadog/datadog-ci dsyms upload /path/to/appDsyms/ -``` +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. -**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. +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][6]. For more information, see [dSYMs commands][7]. + ``` + 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 @@ -154,3 +195,4 @@ If your application has Bitcode enabled, download your app's dSYM files on [App [5]: https://www.npmjs.com/package/@datadog/datadog-ci [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 From 217c0c5debeb51642feea18fb15878483c982118 Mon Sep 17 00:00:00 2001 From: Austin Lai Date: Tue, 8 Mar 2022 18:31:34 -0800 Subject: [PATCH 051/104] DOCS-3179 Addresses copy nits in Data Collected doc page. --- docs/rum_collection/data_collected.md | 112 +++++++++++++------------- 1 file changed, 57 insertions(+), 55 deletions(-) diff --git a/docs/rum_collection/data_collected.md b/docs/rum_collection/data_collected.md index 6f93269d79..23f79a9c59 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -9,13 +9,26 @@ further_reading: 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. + +## Overview + +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. 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. -This page provides descriptions of each of the metrics and attributes collected. +| 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 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 | A resource 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 | An error represents an exception 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 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). | ### 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,22 +117,24 @@ 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` | 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 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. | @@ -143,7 +144,7 @@ RUM action, error, resource and long task events contain information about the a | 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,9 +216,9 @@ 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 From e338c3a4d7fa8addd96ed1b25e76a52a8322efff Mon Sep 17 00:00:00 2001 From: Austin Lai <76412946+alai97@users.noreply.github.com> Date: Wed, 9 Mar 2022 07:42:00 -0800 Subject: [PATCH 052/104] Doc Review Co-authored-by: Xavier F. Gouchet --- docs/rum_collection/data_collected.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rum_collection/data_collected.md b/docs/rum_collection/data_collected.md index 089fd2b13d..9cdd27604b 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -22,8 +22,8 @@ There are additional [metrics and attributes that are specific to a given event |------------|-----------|-------------------------------------| | 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 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 | A resource 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 | An error represents an exception emitted by the mobile application attached to the view it is generated in. | +| 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: From c6845b37679e02e3408be96859715026d5dbefdc Mon Sep 17 00:00:00 2001 From: Austin Lai <76412946+alai97@users.noreply.github.com> Date: Wed, 9 Mar 2022 17:18:07 -0800 Subject: [PATCH 053/104] Doc Review Co-authored-by: May Lee --- docs/rum_collection/data_collected.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/rum_collection/data_collected.md b/docs/rum_collection/data_collected.md index 9cdd27604b..4a7ba683c3 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -66,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 From 0c590c6548b308562a6da65903aac7ef79483fef Mon Sep 17 00:00:00 2001 From: Austin Lai <76412946+alai97@users.noreply.github.com> Date: Fri, 11 Mar 2022 15:26:15 -0800 Subject: [PATCH 054/104] SME Review Co-authored-by: Xavier F. Gouchet --- docs/rum_collection/data_collected.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rum_collection/data_collected.md b/docs/rum_collection/data_collected.md index 4a7ba683c3..f6c0a7b7de 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -20,7 +20,7 @@ There are additional [metrics and attributes that are specific to a given event | 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 will share the same `session.id` attribute. | +| 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. 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. | From 4ce1e74f9c39101c46d04e9dff8e3bfc0d2a89cb Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Tue, 15 Mar 2022 15:29:34 +0100 Subject: [PATCH 055/104] RUMM-2010 Fix User-Agent tests flakiness by providing sanitized input to the application name mock. --- .../InternalMonitoring/InternalMonitoringFeatureTests.swift | 2 +- Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift | 2 +- Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift | 2 +- Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/DatadogTests/Datadog/InternalMonitoring/InternalMonitoringFeatureTests.swift b/Tests/DatadogTests/Datadog/InternalMonitoring/InternalMonitoringFeatureTests.swift index 745ab0f431..ba83116f24 100644 --- a/Tests/DatadogTests/Datadog/InternalMonitoring/InternalMonitoringFeatureTests.swift +++ b/Tests/DatadogTests/Datadog/InternalMonitoring/InternalMonitoringFeatureTests.swift @@ -25,7 +25,7 @@ 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 randomSDKVersion: String = .mockRandom(among: .alphanumerics) diff --git a/Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift b/Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift index c2a667a83d..e6d475df59 100644 --- a/Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift +++ b/Tests/DatadogTests/Datadog/Logging/LoggingFeatureTests.swift @@ -25,7 +25,7 @@ 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 randomSDKVersion: String = .mockRandom(among: .alphanumerics) diff --git a/Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift b/Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift index d145c656eb..354133d589 100644 --- a/Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/RUMFeatureTests.swift @@ -25,7 +25,7 @@ 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) diff --git a/Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift b/Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift index b2853bd49b..4ed9ae0012 100644 --- a/Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift +++ b/Tests/DatadogTests/Datadog/Tracing/TracingFeatureTests.swift @@ -25,7 +25,7 @@ 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 randomSDKVersion: String = .mockRandom(among: .alphanumerics) From 5dd6dda01b035e767e309531a41140c2d2bcf7e6 Mon Sep 17 00:00:00 2001 From: Kari Halsted <12926135+kayayarai@users.noreply.github.com> Date: Tue, 15 Mar 2022 10:22:06 -0600 Subject: [PATCH 056/104] fix link reference syntax --- docs/rum_collection/data_collected.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rum_collection/data_collected.md b/docs/rum_collection/data_collected.md index f6c0a7b7de..07cae83bb7 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -5,7 +5,7 @@ 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" --- @@ -222,7 +222,7 @@ Network errors include information about failing HTTP requests. The following fa ## 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. +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 From f1a275ea52b398a4b6b90d863e65b921034923f2 Mon Sep 17 00:00:00 2001 From: Jeff Ward Date: Wed, 16 Mar 2022 11:50:46 -0400 Subject: [PATCH 057/104] Fix update_upstream script for new Flutter plugin location --- tools/distribution/update_upstream_sdks.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/distribution/update_upstream_sdks.py b/tools/distribution/update_upstream_sdks.py index 2199d2bde9..ff6a458970 100755 --- a/tools/distribution/update_upstream_sdks.py +++ b/tools/distribution/update_upstream_sdks.py @@ -38,9 +38,13 @@ def update_flutter_sdk(ios_sdk_git_tag: str, dry_run: bool): 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_sdk.podspec', 'r+') as 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): @@ -54,26 +58,27 @@ def update_flutter_sdk(ios_sdk_git_tag: str, dry_run: bool): 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}/example') + 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}/example/ios') + 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}/integration_test_app') + 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}/integration_test_app/ios') + print(f'ℹ️️ Changing current directory to: {clone_dir}/{flutter_repo_name}/{package_dir}/integration_test_app/ios') os.chdir('ios') shell(command='pod update') From a0add6af38e7662279ad6a2bc0eb103a77c46345 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 15 Mar 2022 18:51:35 +0100 Subject: [PATCH 058/104] RUMM-2020 Generate models from root schema file --- .../RUM/DataModels/RUMDataModels.swift | 1551 ++++---- .../DatadogObjc/RUM/RUMDataModels+objc.swift | 3368 +++++++++-------- tools/rum-models-generator/Package.swift | 4 +- .../Input/JSON/JSONSchema.swift | 94 +- .../Input/JSON/JSONSchemaReader.swift | 32 +- .../RUMModelsGenerator.swift | 50 +- .../Sources/rum-models-generator/main.swift | 10 +- ...-json-schema-to-json-type-transformer.json | 10 + .../main.json | 50 + .../schema-1.json | 17 + .../schema-2.json | 18 + ...th-additional-properties-with-no-type.json | 13 + ...hema-with-typed-additional-properties.json | 44 + .../Input/JSONSchemaReaderTests.swift | 78 +- ...JSONSchemaToJSONTypeTransformerTests.swift | 107 +- tools/rum-models-generator/run.sh | 4 +- 16 files changed, 2943 insertions(+), 2507 deletions(-) create mode 100644 tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer.json create mode 100644 tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer/main.json create mode 100644 tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer/schema-1.json create mode 100644 tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-json-schema-to-json-type-transformer/schema-2.json create mode 100644 tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-reading-schema-with-additional-properties-with-no-type.json create mode 100644 tools/rum-models-generator/Tests/rum-models-generator-coreTests/Fixtures/fixture-reading-schema-with-typed-additional-properties.json diff --git a/Sources/Datadog/RUM/DataModels/RUMDataModels.swift b/Sources/Datadog/RUM/DataModels/RUMDataModels.swift index 6bc4b9d32e..9f50c31fc3 100644 --- a/Sources/Datadog/RUM/DataModels/RUMDataModels.swift +++ b/Sources/Datadog/RUM/DataModels/RUMDataModels.swift @@ -8,11 +8,14 @@ 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 @@ -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,6 +103,105 @@ public struct RUMViewEvent: 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 @@ -167,221 +266,568 @@ public struct RUMViewEvent: RUMDataModel { /// View properties public struct View: Codable { - /// Properties of the actions of the view - public let action: Action - - /// Total number of cpu ticks during the view’s lifetime - public let cpuTicksCount: Double? + /// UUID of the view + public let id: String - /// Average number of cpu ticks per second during the view’s lifetime - public let cpuTicksPerSecond: Double? + /// Is the action starting in the foreground (focus in browser) + public let inForeground: Bool? - /// Properties of the crashes of the view - public let crash: Crash? + /// User defined name of the view + public var name: String? - /// Total layout shift score that occured on the view - public let cumulativeLayoutShift: Double? + /// URL that linked to the initial view of the page + public var referrer: 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]? + /// URL of the view + public var url: String - /// Duration in ns to the complete parsing and loading of the document and its sub resources - public let domComplete: 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 without its sub resources - public let domContentLoaded: Int64? +/// Schema of all properties of an Error event +public struct RUMErrorEvent: RUMDataModel { + /// Internal properties + public let dd: DD - /// Duration in ns to the end of the parsing of the document - public let domInteractive: Int64? + /// Action properties + public let action: Action? - /// Properties of the errors of the view - public let error: Error + /// Application properties + public let application: Application - /// Duration in ns to the first rendering - public let firstContentfulPaint: Int64? + /// CI Visibility properties + public let ciTest: RUMCITest? - /// Duration in ns of the first input event delay - public let firstInputDelay: Int64? + /// Device connectivity properties + public let connectivity: RUMConnectivity? - /// Duration in ns to the first input - public let firstInputTime: Int64? + /// User provided context + public internal(set) var context: RUMEventAttributes? - /// Properties of the frozen frames of the view - public let frozenFrame: FrozenFrame? + /// Start of the event in ms from epoch + public let date: Int64 - /// UUID of the view - public let id: String + /// Error properties + public var error: Error - /// List of the periods of time the user had the view in foreground (focused in the browser) - public let inForegroundPeriods: [InForegroundPeriods]? + /// The service name for this application + public let service: String? - /// Whether the View corresponding to this event is considered active - public let isActive: Bool? + /// Session properties + public let session: Session - /// Whether the View had a low average refresh rate - public let isSlowRendered: Bool? + /// The source of this event + public let source: Source? - /// Duration in ns to the largest contentful paint - public let largestContentfulPaint: Int64? + /// Synthetics properties + public let synthetics: Synthetics? - /// Duration in ns to the end of the load event handler execution - public let loadEvent: Int64? + /// RUM event type + public let type: String = "error" - /// Duration in ns to the view is considered loaded - public let loadingTime: Int64? + /// User properties + public internal(set) var usr: RUMUser? - /// Type of the loading of the view - public let loadingType: LoadingType? + /// View properties + public var view: View - /// Properties of the long tasks of the view - public let longTask: LongTask? + 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" + } - /// Average memory used during the view lifetime (in bytes) - public let memoryAverage: Double? + /// Internal properties + public struct DD: Codable { + /// Browser SDK version + public let browserSdkVersion: String? - /// Peak memory used during the view lifetime (in bytes) - public let memoryMax: Double? + /// Version of the RUM event format + public let formatVersion: Int64 = 2 - /// User defined name of the view - public var name: String? + /// Session-related internal properties + public let session: Session? - /// URL that linked to the initial view of the page - public var referrer: String? + enum CodingKeys: String, CodingKey { + case browserSdkVersion = "browser_sdk_version" + case formatVersion = "format_version" + case session = "session" + } - /// Average refresh rate during the view’s lifetime (in frames per second) - public let refreshRateAverage: Double? + /// Session-related internal properties + public struct Session: Codable { + /// Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan + public let plan: Plan - /// Minimum refresh rate during the view’s lifetime (in frames per second) - public let refreshRateMin: Double? + enum CodingKeys: String, CodingKey { + case plan = "plan" + } - /// Properties of the resources of the view - public let resource: Resource + /// Session plan: 1 is the 'lite' plan, 2 is the 'replay' plan + public enum Plan: Int, Codable { + case plan1 = 1 + case plan2 = 2 + } + } + } - /// Time spent on the view in ns - public let timeSpent: Int64 + /// 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 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 inForeground = "in_foreground" 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" } + } +} - /// Properties of the actions of the view - public struct Action: Codable { - /// Number of actions that occurred on the view - public let count: Int64 +/// Schema of all properties of a Long Task event +public struct RUMLongTaskEvent: RUMDataModel { + /// Internal properties + public let dd: DD - enum CodingKeys: String, CodingKey { - case count = "count" - } + /// 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 + + /// The source of this event + public let source: Source? + + /// Synthetics properties + public let synthetics: Synthetics? + + /// RUM event type + public let type: String = "long_task" + + /// 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 browserSdkVersion = "browser_sdk_version" + case formatVersion = "format_version" + case session = "session" } - /// Properties of the crashes of the view - public struct Crash: Codable { - /// Number of crashes 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 errors of the view - public struct Error: Codable { - /// Number of errors 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 frozen frames of the view - public struct FrozenFrame: Codable { - /// Number of frozen frames 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 foreground period of the view - public struct InForegroundPeriods: Codable { - /// Duration in ns of the view foreground period - public let duration: Int64 + /// Long Task properties + public struct LongTask: Codable { + /// Duration in ns of the long task + public let duration: Int64 - /// Duration in ns between start of the view and start of foreground period - public let start: Int64 + /// UUID of the long task + public let id: String? - enum CodingKeys: String, CodingKey { - case duration = "duration" - case start = "start" - } + /// 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" } + } - /// 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" + /// 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" } - /// 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 + /// 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 - enum CodingKeys: String, CodingKey { - case count = "count" - } - } + /// User defined name of the view + public var name: String? - /// Properties of the resources of the view - public struct Resource: Codable { - /// Number of resources that occurred on the view - public let count: Int64 + /// URL that linked to the initial view of the page + public var referrer: String? - enum CodingKeys: String, CodingKey { - case count = "count" - } + /// URL of the view + public var url: String + + enum CodingKeys: String, CodingKey { + case id = "id" + case name = "name" + case referrer = "referrer" + case url = "url" } } } @@ -785,14 +1231,11 @@ 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 @@ -821,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? @@ -831,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" @@ -851,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 @@ -859,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" } @@ -880,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 @@ -1043,329 +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: 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 - - /// Error properties - public var error: Error - - /// The service name for this application - public let service: String? - - /// Session properties - public let session: Session + /// Properties of the actions of the view + public let action: Action - /// The source of this event - public let source: Source? + /// Total number of cpu ticks during the view’s lifetime + public let cpuTicksCount: Double? - /// Synthetics properties - public let synthetics: Synthetics? + /// Average number of cpu ticks per second during the view’s lifetime + public let cpuTicksPerSecond: Double? - /// RUM event type - public let type: String = "error" + /// Properties of the crashes of the view + public let crash: Crash? - /// User properties - public internal(set) var usr: RUMUser? + /// Total layout shift score that occured on the view + public let cumulativeLayoutShift: Double? - /// View properties - public var view: View + /// 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 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" - } + /// Duration in ns to the complete parsing and loading of the document and its sub resources + public let domComplete: Int64? - /// Internal properties - public struct DD: Codable { - /// Browser SDK version - public let browserSdkVersion: String? + /// Duration in ns to the complete parsing and loading of the document without its sub resources + public let domContentLoaded: Int64? - /// Version of the RUM event format - public let formatVersion: Int64 = 2 + /// Duration in ns to the end of the parsing of the document + public let domInteractive: Int64? - /// Session-related internal properties - public let session: Session? + /// Properties of the errors of the view + public let error: Error - enum CodingKeys: String, CodingKey { - case browserSdkVersion = "browser_sdk_version" - case formatVersion = "format_version" - case session = "session" - } + /// Duration in ns to the first rendering + public let firstContentfulPaint: 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 + /// Duration in ns of the first input event delay + public let firstInputDelay: Int64? - enum CodingKeys: String, CodingKey { - case plan = "plan" - } + /// Duration in ns to the first input + public let firstInputTime: Int64? - /// 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 frozen frames of the view + public let frozenFrame: FrozenFrame? - /// Action properties - public struct Action: Codable { - /// UUID of the action + /// 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]? - /// Application properties - public struct Application: Codable { - /// UUID of the application - public let id: String + /// Whether the View corresponding to this event is considered active + public let isActive: Bool? - enum CodingKeys: String, CodingKey { - case id = "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" + } + + /// 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" + } } - /// 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 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" } } @@ -1374,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 @@ -1405,93 +1732,49 @@ public struct RUMLongTaskEvent: RUMDataModel { 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? + 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? + public let session: Session? - /// Synthetics properties - public let synthetics: Synthetics? - - /// 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" } } @@ -1515,73 +1798,13 @@ public struct RUMLongTaskEvent: RUMDataModel { } } - /// 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" } } @@ -1590,20 +1813,8 @@ 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" } } } @@ -1781,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/DatadogObjc/RUM/RUMDataModels+objc.swift b/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift index b67b3fcce5..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: DDRUMViewEventRUMCITest? { - root.swiftModel.ciTest != nil ? DDRUMViewEventRUMCITest(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 DDRUMViewEventRUMCITest: 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 DDRUMViewEventRUMCITest: 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 class DDRUMViewEventViewInForegroundPeriods: NSObject { - internal let swiftModel: RUMViewEvent.View.InForegroundPeriods - internal var root: DDRUMViewEventViewInForegroundPeriods { self } - internal init(swiftModel: RUMViewEvent.View.InForegroundPeriods) { - self.swiftModel = swiftModel + @objc public var interfaces: [Int] { + root.swiftModel.connectivity!.interfaces.map { DDRUMErrorEventRUMConnectivityInterfaces(swift: $0).rawValue } } - @objc public var duration: NSNumber { - root.swiftModel.duration as NSNumber + @objc public var status: DDRUMErrorEventRUMConnectivityStatus { + .init(swift: root.swiftModel.connectivity!.status) } +} - @objc public var start: NSNumber { - root.swiftModel.start as NSNumber +@objc +public class DDRUMErrorEventRUMConnectivityCellular: NSObject { + internal let root: DDRUMErrorEvent + + internal init(root: DDRUMErrorEvent) { + 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 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: DDRUMResourceEventRUMCITest? { - root.swiftModel.ciTest != nil ? DDRUMResourceEventRUMCITest(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 DDRUMResourceEventRUMCITest: 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 method: DDRUMResourceEventResourceRUMMethod { - .init(swift: root.swiftModel.resource.method) + @objc public var inForeground: NSNumber? { + root.swiftModel.view.inForeground as NSNumber? } - @objc public var provider: DDRUMResourceEventResourceProvider? { - root.swiftModel.resource.provider != nil ? DDRUMResourceEventResourceProvider(root: root) : nil + @objc public var name: String? { + set { root.swiftModel.view.name = newValue } + get { root.swiftModel.view.name } } - @objc public var redirect: DDRUMResourceEventResourceRedirect? { - root.swiftModel.resource.redirect != nil ? DDRUMResourceEventResourceRedirect(root: root) : nil + @objc public var referrer: String? { + set { root.swiftModel.view.referrer = newValue } + get { root.swiftModel.view.referrer } } - @objc public var size: NSNumber? { - root.swiftModel.resource.size as NSNumber? + @objc public var url: String { + set { root.swiftModel.view.url = newValue } + get { root.swiftModel.view.url } } +} - @objc public var ssl: DDRUMResourceEventResourceSSL? { - root.swiftModel.resource.ssl != nil ? DDRUMResourceEventResourceSSL(root: root) : nil +@objc +public class DDRUMLongTaskEvent: NSObject { + internal var swiftModel: RUMLongTaskEvent + internal var root: DDRUMLongTaskEvent { self } + + internal init(swiftModel: RUMLongTaskEvent) { + self.swiftModel = swiftModel } - @objc public var statusCode: NSNumber? { - root.swiftModel.resource.statusCode as NSNumber? + @objc public var dd: DDRUMLongTaskEventDD { + DDRUMLongTaskEventDD(root: root) } - @objc public var type: DDRUMResourceEventResourceResourceType { - .init(swift: root.swiftModel.resource.type) + @objc public var action: DDRUMLongTaskEventAction? { + root.swiftModel.action != nil ? DDRUMLongTaskEventAction(root: root) : nil } - @objc public var url: String { - set { root.swiftModel.resource.url = newValue } - get { root.swiftModel.resource.url } + @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 type: String { + root.swiftModel.type + } + + @objc public var usr: DDRUMLongTaskEventRUMUser? { + root.swiftModel.usr != nil ? DDRUMLongTaskEventRUMUser(root: root) : nil + } + + @objc public var view: DDRUMLongTaskEventView { + DDRUMLongTaskEventView(root: root) + } +} + +@objc +public class DDRUMLongTaskEventDD: NSObject { + internal let root: DDRUMLongTaskEvent + + internal init(root: DDRUMLongTaskEvent) { + 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: DDRUMLongTaskEventDDSession? { + root.swiftModel.dd.session != nil ? DDRUMLongTaskEventDDSession(root: root) : nil + } +} + +@objc +public class DDRUMLongTaskEventDDSession: NSObject { + internal let root: DDRUMLongTaskEvent + + internal init(root: DDRUMLongTaskEvent) { + self.root = root + } + + @objc public var plan: DDRUMLongTaskEventDDSessionPlan { + .init(swift: root.swiftModel.dd.session!.plan) + } +} + +@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 DDRUMLongTaskEventAction: NSObject { + internal let root: DDRUMLongTaskEvent + + internal init(root: DDRUMLongTaskEvent) { + self.root = root + } + + @objc public var id: String { + root.swiftModel.action!.id } } @objc -public class DDRUMResourceEventResourceConnect: 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.connect!.duration as NSNumber - } - - @objc public var start: NSNumber { - root.swiftModel.resource.connect!.start as NSNumber + @objc public var id: String { + root.swiftModel.application.id } } @objc -public class DDRUMResourceEventResourceDNS: 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.dns!.duration as NSNumber - } - - @objc public var start: NSNumber { - root.swiftModel.resource.dns!.start as NSNumber + @objc public var testExecutionId: String { + root.swiftModel.ciTest!.testExecutionId } } @objc -public class DDRUMResourceEventResourceDownload: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMLongTaskEventRUMConnectivity: 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 cellular: DDRUMLongTaskEventRUMConnectivityCellular? { + root.swiftModel.connectivity!.cellular != nil ? DDRUMLongTaskEventRUMConnectivityCellular(root: root) : nil } - @objc public var start: NSNumber { - root.swiftModel.resource.download!.start as NSNumber + @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 DDRUMResourceEventResourceFirstByte: 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 duration: NSNumber { - root.swiftModel.resource.firstByte!.duration as NSNumber + @objc public var carrierName: String? { + root.swiftModel.connectivity!.cellular!.carrierName } - @objc public var start: NSNumber { - root.swiftModel.resource.firstByte!.start as NSNumber + @objc public var technology: String? { + root.swiftModel.connectivity!.cellular!.technology } } @objc -public enum DDRUMResourceEventResourceRUMMethod: Int { - internal init(swift: RUMMethod?) { +public enum DDRUMLongTaskEventRUMConnectivityInterfaces: Int { + internal init(swift: RUMConnectivity.Interfaces) { 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 + 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: RUMMethod? { + internal var toSwift: RUMConnectivity.Interfaces { 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 + 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 post - case get - case head - case put - case delete - case patch -} - -@objc -public class DDRUMResourceEventResourceProvider: NSObject { - internal let root: DDRUMResourceEvent - - internal init(root: DDRUMResourceEvent) { - 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 type: DDRUMResourceEventResourceProviderProviderType { - .init(swift: root.swiftModel.resource.provider!.type) - } } @objc -public enum DDRUMResourceEventResourceProviderProviderType: Int { - internal init(swift: RUMResourceEvent.Resource.Provider.ProviderType?) { +public enum DDRUMLongTaskEventRUMConnectivityStatus: Int { + internal init(swift: RUMConnectivity.Status) { 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 .connected: self = .connected + case .notConnected: self = .notConnected + case .maybe: self = .maybe } } - internal var toSwift: RUMResourceEvent.Resource.Provider.ProviderType? { + internal var toSwift: RUMConnectivity.Status { 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 .connected: return .connected + case .notConnected: return .notConnected + case .maybe: return .maybe } } - 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 + 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 - } -} - -@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 - } + root.swiftModel.longTask.duration as NSNumber } - 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 id: String? { + root.swiftModel.longTask.id } - case document - case xhr - case beacon - case fetch - case css - case js - case image - case font - case media - case other - case native + @objc public var isFrozenFrame: NSNumber? { + root.swiftModel.longTask.isFrozenFrame as NSNumber? + } } @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 } @@ -1385,10 +1679,10 @@ public class DDRUMResourceEventSynthetics: NSObject { } @objc -public class DDRUMResourceEventRUMUser: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMLongTaskEventRUMUser: NSObject { + internal let root: DDRUMLongTaskEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMLongTaskEvent) { self.root = root } @@ -1410,10 +1704,10 @@ public class DDRUMResourceEventRUMUser: NSObject { } @objc -public class DDRUMResourceEventView: NSObject { - internal let root: DDRUMResourceEvent +public class DDRUMLongTaskEventView: NSObject { + internal let root: DDRUMLongTaskEvent - internal init(root: DDRUMResourceEvent) { + internal init(root: DDRUMLongTaskEvent) { self.root = root } @@ -1438,76 +1732,80 @@ public class DDRUMResourceEventView: NSObject { } @objc -public class DDRUMActionEvent: NSObject { - internal var swiftModel: RUMActionEvent - internal var root: DDRUMActionEvent { self } +public class DDRUMResourceEvent: NSObject { + internal var swiftModel: RUMResourceEvent + internal var root: DDRUMResourceEvent { self } - internal init(swiftModel: RUMActionEvent) { + internal init(swiftModel: RUMResourceEvent) { self.swiftModel = swiftModel } - @objc public var dd: DDRUMActionEventDD { - DDRUMActionEventDD(root: root) + @objc public var dd: DDRUMResourceEventDD { + DDRUMResourceEventDD(root: root) } - @objc public var action: DDRUMActionEventAction { - DDRUMActionEventAction(root: root) + @objc public var action: DDRUMResourceEventAction? { + root.swiftModel.action != nil ? DDRUMResourceEventAction(root: root) : nil } - @objc public var application: DDRUMActionEventApplication { - DDRUMActionEventApplication(root: root) + @objc public var application: DDRUMResourceEventApplication { + DDRUMResourceEventApplication(root: root) } - @objc public var ciTest: DDRUMActionEventRUMCITest? { - root.swiftModel.ciTest != nil ? DDRUMActionEventRUMCITest(root: root) : nil + @objc public var ciTest: DDRUMResourceEventRUMCITest? { + root.swiftModel.ciTest != nil ? DDRUMResourceEventRUMCITest(root: root) : nil } - @objc public var connectivity: DDRUMActionEventRUMConnectivity? { - root.swiftModel.connectivity != nil ? DDRUMActionEventRUMConnectivity(root: root) : nil + @objc public var connectivity: DDRUMResourceEventRUMConnectivity? { + root.swiftModel.connectivity != nil ? DDRUMResourceEventRUMConnectivity(root: root) : nil } - @objc public var context: DDRUMActionEventRUMEventAttributes? { - root.swiftModel.context != nil ? DDRUMActionEventRUMEventAttributes(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: DDRUMActionEventSession { - DDRUMActionEventSession(root: root) + @objc public var session: DDRUMResourceEventSession { + DDRUMResourceEventSession(root: root) } - @objc public var source: DDRUMActionEventSource { + @objc public var source: DDRUMResourceEventSource { .init(swift: root.swiftModel.source) } - @objc public var synthetics: DDRUMActionEventSynthetics? { - root.swiftModel.synthetics != nil ? DDRUMActionEventSynthetics(root: root) : nil + @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: DDRUMActionEventRUMUser? { - root.swiftModel.usr != nil ? DDRUMActionEventRUMUser(root: root) : nil + @objc public var usr: DDRUMResourceEventRUMUser? { + root.swiftModel.usr != nil ? DDRUMResourceEventRUMUser(root: root) : nil } - @objc public var view: DDRUMActionEventView { - DDRUMActionEventView(root: root) + @objc public var view: DDRUMResourceEventView { + DDRUMResourceEventView(root: root) } } @objc -public class DDRUMActionEventDD: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventDD: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } @@ -1519,191 +1817,70 @@ public class DDRUMActionEventDD: NSObject { root.swiftModel.dd.formatVersion as NSNumber } - @objc public var session: DDRUMActionEventDDSession? { - root.swiftModel.dd.session != nil ? DDRUMActionEventDDSession(root: root) : nil - } -} - -@objc -public class DDRUMActionEventDDSession: NSObject { - internal let root: DDRUMActionEvent - - internal init(root: DDRUMActionEvent) { - self.root = root - } - - @objc public var plan: DDRUMActionEventDDSessionPlan { - .init(swift: root.swiftModel.dd.session!.plan) - } -} - -@objc -public enum DDRUMActionEventDDSessionPlan: Int { - internal init(swift: RUMActionEvent.DD.Session.Plan) { - switch swift { - case .plan1: self = .plan1 - case .plan2: self = .plan2 - } - } - - internal var toSwift: RUMActionEvent.DD.Session.Plan { - switch self { - case .plan1: return .plan1 - case .plan2: return .plan2 - } - } - - case plan1 - case plan2 -} - -@objc -public class DDRUMActionEventAction: NSObject { - internal let root: DDRUMActionEvent - - 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 var session: DDRUMResourceEventDDSession? { + root.swiftModel.dd.session != nil ? DDRUMResourceEventDDSession(root: root) : nil } -} - -@objc -public class DDRUMActionEventActionResource: NSObject { - internal let root: DDRUMActionEvent - internal init(root: DDRUMActionEvent) { - self.root = root + @objc public var spanId: String? { + root.swiftModel.dd.spanId } - @objc public var count: NSNumber { - root.swiftModel.action.resource!.count as NSNumber + @objc public var traceId: String? { + root.swiftModel.dd.traceId } } @objc -public class DDRUMActionEventActionTarget: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventDDSession: 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 plan: DDRUMResourceEventDDSessionPlan { + .init(swift: root.swiftModel.dd.session!.plan) } } @objc -public enum DDRUMActionEventActionActionType: Int { - internal init(swift: RUMActionEvent.Action.ActionType) { +public enum DDRUMResourceEventDDSessionPlan: Int { + internal init(swift: RUMResourceEvent.DD.Session.Plan) { 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 .plan1: self = .plan1 + case .plan2: self = .plan2 } } - internal var toSwift: RUMActionEvent.Action.ActionType { + internal var toSwift: RUMResourceEvent.DD.Session.Plan { 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 .plan1: return .plan1 + case .plan2: return .plan2 } } - case custom - case click - case tap - case scroll - case swipe - case applicationStart - case back + case plan1 + case plan2 } @objc -public class DDRUMActionEventApplication: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventAction: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { + self.root = root + } + + @objc public var id: String { + root.swiftModel.action!.id + } +} + +@objc +public class DDRUMResourceEventApplication: NSObject { + internal let root: DDRUMResourceEvent + + internal init(root: DDRUMResourceEvent) { self.root = root } @@ -1713,10 +1890,10 @@ public class DDRUMActionEventApplication: NSObject { } @objc -public class DDRUMActionEventRUMCITest: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventRUMCITest: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } @@ -1726,31 +1903,31 @@ public class DDRUMActionEventRUMCITest: NSObject { } @objc -public class DDRUMActionEventRUMConnectivity: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventRUMConnectivity: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } - @objc public var cellular: DDRUMActionEventRUMConnectivityCellular? { - root.swiftModel.connectivity!.cellular != nil ? DDRUMActionEventRUMConnectivityCellular(root: root) : nil + @objc public var cellular: DDRUMResourceEventRUMConnectivityCellular? { + root.swiftModel.connectivity!.cellular != nil ? DDRUMResourceEventRUMConnectivityCellular(root: root) : nil } @objc public var interfaces: [Int] { - root.swiftModel.connectivity!.interfaces.map { DDRUMActionEventRUMConnectivityInterfaces(swift: $0).rawValue } + root.swiftModel.connectivity!.interfaces.map { DDRUMResourceEventRUMConnectivityInterfaces(swift: $0).rawValue } } - @objc public var status: DDRUMActionEventRUMConnectivityStatus { + @objc public var status: DDRUMResourceEventRUMConnectivityStatus { .init(swift: root.swiftModel.connectivity!.status) } } @objc -public class DDRUMActionEventRUMConnectivityCellular: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventRUMConnectivityCellular: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } @@ -1764,7 +1941,7 @@ public class DDRUMActionEventRUMConnectivityCellular: NSObject { } @objc -public enum DDRUMActionEventRUMConnectivityInterfaces: Int { +public enum DDRUMResourceEventRUMConnectivityInterfaces: Int { internal init(swift: RUMConnectivity.Interfaces) { switch swift { case .bluetooth: self = .bluetooth @@ -1805,7 +1982,7 @@ public enum DDRUMActionEventRUMConnectivityInterfaces: Int { } @objc -public enum DDRUMActionEventRUMConnectivityStatus: Int { +public enum DDRUMResourceEventRUMConnectivityStatus: Int { internal init(swift: RUMConnectivity.Status) { switch swift { case .connected: self = .connected @@ -1828,10 +2005,10 @@ public enum DDRUMActionEventRUMConnectivityStatus: Int { } @objc -public class DDRUMActionEventRUMEventAttributes: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventRUMEventAttributes: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } @@ -1841,721 +2018,751 @@ public class DDRUMActionEventRUMEventAttributes: NSObject { } @objc -public class DDRUMActionEventSession: NSObject { - internal let root: DDRUMActionEvent +public class DDRUMResourceEventResource: NSObject { + internal let root: DDRUMResourceEvent - internal init(root: DDRUMActionEvent) { + internal init(root: DDRUMResourceEvent) { self.root = root } - @objc public var hasReplay: NSNumber? { - root.swiftModel.session.hasReplay as NSNumber? + @objc public var connect: DDRUMResourceEventResourceConnect? { + root.swiftModel.resource.connect != nil ? DDRUMResourceEventResourceConnect(root: root) : nil } - @objc public var id: String { - root.swiftModel.session.id + @objc public var dns: DDRUMResourceEventResourceDNS? { + root.swiftModel.resource.dns != nil ? DDRUMResourceEventResourceDNS(root: root) : nil } - @objc public var type: DDRUMActionEventSessionSessionType { - .init(swift: root.swiftModel.session.type) + @objc public var download: DDRUMResourceEventResourceDownload? { + root.swiftModel.resource.download != nil ? DDRUMResourceEventResourceDownload(root: root) : nil } -} -@objc -public enum DDRUMActionEventSessionSessionType: Int { - internal init(swift: RUMActionEvent.Session.SessionType) { - switch swift { - case .user: self = .user - case .synthetics: self = .synthetics - case .ciTest: self = .ciTest - } + @objc public var duration: NSNumber { + root.swiftModel.resource.duration as NSNumber } - internal var toSwift: RUMActionEvent.Session.SessionType { - switch self { - case .user: return .user - case .synthetics: return .synthetics - case .ciTest: return .ciTest - } + @objc public var firstByte: DDRUMResourceEventResourceFirstByte? { + root.swiftModel.resource.firstByte != nil ? DDRUMResourceEventResourceFirstByte(root: root) : nil } - case user - case synthetics - case ciTest + @objc public var id: String? { + root.swiftModel.resource.id + } + + @objc public var method: DDRUMResourceEventResourceRUMMethod { + .init(swift: root.swiftModel.resource.method) + } + + @objc public var provider: DDRUMResourceEventResourceProvider? { + root.swiftModel.resource.provider != nil ? DDRUMResourceEventResourceProvider(root: root) : nil + } + + @objc public var redirect: DDRUMResourceEventResourceRedirect? { + root.swiftModel.resource.redirect != nil ? DDRUMResourceEventResourceRedirect(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 statusCode: NSNumber? { + root.swiftModel.resource.statusCode as NSNumber? + } + + @objc public var type: DDRUMResourceEventResourceResourceType { + .init(swift: root.swiftModel.resource.type) + } + + @objc public var url: String { + set { root.swiftModel.resource.url = newValue } + get { root.swiftModel.resource.url } + } } @objc -public enum DDRUMActionEventSource: Int { - internal init(swift: RUMActionEvent.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 - } +public class DDRUMResourceEventResourceConnect: NSObject { + internal let root: DDRUMResourceEvent + + internal init(root: DDRUMResourceEvent) { + self.root = root } - internal var toSwift: RUMActionEvent.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 duration: NSNumber { + root.swiftModel.resource.connect!.duration as NSNumber } - case none - case android - case ios - case browser - case flutter - case reactNative + @objc public var start: NSNumber { + root.swiftModel.resource.connect!.start as NSNumber + } } @objc -public class DDRUMActionEventSynthetics: 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 injected: NSNumber? { - root.swiftModel.synthetics!.injected as NSNumber? + @objc public var duration: NSNumber { + root.swiftModel.resource.dns!.duration as NSNumber } - @objc public var resultId: String { - root.swiftModel.synthetics!.resultId + @objc public var start: NSNumber { + root.swiftModel.resource.dns!.start as NSNumber } +} - @objc public var testId: String { - root.swiftModel.synthetics!.testId +@objc +public class DDRUMResourceEventResourceDownload: NSObject { + internal let root: DDRUMResourceEvent + + internal init(root: DDRUMResourceEvent) { + 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 class DDRUMActionEventRUMUser: 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 email: String? { - root.swiftModel.usr!.email + @objc public var duration: NSNumber { + root.swiftModel.resource.firstByte!.duration as NSNumber } - @objc public var id: String? { - root.swiftModel.usr!.id + @objc public var start: NSNumber { + root.swiftModel.resource.firstByte!.start as NSNumber } +} - @objc public var name: String? { - root.swiftModel.usr!.name +@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 + } } - @objc public var usrInfo: [String: Any] { - root.swiftModel.usr!.usrInfo.castToObjectiveC() + 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 + } } + + case none + case post + case get + case head + case put + case delete + case patch } @objc -public class DDRUMActionEventView: 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.view.id - } - - @objc public var inForeground: NSNumber? { - root.swiftModel.view.inForeground as NSNumber? + @objc public var domain: String? { + root.swiftModel.resource.provider!.domain } @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 } + root.swiftModel.resource.provider!.name } - @objc public var url: String { - set { root.swiftModel.view.url = newValue } - get { root.swiftModel.view.url } + @objc public var type: DDRUMResourceEventResourceProviderProviderType { + .init(swift: root.swiftModel.resource.provider!.type) } } @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 +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 application: DDRUMErrorEventApplication { - DDRUMErrorEventApplication(root: root) + 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 ciTest: DDRUMErrorEventRUMCITest? { - root.swiftModel.ciTest != nil ? DDRUMErrorEventRUMCITest(root: root) : nil - } + 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 var connectivity: DDRUMErrorEventRUMConnectivity? { - root.swiftModel.connectivity != nil ? DDRUMErrorEventRUMConnectivity(root: root) : nil - } +@objc +public class DDRUMResourceEventResourceRedirect: NSObject { + internal let root: DDRUMResourceEvent - @objc public var context: DDRUMErrorEventRUMEventAttributes? { - root.swiftModel.context != nil ? DDRUMErrorEventRUMEventAttributes(root: root) : nil + internal init(root: DDRUMResourceEvent) { + self.root = root } - @objc public var date: NSNumber { - root.swiftModel.date as NSNumber + @objc public var duration: NSNumber { + root.swiftModel.resource.redirect!.duration as NSNumber } - @objc public var error: DDRUMErrorEventError { - DDRUMErrorEventError(root: root) + @objc public var start: NSNumber { + root.swiftModel.resource.redirect!.start as NSNumber } +} - @objc public var service: String? { - root.swiftModel.service - } +@objc +public class DDRUMResourceEventResourceSSL: NSObject { + internal let root: DDRUMResourceEvent - @objc public var session: DDRUMErrorEventSession { - DDRUMErrorEventSession(root: root) + internal init(root: DDRUMResourceEvent) { + self.root = root } - @objc public var source: DDRUMErrorEventSource { - .init(swift: root.swiftModel.source) + @objc public var duration: NSNumber { + root.swiftModel.resource.ssl!.duration as NSNumber } - @objc public var synthetics: DDRUMErrorEventSynthetics? { - root.swiftModel.synthetics != nil ? DDRUMErrorEventSynthetics(root: root) : nil + @objc public var start: NSNumber { + root.swiftModel.resource.ssl!.start as NSNumber } +} - @objc public var type: String { - root.swiftModel.type +@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 usr: DDRUMErrorEventRUMUser? { - root.swiftModel.usr != nil ? DDRUMErrorEventRUMUser(root: root) : nil + 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 view: DDRUMErrorEventView { - DDRUMErrorEventView(root: root) - } + 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 DDRUMErrorEventDD: NSObject { - internal let root: DDRUMErrorEvent +public class DDRUMResourceEventSession: 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 hasReplay: NSNumber? { + root.swiftModel.session.hasReplay as NSNumber? } - @objc public var formatVersion: NSNumber { - root.swiftModel.dd.formatVersion as NSNumber + @objc public var id: String { + root.swiftModel.session.id } - @objc public var session: DDRUMErrorEventDDSession? { - root.swiftModel.dd.session != nil ? DDRUMErrorEventDDSession(root: root) : nil + @objc public var type: DDRUMResourceEventSessionSessionType { + .init(swift: root.swiftModel.session.type) } } @objc -public class DDRUMErrorEventDDSession: NSObject { - internal let root: DDRUMErrorEvent - - internal init(root: DDRUMErrorEvent) { - self.root = root +public enum DDRUMResourceEventSessionSessionType: Int { + internal init(swift: RUMResourceEvent.Session.SessionType) { + switch swift { + case .user: self = .user + case .synthetics: self = .synthetics + case .ciTest: self = .ciTest + } } - @objc public var plan: DDRUMErrorEventDDSessionPlan { - .init(swift: root.swiftModel.dd.session!.plan) + internal var toSwift: RUMResourceEvent.Session.SessionType { + switch self { + case .user: return .user + case .synthetics: return .synthetics + case .ciTest: return .ciTest + } } + + case user + case synthetics + case ciTest } @objc -public enum DDRUMErrorEventDDSessionPlan: Int { - internal init(swift: RUMErrorEvent.DD.Session.Plan) { +public enum DDRUMResourceEventSource: Int { + internal init(swift: RUMResourceEvent.Source?) { switch swift { - case .plan1: self = .plan1 - case .plan2: self = .plan2 + 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: RUMErrorEvent.DD.Session.Plan { + internal var toSwift: RUMResourceEvent.Source? { switch self { - case .plan1: return .plan1 - case .plan2: return .plan2 + 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 plan1 - case plan2 + case none + case android + case ios + case browser + case flutter + case reactNative } @objc -public class DDRUMErrorEventAction: 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 id: String { - root.swiftModel.action!.id + @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 DDRUMErrorEventApplication: 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 id: String { - root.swiftModel.application.id + @objc public var email: String? { + root.swiftModel.usr!.email } -} -@objc -public class DDRUMErrorEventRUMCITest: NSObject { - internal let root: DDRUMErrorEvent + @objc public var id: String? { + root.swiftModel.usr!.id + } - internal init(root: DDRUMErrorEvent) { - self.root = root + @objc public var name: String? { + root.swiftModel.usr!.name } - @objc public var testExecutionId: String { - root.swiftModel.ciTest!.testExecutionId + @objc public var usrInfo: [String: Any] { + root.swiftModel.usr!.usrInfo.castToObjectiveC() } } @objc -public class DDRUMErrorEventRUMConnectivity: 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 cellular: DDRUMErrorEventRUMConnectivityCellular? { - root.swiftModel.connectivity!.cellular != nil ? DDRUMErrorEventRUMConnectivityCellular(root: root) : nil + @objc public var id: String { + root.swiftModel.view.id } - @objc public var interfaces: [Int] { - root.swiftModel.connectivity!.interfaces.map { DDRUMErrorEventRUMConnectivityInterfaces(swift: $0).rawValue } + @objc public var name: String? { + set { root.swiftModel.view.name = newValue } + get { root.swiftModel.view.name } } - @objc public var status: DDRUMErrorEventRUMConnectivityStatus { - .init(swift: root.swiftModel.connectivity!.status) + @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 DDRUMErrorEventRUMConnectivityCellular: 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 carrierName: String? { - root.swiftModel.connectivity!.cellular!.carrierName + @objc public var dd: DDRUMViewEventDD { + DDRUMViewEventDD(root: root) } - @objc public var technology: String? { - root.swiftModel.connectivity!.cellular!.technology + @objc public var application: DDRUMViewEventApplication { + DDRUMViewEventApplication(root: root) } -} -@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 ciTest: DDRUMViewEventRUMCITest? { + root.swiftModel.ciTest != nil ? DDRUMViewEventRUMCITest(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 connectivity: DDRUMViewEventRUMConnectivity? { + root.swiftModel.connectivity != nil ? DDRUMViewEventRUMConnectivity(root: root) : nil } - 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 context: DDRUMViewEventRUMEventAttributes? { + root.swiftModel.context != nil ? DDRUMViewEventRUMEventAttributes(root: root) : nil } - internal var toSwift: RUMConnectivity.Status { - switch self { - case .connected: return .connected - case .notConnected: return .notConnected - case .maybe: return .maybe - } + @objc public var date: NSNumber { + root.swiftModel.date as NSNumber } - case connected - case notConnected - case maybe -} - -@objc -public class DDRUMErrorEventRUMEventAttributes: NSObject { - internal let root: DDRUMErrorEvent - - internal init(root: DDRUMErrorEvent) { - self.root = root + @objc public var service: String? { + root.swiftModel.service } - @objc public var contextInfo: [String: Any] { - root.swiftModel.context!.contextInfo.castToObjectiveC() + @objc public var session: DDRUMViewEventSession { + DDRUMViewEventSession(root: root) } -} -@objc -public class DDRUMErrorEventError: NSObject { - internal let root: DDRUMErrorEvent + @objc public var source: DDRUMViewEventSource { + .init(swift: root.swiftModel.source) + } - internal init(root: DDRUMErrorEvent) { - self.root = root + @objc public var synthetics: DDRUMViewEventSynthetics? { + root.swiftModel.synthetics != nil ? DDRUMViewEventSynthetics(root: root) : nil } - @objc public var handling: DDRUMErrorEventErrorHandling { - .init(swift: root.swiftModel.error.handling) + @objc public var type: String { + root.swiftModel.type } - @objc public var handlingStack: String? { - root.swiftModel.error.handlingStack + @objc public var usr: DDRUMViewEventRUMUser? { + root.swiftModel.usr != nil ? DDRUMViewEventRUMUser(root: root) : nil } - @objc public var id: String? { - root.swiftModel.error.id + @objc public var view: DDRUMViewEventView { + DDRUMViewEventView(root: root) } +} - @objc public var isCrash: NSNumber? { - root.swiftModel.error.isCrash as NSNumber? +@objc +public class DDRUMViewEventDD: NSObject { + internal let root: DDRUMViewEvent + + internal init(root: DDRUMViewEvent) { + self.root = root } - @objc public var message: String { - set { root.swiftModel.error.message = newValue } - get { root.swiftModel.error.message } + @objc public var browserSdkVersion: String? { + root.swiftModel.dd.browserSdkVersion } - @objc public var resource: DDRUMErrorEventErrorResource? { - root.swiftModel.error.resource != nil ? DDRUMErrorEventErrorResource(root: root) : nil + @objc public var documentVersion: NSNumber { + root.swiftModel.dd.documentVersion as NSNumber } - @objc public var source: DDRUMErrorEventErrorSource { - .init(swift: root.swiftModel.error.source) + @objc public var formatVersion: NSNumber { + root.swiftModel.dd.formatVersion as NSNumber } - @objc public var sourceType: DDRUMErrorEventErrorSourceType { - .init(swift: root.swiftModel.error.sourceType) + @objc public var session: DDRUMViewEventDDSession? { + root.swiftModel.dd.session != nil ? DDRUMViewEventDDSession(root: root) : nil } +} - @objc public var stack: String? { - set { root.swiftModel.error.stack = newValue } - get { root.swiftModel.error.stack } +@objc +public class DDRUMViewEventDDSession: NSObject { + internal let root: DDRUMViewEvent + + 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?) { +public enum DDRUMViewEventDDSessionPlan: Int { + internal init(swift: RUMViewEvent.DD.Session.Plan) { switch swift { - case nil: self = .none - case .handled?: self = .handled - case .unhandled?: self = .unhandled + 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: DDRUMLongTaskEventRUMCITest? { - root.swiftModel.ciTest != nil ? DDRUMLongTaskEventRUMCITest(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 DDRUMLongTaskEventRUMCITest: 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/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/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 From d50d032f8e9dfe6aecf37ab7724f6d054d458ae2 Mon Sep 17 00:00:00 2001 From: Ignacio Bonafonte Date: Thu, 17 Mar 2022 11:38:49 +0100 Subject: [PATCH 059/104] Remove `EnvironmentSpanPropagation`, `TracingWithEnvironmentSpanIntegration`, and `LoggingWithEnvironmentSpanIntegration`, and related tests This code has no users anymore, once complete CI Visibility integration has been added. --- Datadog/Datadog.xcodeproj/project.pbxproj | 4 - .../EnvironmentSpanIntegration.swift | 49 ------------ Sources/Datadog/Logger.swift | 4 - Sources/Datadog/Tracer.swift | 6 +- Tests/DatadogTests/Datadog/LoggerTests.swift | 46 ----------- Tests/DatadogTests/Datadog/TracerTests.swift | 80 ------------------- 6 files changed, 2 insertions(+), 187 deletions(-) delete mode 100644 Sources/Datadog/FeaturesIntegration/EnvironmentSpanIntegration.swift diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index 3abf3d580a..e9f70c141f 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -562,7 +562,6 @@ 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 */; }; @@ -1264,7 +1263,6 @@ 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 = ""; }; @@ -1981,7 +1979,6 @@ 6105D19F2508F1600040DD22 /* LoggingWithActiveSpanIntegration.swift */, 6156CB9B24E18224008CB2B2 /* TracingWithRUMIntegration.swift */, 61FC5F4425CC23C9006BB4DE /* RUMWithCrashContextIntegration.swift */, - E13A880B257922EC004FB174 /* EnvironmentSpanIntegration.swift */, E11625D727B681D200E428C6 /* CITestIntegration.swift */, 9EB4B860274E79620041CD03 /* WebView */, 6112B11C25C84E7F00B37771 /* CrashReporting */, @@ -4288,7 +4285,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 */, 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/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/Tracer.swift b/Sources/Datadog/Tracer.swift index edf7583c63..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 @@ -189,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/Tests/DatadogTests/Datadog/LoggerTests.swift b/Tests/DatadogTests/Datadog/LoggerTests.swift index e1e20ef5ab..3fbaeea43e 100644 --- a/Tests/DatadogTests/Datadog/LoggerTests.swift +++ b/Tests/DatadogTests/Datadog/LoggerTests.swift @@ -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/TracerTests.swift b/Tests/DatadogTests/Datadog/TracerTests.swift index 6ed19ad0ee..a3b8f30089 100644 --- a/Tests/DatadogTests/Datadog/TracerTests.swift +++ b/Tests/DatadogTests/Datadog/TracerTests.swift @@ -1121,85 +1121,5 @@ class TracerTests: XCTestCase { Datadog.flushAndDeinitialize() } - - // MARK: - Environment Context - - func testSendingSpansWithNoDirectParentAndEnvironmentContext() 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 queue = DispatchQueue(label: "\(#function)-queue") - - func makeAPIRequest(completion: @escaping () -> 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 From 68804944b14956b4220cf119797761ccf1f49de7 Mon Sep 17 00:00:00 2001 From: Austin Lai Date: Thu, 17 Mar 2022 08:40:07 -0700 Subject: [PATCH 060/104] Specify Code Block Language --- docs/rum_collection/crash_reporting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rum_collection/crash_reporting.md b/docs/rum_collection/crash_reporting.md index fa88a3b1ed..caa5314bc1 100644 --- a/docs/rum_collection/crash_reporting.md +++ b/docs/rum_collection/crash_reporting.md @@ -176,7 +176,7 @@ To verify your iOS Crash Reporting and Error Tracking configuration, issue a cra 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: - ``` + ```swift func didTapButton() { fatalError(“Crash the app”) } From bc62ff618f75843438eeec153b45986953b6802c Mon Sep 17 00:00:00 2001 From: Austin Lai <76412946+alai97@users.noreply.github.com> Date: Thu, 17 Mar 2022 08:41:16 -0700 Subject: [PATCH 061/104] SME Review Co-authored-by: Maciek Grzybowski --- docs/rum_collection/crash_reporting.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/rum_collection/crash_reporting.md b/docs/rum_collection/crash_reporting.md index caa5314bc1..549a86e511 100644 --- a/docs/rum_collection/crash_reporting.md +++ b/docs/rum_collection/crash_reporting.md @@ -84,18 +84,18 @@ Crash reports are collected in a raw format and mostly contain memory addresses. ### Find your dYSM file -Every iOS application produces dYSM files for each application module. Each application version contains a set of dYSM files. +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** in release. | +| 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. | ### Upload your dYSM file -dYSM files minimize an application's binary size and enable faster download speed. 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. +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. From f662ae96e67f2faa015a69698aa4a7879c1df9d6 Mon Sep 17 00:00:00 2001 From: Austin Lai <76412946+alai97@users.noreply.github.com> Date: Mon, 21 Mar 2022 14:42:17 -0700 Subject: [PATCH 062/104] SME Review Co-authored-by: Xavier F. Gouchet --- docs/rum_collection/data_collected.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rum_collection/data_collected.md b/docs/rum_collection/data_collected.md index 07cae83bb7..1cafd72bba 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -21,7 +21,7 @@ There are additional [metrics and attributes that are specific to a given event | 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. 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`. | +| 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. | From 4ba142b06fc92aa5a63d8baa918c7e9714147d26 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 22 Mar 2022 14:00:05 +0100 Subject: [PATCH 063/104] Bumped version to 1.10.0-beta1 --- DatadogSDK.podspec | 2 +- DatadogSDKAlamofireExtension.podspec | 2 +- DatadogSDKCrashReporting.podspec | 4 ++-- DatadogSDKObjc.podspec | 4 ++-- Sources/Datadog/Versioning.swift | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/DatadogSDK.podspec b/DatadogSDK.podspec index 540e49cc71..3903903ee6 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" diff --git a/DatadogSDKAlamofireExtension.podspec b/DatadogSDKAlamofireExtension.podspec index 5bcd582e66..8fcbb6ac32 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" diff --git a/DatadogSDKCrashReporting.podspec b/DatadogSDKCrashReporting.podspec index 4018132b44..a9c4267349 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" @@ -21,6 +21,6 @@ Pod::Spec.new do |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/DatadogSDKObjc.podspec b/DatadogSDKObjc.podspec index 92f90781ac..9b010d292f 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" @@ -20,5 +20,5 @@ Pod::Spec.new do |s| 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/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" From 54444ea4346d6582ef517581a0b28422f54b8aad Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 22 Mar 2022 14:15:17 +0100 Subject: [PATCH 064/104] Expose web-view tracking --- .../WebView/WKUserContentController+Datadog.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift b/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift index 7b270b1841..e418e9186c 100644 --- a/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift +++ b/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift @@ -4,7 +4,6 @@ * Copyright 2019-2020 Datadog, Inc. */ -#if DD_SDK_ENABLE_EXPERIMENTAL_APIS import Foundation import WebKit @@ -146,4 +145,3 @@ internal class DatadogMessageHandler: NSObject, WKScriptMessageHandler { } } } -#endif From f39276da81cf65e1a9b0aedcf0badea224d00fa0 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 22 Mar 2022 16:23:27 +0100 Subject: [PATCH 065/104] Fix sdk version assertion --- .../Scenarios/Logging/LoggingCommonAsserts.swift | 2 +- .../Scenarios/RUM/RUMCommonAsserts.swift | 4 ++-- .../Scenarios/Tracing/TracingCommonAsserts.swift | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/DatadogIntegrationTests/Scenarios/Logging/LoggingCommonAsserts.swift b/Tests/DatadogIntegrationTests/Scenarios/Logging/LoggingCommonAsserts.swift index 2d83074d68..1f14b74f44 100644 --- a/Tests/DatadogIntegrationTests/Scenarios/Logging/LoggingCommonAsserts.swift +++ b/Tests/DatadogIntegrationTests/Scenarios/Logging/LoggingCommonAsserts.swift @@ -39,7 +39,7 @@ extension LoggingCommonAsserts { #"^User-Agent: Example/1.0 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..1dc0ca3c0d 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), """ @@ -39,7 +39,7 @@ extension RUMCommonAsserts { #"^User-Agent: Example/1.0 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..a832b51565 100644 --- a/Tests/DatadogIntegrationTests/Scenarios/Tracing/TracingCommonAsserts.swift +++ b/Tests/DatadogIntegrationTests/Scenarios/Tracing/TracingCommonAsserts.swift @@ -49,7 +49,7 @@ extension TracingCommonAsserts { #"^User-Agent: Example/1.0 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 From c03acd3684806acb00eda68e68e584fb16bc8e65 Mon Sep 17 00:00:00 2001 From: Austin Lai <76412946+alai97@users.noreply.github.com> Date: Tue, 22 Mar 2022 13:18:50 -0700 Subject: [PATCH 066/104] Bracket Nit --- docs/log_collection.md | 2 +- docs/rum_collection/data_collected.md | 2 +- docs/trace_collection.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/log_collection.md b/docs/log_collection.md index 4a8c825380..5d86491bdc 100644 --- a/docs/log_collection.md +++ b/docs/log_collection.md @@ -214,7 +214,7 @@ The SDK changes its behavior according to the new value. For example, if the cur - 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. +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. diff --git a/docs/rum_collection/data_collected.md b/docs/rum_collection/data_collected.md index 58a63e51ae..557e0770c6 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -220,7 +220,7 @@ Network errors include information about failing HTTP requests. The following fa ## 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. +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 diff --git a/docs/trace_collection.md b/docs/trace_collection.md index cfeff3bd53..9c239c6ebe 100644 --- a/docs/trace_collection.md +++ b/docs/trace_collection.md @@ -212,7 +212,7 @@ For example, if the current tracking consent is `.pending`: - 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. -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. +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. From 749b4d517cd217992dcbc6a810a0e1c7f23ba28d Mon Sep 17 00:00:00 2001 From: Austin Lai <76412946+alai97@users.noreply.github.com> Date: Tue, 22 Mar 2022 15:32:16 -0700 Subject: [PATCH 067/104] Update Session Attribute --- docs/rum_collection/data_collected.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rum_collection/data_collected.md b/docs/rum_collection/data_collected.md index 1cafd72bba..186b9d4026 100644 --- a/docs/rum_collection/data_collected.md +++ b/docs/rum_collection/data_collected.md @@ -117,7 +117,7 @@ You can enable [tracking user info][2] globally to collect and apply user attrib |------------------------------|--------|----------------------------------------------------------------------------| | `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.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. | From fae4125051668fa6f62fbddd439331d89c5d3f3d Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 22 Mar 2022 15:42:27 +0100 Subject: [PATCH 068/104] RUMM-1803 Stop reporting pre-warmed application launch time --- CHANGELOG.md | 1 + .../Core/System/LaunchTimeProvider.swift | 14 ++++++++- .../RUM/RUMMonitor/Scopes/RUMViewScope.swift | 16 +++++++++- .../_Datadog_Private/ObjcAppLaunchHandler.m | 15 ++++++++- .../include/ObjcAppLaunchHandler.h | 7 ++++- Tests/DatadogTests/Datadog/LoggerTests.swift | 2 +- .../Datadog/Mocks/CoreMocks.swift | 19 ++++++++++-- .../Datadog/Mocks/RUMFeatureMocks.swift | 2 +- .../RUMMonitor/Scopes/RUMViewScopeTests.swift | 31 ++++++++++++++++++- Tests/DatadogTests/Datadog/TracerTests.swift | 2 +- 10 files changed, 99 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aadf7836a4..bc245d78ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * [FEATURE] Web-view tracking. See [#729][] * [BUGFIX] Strip query parameters from span resource. See [#728][] +* [BUGFIX] Stop reporting pre-warmed application launch time. # 1.9.0 / 01-26-2022 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/RUM/RUMMonitor/Scopes/RUMViewScope.swift b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift index e104281dcc..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 @@ -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,7 +326,7 @@ 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, 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/DatadogTests/Datadog/LoggerTests.swift b/Tests/DatadogTests/Datadog/LoggerTests.swift index 3fbaeea43e..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() } diff --git a/Tests/DatadogTests/Datadog/Mocks/CoreMocks.swift b/Tests/DatadogTests/Datadog/Mocks/CoreMocks.swift index d6bfb6346c..732706118c 100644 --- a/Tests/DatadogTests/Datadog/Mocks/CoreMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/CoreMocks.swift @@ -491,7 +491,7 @@ extension FeaturesCommonDependencies { ) ), carrierInfoProvider: CarrierInfoProviderType = CarrierInfoProviderMock.mockAny(), - launchTimeProvider: LaunchTimeProviderType = LaunchTimeProviderMock(), + launchTimeProvider: LaunchTimeProviderType = LaunchTimeProviderMock.mockAny(), appStateListener: AppStateListening = AppStateListenerMock.mockAny() ) -> FeaturesCommonDependencies { let httpClient: HTTPClient @@ -682,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 0b0ad553b0..b23d151adc 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) 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/TracerTests.swift b/Tests/DatadogTests/Datadog/TracerTests.swift index a3b8f30089..7f4e5433e3 100644 --- a/Tests/DatadogTests/Datadog/TracerTests.swift +++ b/Tests/DatadogTests/Datadog/TracerTests.swift @@ -319,7 +319,7 @@ class TracerTests: XCTestCase { Datadog.instance = Datadog( consentProvider: ConsentProvider(initialConsent: .granted), userInfoProvider: UserInfoProvider(), - launchTimeProvider: LaunchTimeProviderMock() + launchTimeProvider: LaunchTimeProviderMock.mockAny() ) defer { Datadog.flushAndDeinitialize() } From 107ba57df1ba1a5cb3e44bd40d0dce9ecf371ecc Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 23 Mar 2022 15:38:25 +0100 Subject: [PATCH 069/104] RUMM-1803 Update CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc245d78ab..a0d828fccf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ * [FEATURE] Web-view tracking. See [#729][] * [BUGFIX] Strip query parameters from span resource. See [#728][] -* [BUGFIX] Stop reporting pre-warmed application launch time. +* [BUGFIX] Stop reporting pre-warmed application launch time. See [#789][] # 1.9.0 / 01-26-2022 @@ -325,6 +325,7 @@ [#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 +[#789]: https://github.com/DataDog/dd-sdk-ios/issues/789 [@00FA9A]: https://github.com/00FA9A [@Britton-Earnin]: https://github.com/Britton-Earnin [@Hengyu]: https://github.com/Hengyu From 799cb62bc8751ac128878b55cb4d5ec9f9ddea6f Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Thu, 24 Mar 2022 11:17:38 +0100 Subject: [PATCH 070/104] RUMM-1803 Add env ActivePrewarm unit tests --- .../Core/System/LaunchTimeProviderTests.swift | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Tests/DatadogTests/Datadog/Core/System/LaunchTimeProviderTests.swift b/Tests/DatadogTests/Datadog/Core/System/LaunchTimeProviderTests.swift index 9a108040fa..d9bc61df16 100644 --- a/Tests/DatadogTests/Datadog/Core/System/LaunchTimeProviderTests.swift +++ b/Tests/DatadogTests/Datadog/Core/System/LaunchTimeProviderTests.swift @@ -8,6 +8,11 @@ import XCTest @testable import Datadog class LaunchTimeProviderTests: XCTestCase { + override func tearDown() { + super.tearDown() + setenv("ActivePrewarm", "", 1) + } + func testGivenStartedApplication_whenRequestingLaunchTimeAtAnyTime_itReturnsTheSameValue() { // Given let provider = LaunchTimeProvider() @@ -35,4 +40,27 @@ 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) + } } From 16f7d57868e942a04d6e5149917c0c7b26624eaa Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 23 Feb 2022 14:28:32 +0100 Subject: [PATCH 071/104] RUMM-2033 Add tvOS compatibility --- .../Datadog/Core/Persistence/Files/File.swift | 4 +- .../Core/System/CarrierInfoProvider.swift | 24 +++++------ .../Datadog/Core/System/MobileDevice.swift | 19 +++++++++ .../NetworkConnectionInfoProvider.swift | 10 ++--- Sources/Datadog/Core/Utils/JSONEncoder.swift | 2 +- .../WKUserContentController+Datadog.swift | 4 ++ .../Kronos/KronosMonitor.swift | 4 +- .../Datadog/RUM/Debugging/RUMDebugging.swift | 12 ++++++ .../SwiftUI/SwiftUIActionModifier.swift | 5 +++ .../Views/SwiftUI/SwiftUIViewModifier.swift | 4 +- .../Interception/TaskInterception.swift | 2 +- Sources/Datadog/Utils/SwiftUIExtensions.swift | 2 +- .../DDCrashReportBuilderTests.swift | 2 +- .../System/CarrierInfoProviderTests.swift | 5 +++ .../Core/System/LaunchTimeProviderTests.swift | 5 +++ .../Core/System/MobileDeviceTests.swift | 2 + .../NetworkConnectionInfoProviderTests.swift | 10 ++--- .../CrashContextProviderTests.swift | 7 +++- .../SystemFrameworks/CoreTelephonyMocks.swift | 3 ++ .../Mocks/SystemFrameworks/UIKitMocks.swift | 42 +++++++++++++------ .../RUM/Debugging/RUMDebuggingTests.swift | 5 +++ .../UIKit/UIApplicationSwizzlerTests.swift | 5 +++ .../UIKitRUMUserActionsHandlerTests.swift | 2 +- .../UIKit/UIKitRUMViewsPredicateTests.swift | 2 +- ...WKUserContentController+DatadogTests.swift | 5 +++ .../Interception/TaskInterceptionTests.swift | 6 +-- .../Utils/SwiftUIExtensionsTests.swift | 8 ++-- 27 files changed, 145 insertions(+), 56 deletions(-) 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/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/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/Utils/JSONEncoder.swift b/Sources/Datadog/Core/Utils/JSONEncoder.swift index f6a2ae407b..5b33758c89 100644 --- a/Sources/Datadog/Core/Utils/JSONEncoder.swift +++ b/Sources/Datadog/Core/Utils/JSONEncoder.swift @@ -14,7 +14,7 @@ extension JSONEncoder { let formatted = iso8601DateFormatter.string(from: date) try container.encode(formatted) } - if #available(iOS 13.0, OSX 10.15, *) { + if #available(iOS 13, tvOS 13, macOS 10.15, *) { encoder.outputFormatting = [.withoutEscapingSlashes] } return encoder diff --git a/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift b/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift index e418e9186c..6992e1b2c2 100644 --- a/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift +++ b/Sources/Datadog/FeaturesIntegration/WebView/WKUserContentController+Datadog.swift @@ -4,6 +4,8 @@ * Copyright 2019-2020 Datadog, Inc. */ +#if !os(tvOS) + import Foundation import WebKit @@ -145,3 +147,5 @@ internal class DatadogMessageHandler: NSObject, WKScriptMessageHandler { } } } + +#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/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..e1ed099fd1 100644 --- a/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift +++ b/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift @@ -7,6 +7,9 @@ #if canImport(SwiftUI) import SwiftUI +// TODO: RUMM-2035 Enable SwiftUI tap action on tvOS +#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 +52,5 @@ public extension SwiftUI.View { } #endif + +#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/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/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/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/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 d9bc61df16..feeb52fae6 100644 --- a/Tests/DatadogTests/Datadog/Core/System/LaunchTimeProviderTests.swift +++ b/Tests/DatadogTests/Datadog/Core/System/LaunchTimeProviderTests.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 LaunchTimeProviderTests: XCTestCase { override func tearDown() { super.tearDown() @@ -64,3 +67,5 @@ class LaunchTimeProviderTests: XCTestCase { 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/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/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..b80173f2cf 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,16 +65,7 @@ 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 { 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..af80547ee9 100644 --- a/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift @@ -164,7 +164,7 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { 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] 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/WebView/WKUserContentController+DatadogTests.swift b/Tests/DatadogTests/Datadog/RUM/WebView/WKUserContentController+DatadogTests.swift index 62d1eb953b..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 { @@ -211,3 +214,5 @@ class WKUserContentController_DatadogTests: XCTestCase { } } } + +#endif 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 } From ae56e121ab00f0901f57fd76c646292c842de10c Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 23 Feb 2022 14:39:03 +0100 Subject: [PATCH 072/104] RUMM-2033 Rename iOS targets --- Datadog/Datadog.xcodeproj/project.pbxproj | 96 +++++++++---------- ...{Datadog.xcscheme => Datadog iOS.xcscheme} | 12 +-- ...eme => DatadogCrashReporting iOS.xcscheme} | 10 +- .../DatadogIntegrationTests.xcscheme | 4 +- ...Objc.xcscheme => DatadogObjc iOS.xcscheme} | 12 +-- Makefile | 4 +- xcconfigs/Base.xcconfig | 4 + 7 files changed, 73 insertions(+), 69 deletions(-) rename Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/{Datadog.xcscheme => Datadog iOS.xcscheme} (96%) rename Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/{DatadogCrashReporting.xcscheme => DatadogCrashReporting iOS.xcscheme} (96%) rename Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/{DatadogObjc.xcscheme => DatadogObjc iOS.xcscheme} (95%) diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index e9f70c141f..1fc62ab5a7 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -3594,9 +3594,9 @@ /* 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 */, @@ -3608,14 +3608,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 */, @@ -3627,14 +3627,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 */, @@ -3646,7 +3646,7 @@ dependencies = ( 61133C732423993200786299 /* PBXTargetDependency */, ); - name = DatadogObjc; + name = "DatadogObjc iOS"; productName = DatadogObjc; productReference = 61133BF0242397DA00786299 /* DatadogObjc.framework */; productType = "com.apple.product-type.framework"; @@ -3774,9 +3774,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 */, @@ -3789,14 +3789,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 */, @@ -3809,7 +3809,7 @@ 61B7885F25C180CB002675B5 /* PBXTargetDependency */, 61B7888025C18147002675B5 /* PBXTargetDependency */, ); - name = DatadogCrashReportingTests; + name = "DatadogCrashReportingTests iOS"; productName = DatadogCrashReportingTests; productReference = 61B7885C25C180CB002675B5 /* DatadogCrashReportingTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; @@ -3881,11 +3881,11 @@ 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 */, 61441C6724619FE4003D8BB8 /* DatadogBenchmarkTests */, 61441C2924616F1D003D8BB8 /* DatadogIntegrationTests */, 61441C0124616DE9003D8BB8 /* Example */, @@ -4709,7 +4709,7 @@ /* Begin PBXTargetDependency section */ 61133C732423993200786299 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61133B81242393DE00786299 /* Datadog */; + target = 61133B81242393DE00786299 /* Datadog iOS */; targetProxy = 61133C722423993200786299 /* PBXContainerItemProxy */; }; 61441C3024616F1D003D8BB8 /* PBXTargetDependency */ = { @@ -4719,7 +4719,7 @@ }; 61441C5024619499003D8BB8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61133B81242393DE00786299 /* Datadog */; + target = 61133B81242393DE00786299 /* Datadog iOS */; targetProxy = 61441C4F24619499003D8BB8 /* PBXContainerItemProxy */; }; 61441C5A24619A08003D8BB8 /* PBXTargetDependency */ = { @@ -4734,12 +4734,12 @@ }; 614ED39D260357FA00C8C519 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61B7885325C180CB002675B5 /* DatadogCrashReporting */; + target = 61B7885325C180CB002675B5 /* DatadogCrashReporting iOS */; targetProxy = 614ED39C260357FA00C8C519 /* PBXContainerItemProxy */; }; 6170DC5325C18E57003AED5C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61B7885325C180CB002675B5 /* DatadogCrashReporting */; + target = 61B7885325C180CB002675B5 /* DatadogCrashReporting iOS */; targetProxy = 6170DC5225C18E57003AED5C /* PBXContainerItemProxy */; }; 618F9846265BC486009959F8 /* PBXTargetDependency */ = { @@ -4749,12 +4749,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 */ = { @@ -4764,7 +4764,7 @@ }; 61B7885F25C180CB002675B5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61B7885325C180CB002675B5 /* DatadogCrashReporting */; + target = 61B7885325C180CB002675B5 /* DatadogCrashReporting iOS */; targetProxy = 61B7885E25C180CB002675B5 /* PBXContainerItemProxy */; }; 61B7888025C18147002675B5 /* PBXTargetDependency */ = { @@ -4774,7 +4774,7 @@ }; 61DE335825C82941008E3EC2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61133B81242393DE00786299 /* Datadog */; + target = 61133B81242393DE00786299 /* Datadog iOS */; targetProxy = 61DE335725C82941008E3EC2 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -4948,7 +4948,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; @@ -4977,7 +4977,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; @@ -4999,7 +4999,7 @@ "@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"; @@ -5022,7 +5022,7 @@ "@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; @@ -5051,7 +5051,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; @@ -5080,7 +5080,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; @@ -5465,7 +5465,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"; @@ -5496,7 +5496,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; @@ -5526,7 +5526,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; @@ -5547,7 +5547,7 @@ "@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"; }; @@ -5566,7 +5566,7 @@ "@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"; }; @@ -5585,7 +5585,7 @@ "@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"; }; @@ -5670,7 +5670,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; @@ -5699,7 +5699,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; @@ -5721,7 +5721,7 @@ "@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; @@ -5742,7 +5742,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61133B96242393DE00786299 /* Build configuration list for PBXNativeTarget "Datadog" */ = { + 61133B96242393DE00786299 /* Build configuration list for PBXNativeTarget "Datadog iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 61133B97242393DE00786299 /* Debug */, @@ -5752,7 +5752,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61133B99242393DE00786299 /* Build configuration list for PBXNativeTarget "DatadogTests" */ = { + 61133B99242393DE00786299 /* Build configuration list for PBXNativeTarget "DatadogTests iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 61133B9A242393DE00786299 /* Debug */, @@ -5762,7 +5762,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61133C01242397DA00786299 /* Build configuration list for PBXNativeTarget "DatadogObjc" */ = { + 61133C01242397DA00786299 /* Build configuration list for PBXNativeTarget "DatadogObjc iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 61133C02242397DA00786299 /* Debug */, @@ -5832,7 +5832,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 */, @@ -5842,7 +5842,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 */, 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/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/DatadogIntegrationTests.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogIntegrationTests.xcscheme index b73d9d58e8..8e15dbbfdc 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"> 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/Makefile b/Makefile index 4c750b6d47..52e4aa5c6d 100644 --- a/Makefile +++ b/Makefile @@ -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: 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" From 6ed0f5f0abf5f2110d869cd3ec21d16bade289b6 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 23 Feb 2022 15:35:44 +0100 Subject: [PATCH 073/104] RUMM-2023 Update bitrise configuration --- bitrise.yml | 12 ++++++------ tools/nightly-unit-tests/bitrise.yml.src | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bitrise.yml b/bitrise.yml index 23baa38716..3726780bc6 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -129,22 +129,22 @@ workflows: - xcode-test: title: Run unit tests for Datadog - iOS Simulator inputs: - - scheme: Datadog - - simulator_device: iPhone 11 + - scheme: Datadog iOS + - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - is_clean_build: 'yes' - test_repetition_mode: 'retry_on_failure' - maximum_test_repetitions: 2 - generate_code_coverage_files: 'yes' - project_path: Datadog.xcworkspace - - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/Datadog-unit-tests.html" + - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/Datadog-ios-unit-tests.html" - xcode-test: title: Run unit tests for DatadogCrashReporting - iOS Simulator inputs: - - scheme: DatadogCrashReporting - - simulator_device: iPhone 11 + - scheme: DatadogCrashReporting iOS + - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - generate_code_coverage_files: 'yes' - project_path: Datadog.xcworkspace - - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/DatadogCrashReporting-unit-tests.html" + - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/DatadogCrashReporting-ios-unit-tests.html" - xcode-test: title: Run benchmarks - DatadogBenchmarkTests on iOS Simulator inputs: 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: From 7481a09fb01b4fe72695e2f2087f9e445ae1d5c5 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 22 Feb 2022 13:38:16 +0100 Subject: [PATCH 074/104] RUMM-2033 Create Datadog tvOS targets --- Datadog/Datadog.xcodeproj/project.pbxproj | 1684 ++++++++++++++++- .../xcschemes/Datadog tvOS.xcscheme | 180 ++ .../DatadogCrashReporting tvOS.xcscheme | 227 +++ .../xcschemes/DatadogObjc tvOS.xcscheme | 177 ++ 4 files changed, 2238 insertions(+), 30 deletions(-) create mode 100644 Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Datadog tvOS.xcscheme create mode 100644 Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting tvOS.xcscheme create mode 100644 Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index 1fc62ab5a7..7a1f352407 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -550,8 +550,418 @@ 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 /* EnvironmentSpanIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13A880B257922EC004FB174 /* EnvironmentSpanIntegration.swift */; }; + 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 */; }; + D2CB6FEF27C5365A00A62B57 /* Datadog.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6ED127C50EAE00A62B57 /* Datadog.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D2CB6FF327C5369600A62B57 /* DatadogCrashReporting.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6FD127C5348200A62B57 /* DatadogCrashReporting.framework */; }; 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 */; }; @@ -605,13 +1015,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 */; @@ -668,6 +1071,34 @@ remoteGlobalIDString = 61133B81242393DE00786299; remoteInfo = Datadog; }; + D28D5D5327C53A60008E72D0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61133B79242393DE00786299 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2CB6FBA27C5348200A62B57; + remoteInfo = "DatadogCrashReporting tvOS"; + }; + D2CB6F9427C5217A00A62B57 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 61133B79242393DE00786299 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 61133B81242393DE00786299; + remoteInfo = Datadog; + }; + 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 */ @@ -696,6 +1127,17 @@ name = "⚙️ Embed Framework Dependencies"; runOnlyForDeploymentPostprocessing = 0; }; + D2CB6FF227C5365A00A62B57 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + D2CB6FEF27C5365A00A62B57 /* Datadog.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -1253,6 +1695,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 = ""; }; @@ -1366,6 +1813,49 @@ ); 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 */ @@ -1451,6 +1941,11 @@ 6199362B265BA958009D7EA8 /* E2E.app */, 61993665265BBEDC009D7EA8 /* E2ETests.xctest */, 618F9840265BC486009959F8 /* E2EInstrumentationTests.xctest */, + D2CB6ED127C50EAE00A62B57 /* Datadog.framework */, + D2CB6F8F27C520D400A62B57 /* DatadogTests.xctest */, + D2CB6FB027C5217A00A62B57 /* DatadogObjc.framework */, + D2CB6FD127C5348200A62B57 /* DatadogCrashReporting.framework */, + D2CB6FEC27C5352300A62B57 /* DatadogCrashReportingTests.xctest */, ); name = Products; sourceTree = ""; @@ -3591,6 +4086,32 @@ ); 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 */ @@ -3665,7 +4186,6 @@ dependencies = ( 61441C5024619499003D8BB8 /* PBXTargetDependency */, 6170DC5325C18E57003AED5C /* PBXTargetDependency */, - 614ED39D260357FA00C8C519 /* PBXTargetDependency */, ); name = Example; packageProductDependencies = ( @@ -3814,6 +4334,103 @@ productReference = 61B7885C25C180CB002675B5 /* DatadogCrashReportingTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 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 = ( + ); + 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 = ( + D2CB6F9327C5217A00A62B57 /* PBXTargetDependency */, + 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 */, + D2CB6FF227C5365A00A62B57 /* Embed 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 */, + ); + name = "DatadogCrashReportingTests tvOS"; + productName = DatadogCrashReportingTests; + productReference = D2CB6FEC27C5352300A62B57 /* DatadogCrashReportingTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -3886,6 +4503,11 @@ 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 */, @@ -3994,6 +4616,41 @@ ); 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 */ @@ -4111,6 +4768,82 @@ shellScript = "if which swiftlint >/dev/null; then\n cd ${SOURCE_ROOT}/..\n ./tools/lint/run-linter.sh\nfi\n"; showEnvVarsInLog = 0; }; + D2CB6ECB27C50EAE00A62B57 /* ⚙️ 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; + }; + 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 */ @@ -4704,22 +5437,453 @@ ); runOnlyForDeploymentPostprocessing = 0; }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 61133C732423993200786299 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 61133B81242393DE00786299 /* Datadog iOS */; - targetProxy = 61133C722423993200786299 /* PBXContainerItemProxy */; + D2CB6E0F27C50EAE00A62B57 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D2CB6E1027C50EAE00A62B57 /* CrashReportingWithRUMIntegration.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 /* EnvironmentSpanIntegration.swift 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; }; - 61441C3024616F1D003D8BB8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 61441C0124616DE9003D8BB8 /* Example */; - targetProxy = 61441C2F24616F1D003D8BB8 /* PBXContainerItemProxy */; + 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 */, + 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; }; - 61441C5024619499003D8BB8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 61133B81242393DE00786299 /* Datadog iOS */; + 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 iOS */; + targetProxy = 61133C722423993200786299 /* PBXContainerItemProxy */; + }; + 61441C3024616F1D003D8BB8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 61441C0124616DE9003D8BB8 /* Example */; + targetProxy = 61441C2F24616F1D003D8BB8 /* PBXContainerItemProxy */; + }; + 61441C5024619499003D8BB8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 61133B81242393DE00786299 /* Datadog iOS */; targetProxy = 61441C4F24619499003D8BB8 /* PBXContainerItemProxy */; }; 61441C5A24619A08003D8BB8 /* PBXTargetDependency */ = { @@ -4732,11 +5896,6 @@ target = 61441C0124616DE9003D8BB8 /* Example */; targetProxy = 61441C7424619FED003D8BB8 /* PBXContainerItemProxy */; }; - 614ED39D260357FA00C8C519 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 61B7885325C180CB002675B5 /* DatadogCrashReporting iOS */; - targetProxy = 614ED39C260357FA00C8C519 /* PBXContainerItemProxy */; - }; 6170DC5325C18E57003AED5C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 61B7885325C180CB002675B5 /* DatadogCrashReporting iOS */; @@ -4777,6 +5936,26 @@ target = 61133B81242393DE00786299 /* Datadog iOS */; targetProxy = 61DE335725C82941008E3EC2 /* PBXContainerItemProxy */; }; + D28D5D5427C53A60008E72D0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2CB6FBA27C5348200A62B57 /* DatadogCrashReporting tvOS */; + targetProxy = D28D5D5327C53A60008E72D0 /* PBXContainerItemProxy */; + }; + D2CB6F9327C5217A00A62B57 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 61133B81242393DE00786299 /* Datadog iOS */; + targetProxy = D2CB6F9427C5217A00A62B57 /* 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 */ @@ -4858,13 +6037,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 = ""; }; @@ -4915,12 +6094,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 = ""; @@ -5637,12 +6816,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 = ""; @@ -5729,6 +6908,401 @@ }; name = Integration; }; + 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; + }; + 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; + }; + 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; + }; + 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; + }; + 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; + }; + 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; + }; + name = Integration; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -5852,6 +7426,56 @@ 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 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 tvOS.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting tvOS.xcscheme new file mode 100644 index 0000000000..a80c12c694 --- /dev/null +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting tvOS.xcscheme @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..3fbe0116ba --- /dev/null +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 80d2f440fd69376ab342c3c136f4fabf5f7c539e Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 22 Feb 2022 19:14:27 +0100 Subject: [PATCH 075/104] RUMM-2023 Update bitrise configuration --- bitrise.yml | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/bitrise.yml b/bitrise.yml index 3726780bc6..19b893f3bd 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -123,6 +123,7 @@ workflows: run_unit_tests: description: |- Runs unit tests for SDK on iOS Simulator. + Runs unit tests for SDK on tvOS Simulator. Runs benchmarks for SDK on iOS Simulator. Runs unit tests for HTTPServerMock package on macOS. steps: @@ -145,11 +146,30 @@ workflows: - generate_code_coverage_files: 'yes' - project_path: Datadog.xcworkspace - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/DatadogCrashReporting-ios-unit-tests.html" + - xcode-test: + title: Run unit tests for Datadog - tvOS Simulator + inputs: + - scheme: Datadog tvOS + - destination: platform=tvOS Simulator,name=Apple TV,OS=latest + - is_clean_build: 'yes' + - test_repetition_mode: 'retry_on_failure' + - maximum_test_repetitions: 2 + - generate_code_coverage_files: 'yes' + - project_path: Datadog.xcworkspace + - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/Datadog-tvos-unit-tests.html" + - xcode-test: + title: Run unit tests for DatadogCrashReporting - tvOS Simulator + inputs: + - scheme: DatadogCrashReporting tvOS + - destination: platform=tvOS Simulator,name=Apple TV,OS=latest + - generate_code_coverage_files: 'yes' + - project_path: Datadog.xcworkspace + - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/DatadogCrashReporting-tvos-unit-tests.html" - xcode-test: title: Run benchmarks - DatadogBenchmarkTests on iOS Simulator inputs: - scheme: DatadogBenchmarkTests - - simulator_device: iPhone 11 + - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - should_build_before_test: 'no' - is_clean_build: 'no' - generate_code_coverage_files: 'yes' @@ -177,7 +197,7 @@ workflows: title: Run integration tests for RUM, Logging and Tracing (on iOS Simulator) inputs: - scheme: DatadogIntegrationTests - - simulator_device: iPhone 11 + - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - should_build_before_test: 'no' - is_clean_build: 'no' - generate_code_coverage_files: 'yes' @@ -188,7 +208,7 @@ workflows: title: Run integration tests for Crash Reporting (on iOS Simulator) inputs: - scheme: DatadogIntegrationTests - - simulator_device: iPhone 11 + - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - should_build_before_test: 'no' - is_clean_build: 'no' - generate_code_coverage_files: 'yes' @@ -219,7 +239,7 @@ workflows: title: Run SPMProject tests inputs: - scheme: SPMProject - - simulator_device: iPhone 11 + - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - is_clean_build: 'yes' - cache_level: none - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/spm/SPMProject.xcodeproj" @@ -235,7 +255,7 @@ workflows: title: Run CTProject tests inputs: - scheme: CTProject - - simulator_device: iPhone 11 + - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - is_clean_build: 'yes' - cache_level: none - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/carthage/CTProject.xcodeproj" @@ -251,7 +271,7 @@ workflows: title: Run CPProject tests with 'use_frameworks!' inputs: - scheme: CPProjectUseFrameworks - - simulator_device: iPhone 11 + - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - is_clean_build: 'yes' - cache_level: none - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/cocoapods/CPProject.xcworkspace" @@ -260,7 +280,7 @@ workflows: title: Run CPProject tests with no 'use_frameworks!' inputs: - scheme: CPProjectNoUseFrameworks - - simulator_device: iPhone 11 + - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - is_clean_build: 'yes' - cache_level: none - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/cocoapods/CPProject.xcworkspace" @@ -288,14 +308,14 @@ workflows: title: Run E2E tests for manual instrumentation APIs - iOS Simulator inputs: - scheme: E2ETests - - simulator_device: iPhone 11 + - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - project_path: Datadog.xcworkspace - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/E2E-tests.html" - xcode-test: title: Run E2E tests for auto instrumentation APIs - iOS Simulator inputs: - scheme: E2EInstrumentationTests - - simulator_device: iPhone 11 + - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - project_path: Datadog.xcworkspace - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/E2E-instrumentation-tests.html" From bb6da1af4ae81ac3ad7596b1c945ac734a32d669 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 23 Feb 2022 09:59:29 +0100 Subject: [PATCH 076/104] RUMM-2023 Update Makefile for tvOS --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 52e4aa5c6d..60bb64f757 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,8 @@ all: dependencies xcodeproj-httpservermock templates 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; From 00bc0354abcf8504cb24e048304bbafa6b07921a Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Fri, 25 Feb 2022 14:56:31 +0100 Subject: [PATCH 077/104] RUMM-2023 Fix tvOS CR coverage --- .../xcschemes/DatadogCrashReporting tvOS.xcscheme | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting tvOS.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting tvOS.xcscheme index a80c12c694..7feef26eed 100644 --- a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting tvOS.xcscheme +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogCrashReporting tvOS.xcscheme @@ -171,9 +171,9 @@ From cd99e234a5c58259b4c6c96c1b115973afd17d78 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Thu, 24 Feb 2022 14:58:10 +0100 Subject: [PATCH 078/104] RUMM-2036 Add tvOS deployment target to podspec --- DatadogSDK.podspec | 1 + DatadogSDK.podspec.src | 1 + DatadogSDKAlamofireExtension.podspec | 1 + DatadogSDKAlamofireExtension.podspec.src | 1 + DatadogSDKCrashReporting.podspec | 1 + DatadogSDKCrashReporting.podspec.src | 1 + DatadogSDKObjc.podspec | 1 + DatadogSDKObjc.podspec.src | 1 + 8 files changed, 8 insertions(+) diff --git a/DatadogSDK.podspec b/DatadogSDK.podspec index 3903903ee6..511457c688 100644 --- a/DatadogSDK.podspec +++ b/DatadogSDK.podspec @@ -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 8fcbb6ac32..ceecf9d863 100644 --- a/DatadogSDKAlamofireExtension.podspec +++ b/DatadogSDKAlamofireExtension.podspec @@ -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 a9c4267349..21bc91be6e 100644 --- a/DatadogSDKCrashReporting.podspec +++ b/DatadogSDKCrashReporting.podspec @@ -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/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 9b010d292f..c43456776b 100644 --- a/DatadogSDKObjc.podspec +++ b/DatadogSDKObjc.podspec @@ -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/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 } From fef933ebe32959acfeb4ebbce5dd3a986267771b Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Fri, 25 Feb 2022 14:11:47 +0100 Subject: [PATCH 079/104] RUMM-2036 CocoaPods tvOS integration tests --- bitrise.yml | 30 +- .../{CPProject => App}/AppDelegate.swift | 0 .../cocoapods/{CPProject => App}/Info.plist | 6 - .../{CPProject => App}/SceneDelegate.swift | 8 + .../{CPProject => App}/ViewController.swift | 13 + .../CPProjectTests.swift | 7 +- .../{CPProjectTests => AppTests}/Info.plist | 0 .../CPProjectUITests.swift | 0 .../Info.plist | 0 .../CPProject.xcodeproj/project.pbxproj | 1025 ++++++++++++++--- ...orks.xcscheme => App Dynamic iOS.xcscheme} | 20 +- .../xcschemes/App Dynamic tvOS.xcscheme | 98 ++ ...works.xcscheme => App Static iOS.xcscheme} | 20 +- .../xcschemes/App Static tvOS.xcscheme | 98 ++ .../Base.lproj/LaunchScreen.storyboard | 25 - .../CPProject/Base.lproj/Main.storyboard | 45 - .../cocoapods/Podfile.src | 25 +- 17 files changed, 1166 insertions(+), 254 deletions(-) rename dependency-manager-tests/cocoapods/{CPProject => App}/AppDelegate.swift (100%) rename dependency-manager-tests/cocoapods/{CPProject => App}/Info.plist (90%) rename dependency-manager-tests/cocoapods/{CPProject => App}/SceneDelegate.swift (74%) rename dependency-manager-tests/cocoapods/{CPProject => App}/ViewController.swift (82%) rename dependency-manager-tests/cocoapods/{CPProjectTests => AppTests}/CPProjectTests.swift (78%) rename dependency-manager-tests/cocoapods/{CPProjectTests => AppTests}/Info.plist (100%) rename dependency-manager-tests/cocoapods/{CPProjectUITests => AppUITests}/CPProjectUITests.swift (100%) rename dependency-manager-tests/cocoapods/{CPProjectUITests => AppUITests}/Info.plist (100%) rename dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/{CPProjectUseFrameworks.xcscheme => App Dynamic iOS.xcscheme} (84%) create mode 100644 dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Dynamic tvOS.xcscheme rename dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/{CPProjectNoUseFrameworks.xcscheme => App Static iOS.xcscheme} (84%) create mode 100644 dependency-manager-tests/cocoapods/CPProject.xcodeproj/xcshareddata/xcschemes/App Static tvOS.xcscheme delete mode 100644 dependency-manager-tests/cocoapods/CPProject/Base.lproj/LaunchScreen.storyboard delete mode 100644 dependency-manager-tests/cocoapods/CPProject/Base.lproj/Main.storyboard diff --git a/bitrise.yml b/bitrise.yml index 19b893f3bd..0ff6cd33fc 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -268,23 +268,41 @@ workflows: set -e make test-cocoapods ci=${CI} - xcode-test: - title: Run CPProject tests with 'use_frameworks!' + title: Run CPProject tests iOS with 'use_frameworks!' inputs: - - scheme: CPProjectUseFrameworks + - scheme: App Dynamic iOS - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - is_clean_build: 'yes' - cache_level: none - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/cocoapods/CPProject.xcworkspace" - - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/CPProject-use_frameworks-tests.html" + - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/CPProject-ios-dynamic-tests.html" - xcode-test: - title: Run CPProject tests with no 'use_frameworks!' + title: Run CPProject tests iOS with no 'use_frameworks!' inputs: - - scheme: CPProjectNoUseFrameworks + - scheme: App Static iOS - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - is_clean_build: 'yes' - cache_level: none - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/cocoapods/CPProject.xcworkspace" - - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/CPProject-no_use_frameworks-tests.html" + - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/CPProject-ios-static-tests.html" + - xcode-test: + title: Run CPProject tests tvOS with 'use_frameworks!' + inputs: + - scheme: App Dynamic tvOS + - destination: platform=tvOS Simulator,name=Apple TV,OS=latest + - is_clean_build: 'yes' + - cache_level: none + - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/cocoapods/CPProject.xcworkspace" + - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/CPProject-tvos-dynamic-tests.html" + - xcode-test: + title: Run CPProject tests tvOS with no 'use_frameworks!' + inputs: + - scheme: App Static tvOS + - destination: platform=tvOS Simulator,name=Apple TV,OS=latest + - is_clean_build: 'yes' + - cache_level: none + - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/cocoapods/CPProject.xcworkspace" + - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/CPProject-tvos-static-tests.html" create_dogfooding_pr: description: |- 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/cocoapods/CPProject/SceneDelegate.swift b/dependency-manager-tests/cocoapods/App/SceneDelegate.swift similarity index 74% rename from dependency-manager-tests/cocoapods/CPProject/SceneDelegate.swift rename to dependency-manager-tests/cocoapods/App/SceneDelegate.swift index c812c9793c..09f8e5a3ae 100644 --- a/dependency-manager-tests/cocoapods/CPProject/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 From 2058e3610fcf4d4dcb86c162ff10c0d5b0ab6d58 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Mon, 28 Feb 2022 09:23:48 +0100 Subject: [PATCH 080/104] RUMM-2037 Add tvOS platform to Package.swift --- Package.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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( From 674846008bc700d961d9325badf3fbcb4803c0c8 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Mon, 28 Feb 2022 09:48:49 +0100 Subject: [PATCH 081/104] RUMM-2037 SPM tvOS integration tests --- bitrise.yml | 17 +- .../spm/{SPMProject => App}/AppDelegate.swift | 0 .../spm/{SPMProject => App}/Info.plist | 6 - .../{SPMProject => App}/SceneDelegate.swift | 8 + .../{SPMProject => App}/ViewController.swift | 13 + .../AppTests.swift} | 3 +- .../{SPMProjectTests => AppTests}/Info.plist | 0 .../AppUITests.swift} | 0 .../Info.plist | 0 .../SPMProject.xcodeproj.src/project.pbxproj | 520 +++++++++++++++--- .../{SPMProject.xcscheme => App iOS.xcscheme} | 22 +- .../xcshareddata/xcschemes/App tvOS.xcscheme | 98 ++++ .../Base.lproj/LaunchScreen.storyboard | 25 - .../spm/SPMProject/Base.lproj/Main.storyboard | 57 -- 14 files changed, 583 insertions(+), 186 deletions(-) rename dependency-manager-tests/spm/{SPMProject => App}/AppDelegate.swift (100%) rename dependency-manager-tests/spm/{SPMProject => App}/Info.plist (90%) rename dependency-manager-tests/spm/{SPMProject => App}/SceneDelegate.swift (74%) rename dependency-manager-tests/spm/{SPMProject => App}/ViewController.swift (79%) rename dependency-manager-tests/spm/{SPMProjectTests/SPMProjectTests.swift => AppTests/AppTests.swift} (94%) rename dependency-manager-tests/spm/{SPMProjectTests => AppTests}/Info.plist (100%) rename dependency-manager-tests/spm/{SPMProjectUITests/SPMProjectUITests.swift => AppUITests/AppUITests.swift} (100%) rename dependency-manager-tests/spm/{SPMProjectUITests => AppUITests}/Info.plist (100%) rename dependency-manager-tests/spm/SPMProject.xcodeproj.src/xcshareddata/xcschemes/{SPMProject.xcscheme => App iOS.xcscheme} (86%) create mode 100644 dependency-manager-tests/spm/SPMProject.xcodeproj.src/xcshareddata/xcschemes/App tvOS.xcscheme delete mode 100644 dependency-manager-tests/spm/SPMProject/Base.lproj/LaunchScreen.storyboard delete mode 100644 dependency-manager-tests/spm/SPMProject/Base.lproj/Main.storyboard diff --git a/bitrise.yml b/bitrise.yml index 0ff6cd33fc..37d5fbca60 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -231,19 +231,28 @@ workflows: - xcodebuild: title: Check Mac Catalyst compatibility (build SPMProject for Catalyst) inputs: - - scheme: SPMProject + - scheme: App iOS - destination: platform=macOS,variant=Mac Catalyst - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/spm/SPMProject.xcodeproj" - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/SPMProject-catalyst-sanity-check.html" - xcode-test: - title: Run SPMProject tests + title: Run SPMProject iOS tests inputs: - - scheme: SPMProject + - scheme: App iOS - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - is_clean_build: 'yes' - cache_level: none - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/spm/SPMProject.xcodeproj" - - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/SPMProject-tests.html" + - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/SPMProject-ios-tests.html" + - xcode-test: + title: Run SPMProject tvOS tests + inputs: + - scheme: App tvOS + - destination: platform=tvOS Simulator,name=Apple TV,OS=latest + - is_clean_build: 'yes' + - cache_level: none + - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/spm/SPMProject.xcodeproj" + - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/SPMProject-tvos-tests.html" - script: title: Test Carthage compatibility inputs: 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/spm/SPMProject/SceneDelegate.swift b/dependency-manager-tests/spm/App/SceneDelegate.swift similarity index 74% rename from dependency-manager-tests/spm/SPMProject/SceneDelegate.swift rename to dependency-manager-tests/spm/App/SceneDelegate.swift index c812c9793c..09f8e5a3ae 100644 --- a/dependency-manager-tests/spm/SPMProject/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/SPMProject.xcodeproj.src/project.pbxproj b/dependency-manager-tests/spm/SPMProject.xcodeproj.src/project.pbxproj index 810d7ecf50..00c29aa360 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,14 +989,49 @@ 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; + branch = REMOTE_GIT_REFERENCE; + kind = branch; + }; + }; + D23BF5F127CCCC3300BB4CCD /* XCRemoteSwiftPackageReference "dd-sdk-ios" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/DataDog/dd-sdk-ios"; + requirement = { + branch = REMOTE_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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 4b348c05684ced5fa39faab7a42a7313b8323599 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Mon, 28 Feb 2022 16:05:44 +0100 Subject: [PATCH 082/104] RUMM-2037 Fix make create-src-from-xcodeproj --- dependency-manager-tests/spm/Makefile | 2 +- .../spm/SPMProject.xcodeproj.src/project.pbxproj | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 00c29aa360..d65fe4f82b 100644 --- a/dependency-manager-tests/spm/SPMProject.xcodeproj.src/project.pbxproj +++ b/dependency-manager-tests/spm/SPMProject.xcodeproj.src/project.pbxproj @@ -1023,7 +1023,7 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/DataDog/dd-sdk-ios"; requirement = { - branch = REMOTE_GIT_REFERENCE; + branch = GIT_REFERENCE; kind = branch; }; }; @@ -1031,7 +1031,7 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/DataDog/dd-sdk-ios"; requirement = { - branch = REMOTE_GIT_REFERENCE; + branch = GIT_REFERENCE; kind = branch; }; }; From 24b7e41d36451f4e65b08747a6bca0db12db2894 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Mon, 28 Feb 2022 11:59:15 +0100 Subject: [PATCH 083/104] RUMM-2045 Fix DatadogObjc tvOS build --- Datadog/Datadog.xcodeproj/project.pbxproj | 26 ------------------- .../xcschemes/DatadogObjc tvOS.xcscheme | 8 +++--- 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index 7a1f352407..d3b5ab6f4d 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -960,7 +960,6 @@ 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 */; }; - D2CB6FEF27C5365A00A62B57 /* Datadog.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6ED127C50EAE00A62B57 /* Datadog.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; D2CB6FF327C5369600A62B57 /* DatadogCrashReporting.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2CB6FD127C5348200A62B57 /* DatadogCrashReporting.framework */; }; D2EFF3D32731822A00D09F33 /* RUMViewsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EFF3D22731822A00D09F33 /* RUMViewsHandler.swift */; }; D2F1B81126D795F3009F3293 /* DDNoopRUMMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F1B81026D795F3009F3293 /* DDNoopRUMMonitor.swift */; }; @@ -1078,13 +1077,6 @@ remoteGlobalIDString = D2CB6FBA27C5348200A62B57; remoteInfo = "DatadogCrashReporting tvOS"; }; - D2CB6F9427C5217A00A62B57 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 61133B79242393DE00786299 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 61133B81242393DE00786299; - remoteInfo = Datadog; - }; D2CB6FB527C5234300A62B57 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 61133B79242393DE00786299 /* Project object */; @@ -1127,17 +1119,6 @@ name = "⚙️ Embed Framework Dependencies"; runOnlyForDeploymentPostprocessing = 0; }; - D2CB6FF227C5365A00A62B57 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - D2CB6FEF27C5365A00A62B57 /* Datadog.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -4383,7 +4364,6 @@ buildRules = ( ); dependencies = ( - D2CB6F9327C5217A00A62B57 /* PBXTargetDependency */, D2CB6FB627C5234300A62B57 /* PBXTargetDependency */, ); name = "DatadogObjc tvOS"; @@ -4400,7 +4380,6 @@ D2CB6FC827C5348200A62B57 /* Resources */, D2CB6FC927C5348200A62B57 /* ⚙️ Run linter */, D2CB6FCA27C5348200A62B57 /* Frameworks */, - D2CB6FF227C5365A00A62B57 /* Embed Frameworks */, ); buildRules = ( ); @@ -5941,11 +5920,6 @@ target = D2CB6FBA27C5348200A62B57 /* DatadogCrashReporting tvOS */; targetProxy = D28D5D5327C53A60008E72D0 /* PBXContainerItemProxy */; }; - D2CB6F9327C5217A00A62B57 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 61133B81242393DE00786299 /* Datadog iOS */; - targetProxy = D2CB6F9427C5217A00A62B57 /* PBXContainerItemProxy */; - }; D2CB6FB627C5234300A62B57 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = D2CB6E0A27C50EAE00A62B57 /* Datadog tvOS */; diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme index 3fbe0116ba..504ee8d144 100644 --- a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme @@ -22,10 +22,10 @@ + buildForRunning = "NO" + buildForProfiling = "NO" + buildForArchiving = "NO" + buildForAnalyzing = "NO"> Date: Mon, 28 Feb 2022 14:56:49 +0100 Subject: [PATCH 084/104] RUMM-2045 Carthage tvOS integration tests --- bitrise.yml | 15 +- .../{CTProject => App}/AppDelegate.swift | 0 .../carthage/{CTProject => App}/Info.plist | 6 - .../{CTProject => App}/SceneDelegate.swift | 8 + .../{CTProject => App}/ViewController.swift | 13 + .../AppTests.swift} | 3 +- .../{CTProjectTests => AppTests}/Info.plist | 0 .../AppUITests.swift} | 0 .../Info.plist | 0 .../CTProject.xcodeproj/project.pbxproj | 494 +++++++++++++++--- .../xcshareddata/xcschemes/App iOS.xcscheme | 98 ++++ .../xcshareddata/xcschemes/App tvOS.xcscheme | 98 ++++ .../Base.lproj/LaunchScreen.storyboard | 25 - .../CTProject/Base.lproj/Main.storyboard | 57 -- dependency-manager-tests/carthage/Makefile | 2 +- 15 files changed, 644 insertions(+), 175 deletions(-) rename dependency-manager-tests/carthage/{CTProject => App}/AppDelegate.swift (100%) rename dependency-manager-tests/carthage/{CTProject => App}/Info.plist (90%) rename dependency-manager-tests/carthage/{CTProject => App}/SceneDelegate.swift (74%) rename dependency-manager-tests/carthage/{CTProject => App}/ViewController.swift (79%) rename dependency-manager-tests/carthage/{CTProjectTests/CTProjectTests.swift => AppTests/AppTests.swift} (94%) rename dependency-manager-tests/carthage/{CTProjectTests => AppTests}/Info.plist (100%) rename dependency-manager-tests/carthage/{CTProjectUITests/CTProjectUITests.swift => AppUITests/AppUITests.swift} (100%) rename dependency-manager-tests/carthage/{CTProjectUITests => AppUITests}/Info.plist (100%) create mode 100644 dependency-manager-tests/carthage/CTProject.xcodeproj/xcshareddata/xcschemes/App iOS.xcscheme create mode 100644 dependency-manager-tests/carthage/CTProject.xcodeproj/xcshareddata/xcschemes/App tvOS.xcscheme delete mode 100644 dependency-manager-tests/carthage/CTProject/Base.lproj/LaunchScreen.storyboard delete mode 100644 dependency-manager-tests/carthage/CTProject/Base.lproj/Main.storyboard diff --git a/bitrise.yml b/bitrise.yml index 37d5fbca60..a65dd185f3 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -261,14 +261,23 @@ workflows: set -e make test-carthage ci=${CI} - xcode-test: - title: Run CTProject tests + title: Run CTProject iOS tests inputs: - - scheme: CTProject + - scheme: App iOS - destination: platform=iOS Simulator,name=iPhone 11,OS=latest - is_clean_build: 'yes' - cache_level: none - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/carthage/CTProject.xcodeproj" - - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/CTProject-tests.html" + - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/CTProject-ios-tests.html" + - xcode-test: + title: Run CTProject tvOS tests + inputs: + - scheme: App tvOS + - destination: platform=tvOS Simulator,name=Apple TV,OS=latest + - is_clean_build: 'yes' + - cache_level: none + - project_path: "$BITRISE_SOURCE_DIR/dependency-manager-tests/carthage/CTProject.xcodeproj" + - xcpretty_test_options: --color --report html --output "${BITRISE_DEPLOY_DIR}/CTProject-tvos-tests.html" - script: title: Test Cocoapods compatibility inputs: diff --git a/dependency-manager-tests/carthage/CTProject/AppDelegate.swift b/dependency-manager-tests/carthage/App/AppDelegate.swift similarity index 100% rename from dependency-manager-tests/carthage/CTProject/AppDelegate.swift rename to dependency-manager-tests/carthage/App/AppDelegate.swift diff --git a/dependency-manager-tests/carthage/CTProject/Info.plist b/dependency-manager-tests/carthage/App/Info.plist similarity index 90% rename from dependency-manager-tests/carthage/CTProject/Info.plist rename to dependency-manager-tests/carthage/App/Info.plist index 2a3483c0d2..639166254f 100644 --- a/dependency-manager-tests/carthage/CTProject/Info.plist +++ b/dependency-manager-tests/carthage/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/carthage/CTProject/SceneDelegate.swift b/dependency-manager-tests/carthage/App/SceneDelegate.swift similarity index 74% rename from dependency-manager-tests/carthage/CTProject/SceneDelegate.swift rename to dependency-manager-tests/carthage/App/SceneDelegate.swift index c812c9793c..09f8e5a3ae 100644 --- a/dependency-manager-tests/carthage/CTProject/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..8f08e2c929 100644 --- a/dependency-manager-tests/carthage/CTProject.xcodeproj/project.pbxproj +++ b/dependency-manager-tests/carthage/CTProject.xcodeproj/project.pbxproj @@ -10,17 +10,29 @@ 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 */; }; + D24C2F7727CCDDAA001365B0 /* DatadogCrashReporting.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 615D9E6A2604B5B1006DC6D1 /* DatadogCrashReporting.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 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, ); }; }; + D290BA2727CD09740019936D /* DatadogCrashReporting.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 615D9E6A2604B5B1006DC6D1 /* DatadogCrashReporting.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 +50,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 */ @@ -48,12 +74,27 @@ dstSubfolderSpec = 10; files = ( 9EF87B8D26B04E1F00998076 /* CrashReporter.xcframework in Embed Frameworks */, + D24C2F7727CCDDAA001365B0 /* DatadogCrashReporting.xcframework in Embed Frameworks */, 9E9D5E8D25F90FC6002F12A0 /* Datadog.xcframework in Embed Frameworks */, 9E9D5E8B25F90FC6002F12A0 /* DatadogObjc.xcframework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; + D290BA2527CD09740019936D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + D290BA2627CD09740019936D /* CrashReporter.xcframework in Embed Frameworks */, + D290BA2727CD09740019936D /* DatadogCrashReporting.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 +102,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 +127,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 +147,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 +189,9 @@ isa = PBXGroup; children = ( 615519312461CDB4002A85CF /* xcconfigs */, - 61C36417243752A500C4D4E6 /* CTProject */, - 61C3642E243752A600C4D4E6 /* CTProjectTests */, - 61C36439243752A600C4D4E6 /* CTProjectUITests */, + 61C36417243752A500C4D4E6 /* App */, + 61C3642E243752A600C4D4E6 /* AppTests */, + 61C36439243752A600C4D4E6 /* AppUITests */, 61C36416243752A500C4D4E6 /* Products */, 61C364492437547A00C4D4E6 /* Frameworks */, ); @@ -133,42 +200,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 +254,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 +268,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 +286,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 +304,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 +371,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1140; - LastUpgradeCheck = 1140; + LastUpgradeCheck = 1310; ORGANIZATIONNAME = Datadog; TargetAttributes = { 61C36414243752A500C4D4E6 = { @@ -262,6 +385,12 @@ CreatedOnToolsVersion = 11.4; TestTargetID = 61C36414243752A500C4D4E6; }; + D290BA2F27CD09A20019936D = { + TestTargetID = D290BA1927CD09740019936D; + }; + D290BA3B27CD09C70019936D = { + TestTargetID = D290BA1927CD09740019936D; + }; }; }; buildConfigurationList = 61C36410243752A500C4D4E6 /* Build configuration list for PBXProject "CTProject" */; @@ -277,9 +406,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 +421,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61C36425243752A600C4D4E6 /* LaunchScreen.storyboard in Resources */, - 61C36420243752A500C4D4E6 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -308,6 +438,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 +481,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 +517,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61C36430243752A600C4D4E6 /* CTProjectTests.swift in Sources */, + 61C36430243752A600C4D4E6 /* AppTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -355,7 +525,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 +560,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 +608,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 +640,7 @@ SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TVOS_DEPLOYMENT_TARGET = 13.0; VALIDATE_WORKSPACE = YES; }; name = Debug; @@ -483,6 +672,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 +697,7 @@ SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; + TVOS_DEPLOYMENT_TARGET = 13.0; VALIDATE_PRODUCT = YES; VALIDATE_WORKSPACE = YES; }; @@ -517,13 +708,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 +725,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 +743,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 +753,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 +763,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 +773,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 +782,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 +801,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 +815,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 +939,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 +948,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 +957,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 +966,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; } From acff4bbc70930a4f68a62e1241f6918d144f3bc3 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 8 Mar 2022 09:43:33 +0100 Subject: [PATCH 085/104] RUMM-2045 Do not embed DatadogCrashReporter.xcframework --- .../carthage/CTProject.xcodeproj/project.pbxproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dependency-manager-tests/carthage/CTProject.xcodeproj/project.pbxproj b/dependency-manager-tests/carthage/CTProject.xcodeproj/project.pbxproj index 8f08e2c929..e1157d8967 100644 --- a/dependency-manager-tests/carthage/CTProject.xcodeproj/project.pbxproj +++ b/dependency-manager-tests/carthage/CTProject.xcodeproj/project.pbxproj @@ -19,7 +19,6 @@ 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, ); }; }; D24C2F7627CCDDAA001365B0 /* DatadogCrashReporting.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 615D9E6A2604B5B1006DC6D1 /* DatadogCrashReporting.xcframework */; }; - D24C2F7727CCDDAA001365B0 /* DatadogCrashReporting.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 615D9E6A2604B5B1006DC6D1 /* DatadogCrashReporting.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 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 */; }; @@ -28,7 +27,6 @@ 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, ); }; }; - D290BA2727CD09740019936D /* DatadogCrashReporting.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 615D9E6A2604B5B1006DC6D1 /* DatadogCrashReporting.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 */; }; @@ -74,7 +72,6 @@ dstSubfolderSpec = 10; files = ( 9EF87B8D26B04E1F00998076 /* CrashReporter.xcframework in Embed Frameworks */, - D24C2F7727CCDDAA001365B0 /* DatadogCrashReporting.xcframework in Embed Frameworks */, 9E9D5E8D25F90FC6002F12A0 /* Datadog.xcframework in Embed Frameworks */, 9E9D5E8B25F90FC6002F12A0 /* DatadogObjc.xcframework in Embed Frameworks */, ); @@ -88,7 +85,6 @@ dstSubfolderSpec = 10; files = ( D290BA2627CD09740019936D /* CrashReporter.xcframework in Embed Frameworks */, - D290BA2727CD09740019936D /* DatadogCrashReporting.xcframework in Embed Frameworks */, D290BA2827CD09740019936D /* Datadog.xcframework in Embed Frameworks */, D290BA2927CD09740019936D /* DatadogObjc.xcframework in Embed Frameworks */, ); From 170de04c183ae9ffb162312876fdfcc445e979ac Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 1 Mar 2022 15:49:00 +0100 Subject: [PATCH 086/104] RUMM-2034 Rename Example iOS target --- Datadog/Datadog.xcodeproj/project.pbxproj | 45 ++++++++++--------- .../DatadogIntegrationTests.xcscheme | 4 +- ...{Example.xcscheme => Example iOS.xcscheme} | 12 ++--- 3 files changed, 32 insertions(+), 29 deletions(-) rename Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/{Example.xcscheme => Example iOS.xcscheme} (96%) diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index d3b5ab6f4d..2f1d5c6b9e 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -1287,7 +1287,7 @@ 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 = ""; }; 61441C0D24616DEC003D8BB8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -1914,7 +1914,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 */, @@ -4153,9 +4153,9 @@ 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 */, @@ -4168,11 +4168,11 @@ 61441C5024619499003D8BB8 /* PBXTargetDependency */, 6170DC5325C18E57003AED5C /* 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 */ = { @@ -4489,7 +4489,7 @@ D2CB6FD327C5352300A62B57 /* DatadogCrashReportingTests tvOS */, 61441C6724619FE4003D8BB8 /* DatadogBenchmarkTests */, 61441C2924616F1D003D8BB8 /* DatadogIntegrationTests */, - 61441C0124616DE9003D8BB8 /* Example */, + 61441C0124616DE9003D8BB8 /* Example iOS */, 6199362A265BA958009D7EA8 /* E2E */, 61993664265BBEDC009D7EA8 /* E2ETests */, 618F983F265BC486009959F8 /* E2EInstrumentationTests */, @@ -5857,7 +5857,7 @@ }; 61441C3024616F1D003D8BB8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61441C0124616DE9003D8BB8 /* Example */; + target = 61441C0124616DE9003D8BB8 /* Example iOS */; targetProxy = 61441C2F24616F1D003D8BB8 /* PBXContainerItemProxy */; }; 61441C5024619499003D8BB8 /* PBXTargetDependency */ = { @@ -5867,12 +5867,12 @@ }; 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 */; }; 6170DC5325C18E57003AED5C /* PBXTargetDependency */ = { @@ -5907,7 +5907,7 @@ }; 61B7888025C18147002675B5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 61441C0124616DE9003D8BB8 /* Example */; + target = 61441C0124616DE9003D8BB8 /* Example iOS */; targetProxy = 61B7887F25C18147002675B5 /* PBXContainerItemProxy */; }; 61DE335825C82941008E3EC2 /* PBXTargetDependency */ = { @@ -6157,7 +6157,7 @@ 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; }; @@ -6179,7 +6179,7 @@ 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; }; @@ -6254,6 +6254,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"; @@ -6275,6 +6276,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; @@ -6295,6 +6297,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; @@ -6376,7 +6379,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; }; @@ -6394,7 +6397,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; }; @@ -6412,7 +6415,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; }; @@ -6702,7 +6705,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReportingTests; 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; }; @@ -6721,7 +6724,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReportingTests; 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; }; @@ -6740,7 +6743,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.datadogqh.DatadogCrashReportingTests; 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; }; @@ -6878,7 +6881,7 @@ 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; }; @@ -7320,7 +7323,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 61441C1324616DEC003D8BB8 /* Build configuration list for PBXNativeTarget "Example" */ = { + 61441C1324616DEC003D8BB8 /* Build configuration list for PBXNativeTarget "Example iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 61441C1424616DEC003D8BB8 /* Debug */, diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogIntegrationTests.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogIntegrationTests.xcscheme index 8e15dbbfdc..1b7b188ffe 100644 --- a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogIntegrationTests.xcscheme +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogIntegrationTests.xcscheme @@ -191,8 +191,8 @@ 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 @@ From 39ffcb440a14cadefb65c9ec7dc3556e9e5bc3d1 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 2 Mar 2022 10:05:18 +0100 Subject: [PATCH 087/104] RUMM-2034 Add Example tvOS --- Datadog/Datadog.xcodeproj/project.pbxproj | 350 +++++++++++++++--- .../xcschemes/DatadogObjc tvOS.xcscheme | 10 + .../xcschemes/Example tvOS.xcscheme | 88 +++++ Datadog/Example/AppConfiguration.swift | 6 +- .../{Main.storyboard => Main iOS.storyboard} | 0 .../DebugBackgroundEventsViewController.swift | 10 +- .../Example/Debugging/Helpers/SwiftUI.swift | 4 +- Datadog/Example/ExampleAppDelegate.swift | 2 + .../Example/Utils/UIButton+Disabling.swift | 6 +- .../Logging/LoggingCommonAsserts.swift | 2 +- .../Scenarios/RUM/RUMCommonAsserts.swift | 2 +- .../Tracing/TracingCommonAsserts.swift | 2 +- 12 files changed, 406 insertions(+), 76 deletions(-) create mode 100644 Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/Example tvOS.xcscheme rename Datadog/Example/Base.lproj/{Main.storyboard => Main iOS.storyboard} (100%) diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index 2f1d5c6b9e..debb725d19 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,6 +537,33 @@ 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 */; }; + D240685327CF5CE900C04F44 /* CrashReporter.xcframework in ⚙️ Embed Framework Dependencies */ = {isa = PBXBuildFile; fileRef = 614ED36B260352DC00C8C519 /* CrashReporter.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 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 */; }; + D240687927CF982B00C04F44 /* CrashReporter.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 614ED36B260352DC00C8C519 /* CrashReporter.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 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 */; }; @@ -993,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 */; @@ -1014,13 +1027,6 @@ remoteGlobalIDString = 61441C0124616DE9003D8BB8; remoteInfo = Example; }; - 6170DC5225C18E57003AED5C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 61133B79242393DE00786299 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 61B7885325C180CB002675B5; - remoteInfo = DatadogCrashReporting; - }; 618F9845265BC486009959F8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 61133B79242393DE00786299 /* Project object */; @@ -1070,6 +1076,41 @@ 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 */; @@ -1094,31 +1135,57 @@ /* 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 */, + D240685327CF5CE900C04F44 /* CrashReporter.xcframework 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 */, + D240687927CF982B00C04F44 /* CrashReporter.xcframework in Embed Frameworks */, + D240687C27CF982C00C04F44 /* Datadog.framework in Embed Frameworks */, + D240688027CF982F00C04F44 /* DatadogObjc.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + D2CB6FF227C5365A00A62B57 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + D2CB6FEF27C5365A00A62B57 /* Datadog.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -1289,9 +1356,8 @@ 61417DC52525CDDE00E2D55C /* TaskInterception.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskInterception.swift; sourceTree = ""; }; 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 = ""; }; @@ -1668,6 +1734,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 = ""; }; @@ -1721,9 +1789,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; }; @@ -1794,6 +1863,17 @@ ); 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; @@ -1927,6 +2007,7 @@ D2CB6FB027C5217A00A62B57 /* DatadogObjc.framework */, D2CB6FD127C5348200A62B57 /* DatadogCrashReporting.framework */, D2CB6FEC27C5352300A62B57 /* DatadogCrashReportingTests.xctest */, + D240684D27CE6C9E00C04F44 /* Example tvOS.app */, ); name = Products; sourceTree = ""; @@ -2754,9 +2835,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 = ""; @@ -4160,13 +4241,11 @@ 61441BFE24616DE9003D8BB8 /* Sources */, 61441BFF24616DE9003D8BB8 /* Frameworks */, 61441C0024616DE9003D8BB8 /* Resources */, - 61441C5124619499003D8BB8 /* ⚙️ Embed Framework Dependencies */, + D240687A27CF982B00C04F44 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( - 61441C5024619499003D8BB8 /* PBXTargetDependency */, - 6170DC5325C18E57003AED5C /* PBXTargetDependency */, ); name = "Example iOS"; packageProductDependencies = ( @@ -4315,6 +4394,29 @@ 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" */; @@ -4346,6 +4448,7 @@ buildRules = ( ); dependencies = ( + D240686D27CF687200C04F44 /* PBXTargetDependency */, ); name = "DatadogTests tvOS"; productName = DatadogTests; @@ -4404,6 +4507,7 @@ ); dependencies = ( D28D5D5427C53A60008E72D0 /* PBXTargetDependency */, + D240686B27CF686F00C04F44 /* PBXTargetDependency */, ); name = "DatadogCrashReportingTests tvOS"; productName = DatadogCrashReportingTests; @@ -4462,6 +4566,12 @@ CreatedOnToolsVersion = 12.3; TestTargetID = 61441C0124616DE9003D8BB8; }; + D2CB6ED327C520D400A62B57 = { + TestTargetID = D24067F827CE6C9E00C04F44; + }; + D2CB6FD327C5352300A62B57 = { + TestTargetID = D24067F827CE6C9E00C04F44; + }; }; }; buildConfigurationList = 61133B7C242393DE00786299 /* Build configuration list for PBXProject "Datadog" */; @@ -4490,6 +4600,7 @@ 61441C6724619FE4003D8BB8 /* DatadogBenchmarkTests */, 61441C2924616F1D003D8BB8 /* DatadogIntegrationTests */, 61441C0124616DE9003D8BB8 /* Example iOS */, + D24067F827CE6C9E00C04F44 /* Example tvOS */, 6199362A265BA958009D7EA8 /* E2E */, 61993664265BBEDC009D7EA8 /* E2ETests */, 618F983F265BC486009959F8 /* E2EInstrumentationTests */, @@ -4527,15 +4638,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 */, @@ -4595,6 +4706,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D240683327CE6C9E00C04F44 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D240683D27CE6C9E00C04F44 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D2CB6ECA27C50EAE00A62B57 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -5416,6 +5535,22 @@ ); 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; @@ -5860,11 +5995,6 @@ target = 61441C0124616DE9003D8BB8 /* Example iOS */; targetProxy = 61441C2F24616F1D003D8BB8 /* PBXContainerItemProxy */; }; - 61441C5024619499003D8BB8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 61133B81242393DE00786299 /* Datadog iOS */; - targetProxy = 61441C4F24619499003D8BB8 /* PBXContainerItemProxy */; - }; 61441C5A24619A08003D8BB8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 61441C0124616DE9003D8BB8 /* Example iOS */; @@ -5875,11 +6005,6 @@ target = 61441C0124616DE9003D8BB8 /* Example iOS */; targetProxy = 61441C7424619FED003D8BB8 /* PBXContainerItemProxy */; }; - 6170DC5325C18E57003AED5C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 61B7885325C180CB002675B5 /* DatadogCrashReporting iOS */; - targetProxy = 6170DC5225C18E57003AED5C /* PBXContainerItemProxy */; - }; 618F9846265BC486009959F8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 6199362A265BA958009D7EA8 /* E2E */; @@ -5915,6 +6040,31 @@ 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 */; @@ -5933,26 +6083,26 @@ /* 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 = ""; @@ -6320,7 +6470,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; @@ -6340,7 +6490,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; @@ -6360,7 +6510,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; @@ -6885,6 +7035,70 @@ }; name = Integration; }; + 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; + }; + 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; + }; + 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; + }; D2CB6ECE27C50EAE00A62B57 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 61569894256D0E9A00C6AADA /* Base.xcconfig */; @@ -6992,6 +7206,7 @@ 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; }; @@ -7014,6 +7229,7 @@ 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; }; @@ -7036,6 +7252,7 @@ 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; }; @@ -7239,6 +7456,7 @@ 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; }; @@ -7258,6 +7476,7 @@ 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; }; @@ -7277,6 +7496,7 @@ 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; }; @@ -7403,6 +7623,16 @@ 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 = ( diff --git a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme index 504ee8d144..be13d38968 100644 --- a/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme +++ b/Datadog/Datadog.xcodeproj/xcshareddata/xcschemes/DatadogObjc tvOS.xcscheme @@ -138,6 +138,16 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Datadog/Example/AppConfiguration.swift b/Datadog/Example/AppConfiguration.swift index 36cf7645ee..d6a7839ca3 100644 --- a/Datadog/Example/AppConfiguration.swift +++ b/Datadog/Example/AppConfiguration.swift @@ -76,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/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/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/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/Tests/DatadogIntegrationTests/Scenarios/Logging/LoggingCommonAsserts.swift b/Tests/DatadogIntegrationTests/Scenarios/Logging/LoggingCommonAsserts.swift index 1f14b74f44..57203523cb 100644 --- a/Tests/DatadogIntegrationTests/Scenarios/Logging/LoggingCommonAsserts.swift +++ b/Tests/DatadogIntegrationTests/Scenarios/Logging/LoggingCommonAsserts.swift @@ -36,7 +36,7 @@ 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" diff --git a/Tests/DatadogIntegrationTests/Scenarios/RUM/RUMCommonAsserts.swift b/Tests/DatadogIntegrationTests/Scenarios/RUM/RUMCommonAsserts.swift index 1dc0ca3c0d..7c778c8fcd 100644 --- a/Tests/DatadogIntegrationTests/Scenarios/RUM/RUMCommonAsserts.swift +++ b/Tests/DatadogIntegrationTests/Scenarios/RUM/RUMCommonAsserts.swift @@ -36,7 +36,7 @@ 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" diff --git a/Tests/DatadogIntegrationTests/Scenarios/Tracing/TracingCommonAsserts.swift b/Tests/DatadogIntegrationTests/Scenarios/Tracing/TracingCommonAsserts.swift index a832b51565..875531143f 100644 --- a/Tests/DatadogIntegrationTests/Scenarios/Tracing/TracingCommonAsserts.swift +++ b/Tests/DatadogIntegrationTests/Scenarios/Tracing/TracingCommonAsserts.swift @@ -46,7 +46,7 @@ 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" From 4b7e00b6ac101e0b960470a79dd8960b39b05669 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 8 Mar 2022 09:18:26 +0100 Subject: [PATCH 088/104] RUMM-2034 Do not embed CrashReporter.xcframework --- Datadog/Datadog.xcodeproj/project.pbxproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index debb725d19..ff743a5662 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -546,7 +546,6 @@ 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 */; }; - D240685327CF5CE900C04F44 /* CrashReporter.xcframework in ⚙️ Embed Framework Dependencies */ = {isa = PBXBuildFile; fileRef = 614ED36B260352DC00C8C519 /* CrashReporter.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 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, ); }; }; @@ -556,7 +555,6 @@ 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 */; }; - D240687927CF982B00C04F44 /* CrashReporter.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 614ED36B260352DC00C8C519 /* CrashReporter.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 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 */; }; @@ -1154,7 +1152,6 @@ dstSubfolderSpec = 10; files = ( D240685927CF5D0100C04F44 /* DatadogCrashReporting.framework in ⚙️ Embed Framework Dependencies */, - D240685327CF5CE900C04F44 /* CrashReporter.xcframework in ⚙️ Embed Framework Dependencies */, D240685527CF5D0100C04F44 /* Datadog.framework in ⚙️ Embed Framework Dependencies */, D240686027CF5D0100C04F44 /* DatadogObjc.framework in ⚙️ Embed Framework Dependencies */, ); @@ -1168,7 +1165,6 @@ dstSubfolderSpec = 10; files = ( D240687E27CF982D00C04F44 /* DatadogCrashReporting.framework in Embed Frameworks */, - D240687927CF982B00C04F44 /* CrashReporter.xcframework in Embed Frameworks */, D240687C27CF982C00C04F44 /* Datadog.framework in Embed Frameworks */, D240688027CF982F00C04F44 /* DatadogObjc.framework in Embed Frameworks */, ); From 842ffc9321e154dca32c005a52d70c3f0442712b Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Fri, 4 Mar 2022 12:21:30 +0100 Subject: [PATCH 089/104] RUMM-2035 Support tvOS click action with UIKit auto-instrumentation --- .../Debugging/DebugRUMViewController.swift | 1 + .../RUM/DataModels/RUMDataModelsMapping.swift | 1 + .../UIKit/UIKitRUMUserActionsHandler.swift | 70 +++++++++++++------ .../UIKit/UIKitRUMUserActionsPredicate.swift | 28 ++++++++ Sources/Datadog/RUMMonitor.swift | 1 + 5 files changed, 78 insertions(+), 23 deletions(-) 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/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/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandler.swift b/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandler.swift index 57b8f4437c..509a5974d9 100644 --- a/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandler.swift +++ b/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandler.swift @@ -28,17 +28,11 @@ internal class UIKitRUMUserActionsHandler: UIEventHandler { } func notify_sendEvent(application: UIApplication, event: UIEvent) { - guard let tappedView = captureSingleTouch(event: event)?.view else { + guard let command = 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 +42,13 @@ 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) } - // MARK: - Events Filtering + // MARK: - Event Processing - /// Returns the `UITouch` for given `event` only if the event describes the "single tap ended" interaction. - private func captureSingleTouch(event: UIEvent) -> UITouch? { + #if !os(tvOS) + private func command(from event: UIEvent) -> RUMAddUserActionCommand? { guard let allTouches = event.allTouches else { return nil // not a touch event } @@ -71,10 +56,49 @@ 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 + } + guard let view = tap.view, isSafeForPrivacy(view) else { + return nil // no valid view + } + guard let targetView = bestActionTarget(for: view) else { + return nil // Tapped view is not eligible for producing RUM Action + } + guard let action = predicate.rumAction(targetView: targetView) else { + return nil + } + return RUMAddUserActionCommand( + time: dateProvider.currentDate(), + attributes: action.attributes, + actionType: .tap, + name: action.name + ) + } + #else + private 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 tap + return RUMAddUserActionCommand( + time: dateProvider.currentDate(), + attributes: action.attributes, + actionType: .click, + name: action.name + ) } + #endif /// Tells if capturing given `UIView` is safe for the user privacy. private func isSafeForPrivacy(_ view: UIView) -> Bool { diff --git a/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsPredicate.swift b/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsPredicate.swift index 543b7c8045..aa4cb58271 100644 --- a/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsPredicate.swift +++ b/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsPredicate.swift @@ -29,10 +29,19 @@ public struct RUMAction { /// When the app is running, the SDK will ask the implementation of `UIKitRUMUserActionsPredicate` 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 { + #if !os(tvOS) /// 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? + #else + /// 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? + #endif } /// Default implementation of `UIKitRUMUserActionsPredicate`. @@ -40,12 +49,31 @@ public protocol UIKitRUMUserActionsPredicate { public struct DefaultUIKitRUMUserActionsPredicate: UIKitRUMUserActionsPredicate { public init () {} + #if !os(tvOS) public func rumAction(targetView: UIView) -> RUMAction? { return RUMAction( name: targetName(for: targetView), attributes: [:] ) } + #else + 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: [:]) + } + #endif /// Builds the RUM Action's `target` name for given `UIView`. private func targetName(for view: UIView) -> String { diff --git a/Sources/Datadog/RUMMonitor.swift b/Sources/Datadog/RUMMonitor.swift index 18e51abf16..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 From 53b50d4e58ff1be57cec3e200ef54af238d4b7e2 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Fri, 4 Mar 2022 14:24:02 +0100 Subject: [PATCH 090/104] RUMM-2035 Support tvOS click action with SwiftUI --- .../SwiftUI/SwiftUIActionModifier.swift | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift b/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift index e1ed099fd1..9d305eb34c 100644 --- a/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift +++ b/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift @@ -51,6 +51,48 @@ public extension SwiftUI.View { } } +#else + +/// `SwiftUI.ViewModifier` for RUM which invoke `addUserAction` from the +/// global RUM Monitor when the modified view receives a click from the remote control. +@available(tvOS 14, *) +internal struct RUMClickActionModifier: SwiftUI.ViewModifier { + /// The minimum duration of the long press that must elapse before the gesture succeeds. + let minimumDuration: Double + + /// Action Name used for RUM Explorer. + let name: String + + /// Custom attributes to attach to the Action. + let attributes: [AttributeKey: AttributeValue] + + func body(content: Content) -> some View { + content.simultaneousGesture( + LongPressGesture(minimumDuration: minimumDuration).onEnded { _ in + Global.rum.addUserAction(type: .click, name: name, attributes: attributes) + } + ) + } +} + +@available(tvOS 14, *) +public extension SwiftUI.View { + /// Monitor this view tap actions with Datadog RUM. An Action event will be logged after the minimum duration of presss. + /// + /// - Parameters: + /// - name: The action name. + /// - attributes: custom attributes to attach to the View. + /// - minimumDuration: The minimum duration of the long press that must elapse to complete the click action. + /// - Returns: This view after applying a `ViewModifier` for monitoring the view. + func trackRUMClickAction( + name: String, + attributes: [AttributeKey: AttributeValue] = [:], + minimumDuration: Double = 0.01 + ) -> some View { + return modifier(RUMClickActionModifier(minimumDuration: minimumDuration, name: name, attributes: attributes)) + } +} + #endif #endif From 2f90be3597e3dceec0ab6464e340a5d42c2375cd Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 16 Mar 2022 19:25:01 +0100 Subject: [PATCH 091/104] RUMM-2035 Remove empty folder --- Datadog/Datadog.xcodeproj/project.pbxproj | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index ff743a5662..cf21e8c754 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -2790,7 +2790,6 @@ isa = PBXGroup; children = ( D29D5A48273BF7E100A687C1 /* UIKit */, - D29D5A49273BF7F300A687C1 /* SwiftUI */, ); path = Actions; sourceTree = ""; @@ -4090,13 +4089,6 @@ path = UIKit; sourceTree = ""; }; - D29D5A49273BF7F300A687C1 /* SwiftUI */ = { - isa = PBXGroup; - children = ( - ); - path = SwiftUI; - sourceTree = ""; - }; D29D5A4A273BF81500A687C1 /* UIKit */ = { isa = PBXGroup; children = ( From 4958f4bc5958f67e88e78e48a3ce4996886bdfad Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 16 Mar 2022 19:25:29 +0100 Subject: [PATCH 092/104] RUMM-2035 Update SwiftUI documentation --- .../Actions/SwiftUI/SwiftUIActionModifier.swift | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift b/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift index 9d305eb34c..7f7ba0416f 100644 --- a/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift +++ b/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift @@ -57,8 +57,8 @@ public extension SwiftUI.View { /// global RUM Monitor when the modified view receives a click from the remote control. @available(tvOS 14, *) internal struct RUMClickActionModifier: SwiftUI.ViewModifier { - /// The minimum duration of the long press that must elapse before the gesture succeeds. - let minimumDuration: Double + /// The minimum duration in seconds of the long press that must elapse before the gesture succeeds. + let minimumDuration: TimeInterval /// Action Name used for RUM Explorer. let name: String @@ -77,17 +77,19 @@ internal struct RUMClickActionModifier: SwiftUI.ViewModifier { @available(tvOS 14, *) public extension SwiftUI.View { - /// Monitor this view tap actions with Datadog RUM. An Action event will be logged after the minimum duration of presss. + /// Monitor this view tap actions with Datadog RUM. An Action event will be logged after the minimum + /// duration of presss. /// /// - Parameters: /// - name: The action name. /// - attributes: custom attributes to attach to the View. - /// - minimumDuration: The minimum duration of the long press that must elapse to complete the click action. + /// - minimumDuration: The minimum duration in seconds of the long press that must elapse + /// to complete the click action. /// - Returns: This view after applying a `ViewModifier` for monitoring the view. func trackRUMClickAction( name: String, attributes: [AttributeKey: AttributeValue] = [:], - minimumDuration: Double = 0.01 + minimumDuration: TimeInterval = 0.01 ) -> some View { return modifier(RUMClickActionModifier(minimumDuration: minimumDuration, name: name, attributes: attributes)) } From 557604f627e7d453d8762818c9092c1cd01e1623 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 16 Mar 2022 19:27:09 +0100 Subject: [PATCH 093/104] RUMM-2035 Split press and touch predicates and apply changes to objc --- .../UIKit/UIKitRUMUserActionsHandler.swift | 130 +++++----- .../UIKit/UIKitRUMUserActionsPredicate.swift | 52 ++-- Sources/DatadogObjc/RUMMonitor+objc.swift | 45 +++- .../Datadog/Mocks/RUMFeatureMocks.swift | 21 +- .../Mocks/SystemFrameworks/UIKitMocks.swift | 65 ++++- .../UIKitRUMUserActionsHandlerTests.swift | 224 ++++++++++++++++-- .../Datadog/RUMMonitorTests.swift | 9 +- .../DatadogObjc/DDConfigurationTests.swift | 3 +- .../DatadogObjc/DDRUMMonitorTests.swift | 21 +- .../ObjcAPITests/DDConfiguration+apiTests.m | 4 +- 10 files changed, 462 insertions(+), 112 deletions(-) diff --git a/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandler.swift b/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandler.swift index 509a5974d9..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) + } + + convenience init(dateProvider: DateProvider, predicate: UIPressRUMUserActionsPredicate) { + let factory = UIPressCommandFactory(dateProvider: dateProvider, predicate: predicate) + self.init(factory: factory) + } - init(dateProvider: DateProvider, predicate: UIKitRUMUserActionsPredicate) { - self.dateProvider = dateProvider - self.predicate = predicate + init(factory: UIEventCommandFactory) { + self.factory = factory } // MARK: - UIKitRUMUserActionsHandlerType @@ -28,7 +40,7 @@ internal class UIKitRUMUserActionsHandler: UIEventHandler { } func notify_sendEvent(application: UIApplication, event: UIEvent) { - guard let command = command(from: event) else { + guard let command = factory.command(from: event) else { return // Not a "tap" event or doesn't have the view. } @@ -44,11 +56,41 @@ internal class UIKitRUMUserActionsHandler: UIEventHandler { 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 + } +} + +internal struct UITouchCommandFactory: UIEventCommandFactory { + let dateProvider: DateProvider - // MARK: - Event Processing + let predicate: UITouchRUMUserActionsPredicate - #if !os(tvOS) - private func command(from event: UIEvent) -> RUMAddUserActionCommand? { + func command(from event: UIEvent) -> RUMAddUserActionCommand? { guard let allTouches = event.allTouches else { return nil // not a touch event } @@ -74,42 +116,6 @@ internal class UIKitRUMUserActionsHandler: UIEventHandler { name: action.name ) } - #else - private 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 - ) - } - #endif - - /// 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 !NSStringFromClass(type(of: window)).contains("Keyboard") else { - return false // The window class name suggests that it's the on-screen keyboard. - } - return true - } // MARK: - RUM Action Target Capturing @@ -136,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 aa4cb58271..558bae5f33 100644 --- a/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsPredicate.swift +++ b/Sources/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsPredicate.swift @@ -24,39 +24,63 @@ 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 { - #if !os(tvOS) +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? - #else +} + +/// 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? - #endif } /// Default implementation of `UIKitRUMUserActionsPredicate`. /// It names RUM Actions by the `accessibilityIdentifier` or `className` otherwise. -public struct DefaultUIKitRUMUserActionsPredicate: UIKitRUMUserActionsPredicate { +public struct DefaultUIKitRUMUserActionsPredicate { public init () {} - #if !os(tvOS) + /// Builds the RUM Action's `target` name for given `UIView`. + private func targetName(for view: UIView) -> String { + let className = NSStringFromClass(type(of: view)) + + if let accessibilityIdentifier = view.accessibilityIdentifier { + return "\(className)(\(accessibilityIdentifier))" + } else { + return className + } + } +} + +extension DefaultUIKitRUMUserActionsPredicate: UITouchRUMUserActionsPredicate { public func rumAction(targetView: UIView) -> RUMAction? { return RUMAction( name: targetName(for: targetView), attributes: [:] ) } - #else +} + +extension DefaultUIKitRUMUserActionsPredicate: UIPressRUMUserActionsPredicate { public func rumAction(press type: UIPress.PressType, targetView: UIView) -> RUMAction? { var name: String @@ -73,16 +97,4 @@ public struct DefaultUIKitRUMUserActionsPredicate: UIKitRUMUserActionsPredicate return RUMAction(name: name, attributes: [:]) } - #endif - - /// Builds the RUM Action's `target` name for given `UIView`. - private func targetName(for view: UIView) -> String { - let className = NSStringFromClass(type(of: view)) - - if let accessibilityIdentifier = view.accessibilityIdentifier { - return "\(className)(\(accessibilityIdentifier))" - } else { - return className - } - } } diff --git a/Sources/DatadogObjc/RUMMonitor+objc.swift b/Sources/DatadogObjc/RUMMonitor+objc.swift index bf9931f2ee..c313399014 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,30 @@ public class DDRUMAction: NSObject { } } +#if os(tvOS) +public typealias DDUIKitRUMUserActionsPredicate = DDUIPressRUMUserActionsPredicate +#else +public typealias DDUIKitRUMUserActionsPredicate = DDUITouchRUMUserActionsPredicate +#endif + @objc -public protocol DDUIKitRUMUserActionsPredicate: AnyObject { +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/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift b/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift index b23d151adc..2a21ca57b9 100644 --- a/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift @@ -907,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? @@ -920,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/UIKitMocks.swift b/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/UIKitMocks.swift index b80173f2cf..4675a1f446 100644 --- a/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/UIKitMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/UIKitMocks.swift @@ -69,13 +69,29 @@ class UIDeviceMock: UIDevice { } 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 { @@ -88,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? @@ -111,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/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift b/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift index af80547ee9..20ec635559 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,6 +170,7 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { func testItIgnoresSingleTouchEventWithPhaseOtherThanEnded() { // Given + let handler = touchHandler() let view = UIControl().attached(to: mockAppWindow) let ignoredTouchPhases: [UITouch.Phase] @@ -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/RUMMonitorTests.swift b/Tests/DatadogTests/Datadog/RUMMonitorTests.swift index 72c1991ab0..ac690fe5bf 100644 --- a/Tests/DatadogTests/Datadog/RUMMonitorTests.swift +++ b/Tests/DatadogTests/Datadog/RUMMonitorTests.swift @@ -1325,10 +1325,17 @@ class RUMMonitorTests: XCTestCase { let mockWindow = UIWindow(frame: .zero) let mockUIControl = UIControl() mockWindow.addSubview(mockUIControl) + + userActionsHandler.notify_sendEvent( + application: .shared, + event: .mockWith(touch: .mockWith(view: mockUIControl)) + ) + userActionsHandler.notify_sendEvent( application: .shared, - event: .mockWith(touches: [.mockWith(phase: .ended, view: mockUIControl)]) + event: .mockWith(press: .mockWith(view: mockUIControl)) ) + XCTAssertEqual(output.recordedLog?.status, .warn) XCTAssertEqual( output.recordedLog?.message, diff --git a/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift b/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift index a3f83c9da8..454de3806b 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: 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..51b773afb3 100644 --- a/Tests/DatadogTests/DatadogObjc/ObjcAPITests/DDConfiguration+apiTests.m +++ b/Tests/DatadogTests/DatadogObjc/ObjcAPITests/DDConfiguration+apiTests.m @@ -25,11 +25,13 @@ - (DDRUMView * _Nullable)rumViewFor:(UIViewController * _Nonnull)viewController @interface CustomDDUIKitRUMUserActionsPredicate: NSObject @end -@interface CustomDDUIKitRUMUserActionsPredicate () +@interface CustomDDUIKitRUMUserActionsPredicate () @end @implementation CustomDDUIKitRUMUserActionsPredicate - (DDRUMAction * _Nullable)rumActionWithTargetView:(UIView * _Nonnull)targetView { return nil; } +- (DDRUMAction * _Nullable)rumActionWithPress:(enum UIPressType)type targetView:(UIView * _Nonnull)targetView { return nil; } + @end // MARK: - Tests From 20c4af99e664f9a38a207df54264004735ef8a16 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Wed, 16 Mar 2022 19:55:25 +0100 Subject: [PATCH 094/104] RUMM-2035 Remove objc typealias --- Sources/DatadogObjc/RUMMonitor+objc.swift | 6 ++++-- Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift | 2 +- .../DatadogObjc/ObjcAPITests/DDConfiguration+apiTests.m | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Sources/DatadogObjc/RUMMonitor+objc.swift b/Sources/DatadogObjc/RUMMonitor+objc.swift index c313399014..6692c0367d 100644 --- a/Sources/DatadogObjc/RUMMonitor+objc.swift +++ b/Sources/DatadogObjc/RUMMonitor+objc.swift @@ -101,9 +101,11 @@ public class DDRUMAction: NSObject { } #if os(tvOS) -public typealias DDUIKitRUMUserActionsPredicate = DDUIPressRUMUserActionsPredicate +@objc +public protocol DDUIKitRUMUserActionsPredicate: DDUIPressRUMUserActionsPredicate {} #else -public typealias DDUIKitRUMUserActionsPredicate = DDUITouchRUMUserActionsPredicate +@objc +public protocol DDUIKitRUMUserActionsPredicate: DDUITouchRUMUserActionsPredicate {} #endif @objc diff --git a/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift b/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift index 454de3806b..d5502b4b29 100644 --- a/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift +++ b/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift @@ -149,7 +149,7 @@ class DDConfigurationTests: XCTestCase { objcBuilder.trackUIKitRUMViews(using: viewPredicate) XCTAssertTrue((objcBuilder.build().sdkConfiguration.rumUIKitViewsPredicate as? UIKitRUMViewsPredicateBridge)?.objcPredicate === viewPredicate) - class ObjCActionPredicate: DDUITouchRUMUserActionsPredicate & DDUIPressRUMUserActionsPredicate { + class ObjCActionPredicate: DDUIKitRUMUserActionsPredicate & DDUITouchRUMUserActionsPredicate & DDUIPressRUMUserActionsPredicate { func rumAction(targetView: UIView) -> DDRUMAction? { nil } func rumAction(press type: UIPress.PressType, targetView: UIView) -> DDRUMAction? { nil } } diff --git a/Tests/DatadogTests/DatadogObjc/ObjcAPITests/DDConfiguration+apiTests.m b/Tests/DatadogTests/DatadogObjc/ObjcAPITests/DDConfiguration+apiTests.m index 51b773afb3..30d1d9dcd0 100644 --- a/Tests/DatadogTests/DatadogObjc/ObjcAPITests/DDConfiguration+apiTests.m +++ b/Tests/DatadogTests/DatadogObjc/ObjcAPITests/DDConfiguration+apiTests.m @@ -25,7 +25,7 @@ - (DDRUMView * _Nullable)rumViewFor:(UIViewController * _Nonnull)viewController @interface CustomDDUIKitRUMUserActionsPredicate: NSObject @end -@interface CustomDDUIKitRUMUserActionsPredicate () +@interface CustomDDUIKitRUMUserActionsPredicate () @end @implementation CustomDDUIKitRUMUserActionsPredicate From 849b94dccc140d88bf92dd77f4ba952a005130d1 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Fri, 18 Mar 2022 12:31:24 +0100 Subject: [PATCH 095/104] RUMM-2035 Remove SwiftUI click instrumentation on tvOS --- .../SwiftUI/SwiftUIActionModifier.swift | 46 ------------------- 1 file changed, 46 deletions(-) diff --git a/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift b/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift index 7f7ba0416f..820232fa64 100644 --- a/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift +++ b/Sources/Datadog/RUM/Instrumentation/Actions/SwiftUI/SwiftUIActionModifier.swift @@ -7,7 +7,6 @@ #if canImport(SwiftUI) import SwiftUI -// TODO: RUMM-2035 Enable SwiftUI tap action on tvOS #if !os(tvOS) /// `SwiftUI.ViewModifier` for RUM which invoke `addUserAction` from the @@ -51,50 +50,5 @@ public extension SwiftUI.View { } } -#else - -/// `SwiftUI.ViewModifier` for RUM which invoke `addUserAction` from the -/// global RUM Monitor when the modified view receives a click from the remote control. -@available(tvOS 14, *) -internal struct RUMClickActionModifier: SwiftUI.ViewModifier { - /// The minimum duration in seconds of the long press that must elapse before the gesture succeeds. - let minimumDuration: TimeInterval - - /// Action Name used for RUM Explorer. - let name: String - - /// Custom attributes to attach to the Action. - let attributes: [AttributeKey: AttributeValue] - - func body(content: Content) -> some View { - content.simultaneousGesture( - LongPressGesture(minimumDuration: minimumDuration).onEnded { _ in - Global.rum.addUserAction(type: .click, name: name, attributes: attributes) - } - ) - } -} - -@available(tvOS 14, *) -public extension SwiftUI.View { - /// Monitor this view tap actions with Datadog RUM. An Action event will be logged after the minimum - /// duration of presss. - /// - /// - Parameters: - /// - name: The action name. - /// - attributes: custom attributes to attach to the View. - /// - minimumDuration: The minimum duration in seconds of the long press that must elapse - /// to complete the click action. - /// - Returns: This view after applying a `ViewModifier` for monitoring the view. - func trackRUMClickAction( - name: String, - attributes: [AttributeKey: AttributeValue] = [:], - minimumDuration: TimeInterval = 0.01 - ) -> some View { - return modifier(RUMClickActionModifier(minimumDuration: minimumDuration, name: name, attributes: attributes)) - } -} - #endif - #endif From 5b4c857fcf93475a9389f322794aeb68fe82571e Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Mon, 21 Mar 2022 10:16:42 +0100 Subject: [PATCH 096/104] RUMM-2035 Rename test Co-authored-by: Maciek Grzybowski --- .../Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift b/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift index 20ec635559..49aceee619 100644 --- a/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/Instrumentation/Actions/UIKit/UIKitRUMUserActionsHandlerTests.swift @@ -226,7 +226,7 @@ class UIKitRUMUserActionsHandlerTests: XCTestCase { XCTAssertNil(commandSubscriber.lastReceivedCommand) } - func testGivenTouchEvent_ItAppliesUserAttributesAndCustomName() { + func testGivenTouchEvent_itAppliesUserAttributesAndCustomName() { // Given let mockAttributes: [AttributeKey: AttributeValue] = mockRandomAttributes() let handler = touchHandler( From 25dfab75a1a30a2f8efb917064c783aa9ff95963 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Mon, 21 Mar 2022 17:30:14 +0100 Subject: [PATCH 097/104] RUMM-2054 Build and validate xcframework with tvos slices --- tools/distribution/release.py | 6 +- .../src/release/assets/gh_asset.py | 156 +++++++++++++----- tools/distribution/src/release/semver.py | 3 + 3 files changed, 120 insertions(+), 45 deletions(-) diff --git a/tools/distribution/release.py b/tools/distribution/release.py index a2fb247c9b..34f3992dfe 100755 --- a/tools/distribution/release.py +++ b/tools/distribution/release.py @@ -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/src/release/assets/gh_asset.py b/tools/distribution/src/release/assets/gh_asset.py index fff6c6e66f..417cf6620f 100644 --- a/tools/distribution/src/release/assets/gh_asset.py +++ b/tools/distribution/src/release/assets/gh_asset.py @@ -14,25 +14,25 @@ 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/release/semver.py b/tools/distribution/src/release/semver.py index 3608da2ccc..9cf185744e 100644 --- a/tools/distribution/src/release/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) From 780e121bd5a297d7bea88a30239bb613a78a6c84 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Mon, 28 Mar 2022 20:25:24 +0200 Subject: [PATCH 098/104] RUMM-1651 Add CI Test integration to tvOS --- Datadog/Datadog.xcodeproj/project.pbxproj | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index cf21e8c754..86cba2396f 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -740,7 +740,7 @@ 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 /* EnvironmentSpanIntegration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E13A880B257922EC004FB174 /* EnvironmentSpanIntegration.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 */; }; @@ -979,6 +979,8 @@ 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 */; }; @@ -1171,17 +1173,6 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; - D2CB6FF227C5365A00A62B57 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - D2CB6FEF27C5365A00A62B57 /* Datadog.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -5544,6 +5535,7 @@ 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 */, @@ -5709,7 +5701,7 @@ D2CB6EB327C50EAE00A62B57 /* KronosNTPClient.swift in Sources */, D2CB6EB427C50EAE00A62B57 /* VitalInfoSampler.swift in Sources */, D2CB6EB527C50EAE00A62B57 /* VitalRefreshRateReader.swift in Sources */, - D2CB6EB627C50EAE00A62B57 /* EnvironmentSpanIntegration.swift in Sources */, + D2CB6EB627C50EAE00A62B57 /* (null) in Sources */, D2CB6EB727C50EAE00A62B57 /* URLSessionTracingHandler.swift in Sources */, D2CB6EB827C50EAE00A62B57 /* RUMEventSanitizer.swift in Sources */, D2CB6EB927C50EAE00A62B57 /* DDError.swift in Sources */, @@ -5746,6 +5738,7 @@ 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 */, From 8bb9aabcbe82c73b42692f5f6318e35b06a8c61a Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Mon, 28 Mar 2022 20:31:55 +0200 Subject: [PATCH 099/104] RUMM-1651 Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0d828fccf..b8752fd9e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Unreleased * [FEATURE] Web-view tracking. See [#729][] +* [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][] @@ -326,6 +327,7 @@ [#728]: https://github.com/DataDog/dd-sdk-ios/issues/728 [#729]: https://github.com/DataDog/dd-sdk-ios/issues/729 [#789]: https://github.com/DataDog/dd-sdk-ios/issues/789 +[#793]: https://github.com/DataDog/dd-sdk-ios/issues/793 [@00FA9A]: https://github.com/00FA9A [@Britton-Earnin]: https://github.com/Britton-Earnin [@Hengyu]: https://github.com/Hengyu From a93d2956c23bacdd1a9688cba009f93d925cd0fd Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Mon, 28 Mar 2022 14:50:51 +0200 Subject: [PATCH 100/104] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8752fd9e0..c57e8df7ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # 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][] @@ -326,6 +327,7 @@ [#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 [@00FA9A]: https://github.com/00FA9A @@ -352,4 +354,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 From 49c4c3a0089feaaa70eb807dd60bb84b79156a8a Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Tue, 29 Mar 2022 15:42:55 +0200 Subject: [PATCH 101/104] RUMM-2025 Filter out unrecognized trailing stack frame in `error.stack` (only if the frame has no library base address read). --- .../DDCrashReportExporter.swift | 19 +++++++- .../DDCrashReportExporterTests.swift | 43 +++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) 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/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() { From 5e7e5ed5303604c1d6981cc1325e6c339a00dd99 Mon Sep 17 00:00:00 2001 From: Maciek Grzybowski Date: Tue, 29 Mar 2022 15:58:01 +0200 Subject: [PATCH 102/104] RUMM-2025 Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8752fd9e0..9b5f53b083 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * [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][] +* [IMPROVEMENT] Crash Reporting: Filter out unrecognized trailing `???` stack frame in `error.stack`. See [#794][] # 1.9.0 / 01-26-2022 @@ -328,6 +329,7 @@ [#729]: https://github.com/DataDog/dd-sdk-ios/issues/729 [#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 [@00FA9A]: https://github.com/00FA9A [@Britton-Earnin]: https://github.com/Britton-Earnin [@Hengyu]: https://github.com/Hengyu From dcc9151d2a6e407ed19ab442c4fa50ac03edd83b Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 29 Mar 2022 17:12:25 +0200 Subject: [PATCH 103/104] RUMM-2091 Fix log event srubbing signature --- Sources/Datadog/DatadogConfiguration.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Datadog/DatadogConfiguration.swift b/Sources/Datadog/DatadogConfiguration.swift index c018613ac2..f55693dee6 100644 --- a/Sources/Datadog/DatadogConfiguration.swift +++ b/Sources/Datadog/DatadogConfiguration.swift @@ -406,7 +406,7 @@ extension Datadog { /// - Parameter mapper: the closure taking `LogEvent` as input and expecting `LogEvent` as output. /// The implementation should obtain a mutable version of the `LogEvent`, modify it and return it. Returning `nil` will result /// with dropping the Log event entirely, so it won't be send to Datadog. - public func setLogEventMapper(_ mapper: @escaping (LogEvent) -> LogEvent) -> Builder { + public func setLogEventMapper(_ mapper: @escaping (LogEvent) -> LogEvent?) -> Builder { configuration.logEventMapper = mapper return self } From a8b92c852521e8995fe58c6465e910a011221810 Mon Sep 17 00:00:00 2001 From: Maxime Epain Date: Tue, 29 Mar 2022 17:15:19 +0200 Subject: [PATCH 104/104] RUMM-2091 Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b5f53b083..95e78ebace 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * [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 @@ -330,6 +331,7 @@ [#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