@datadog/mobile-react-native-webview 2.4.4 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/DatadogSDKReactNativeWebView.podspec +46 -0
  2. package/android/build.gradle +249 -0
  3. package/android/detekt.yml +572 -0
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/AndroidManifest.xml +11 -0
  6. package/android/src/newarch/com/datadog/reactnative/webview/DdSdkReactNativeWebViewPackage.kt +35 -0
  7. package/android/src/oldarch/com/datadog/reactnative/webview/DdSdkReactNativeWebViewManager.kt +112 -0
  8. package/android/src/oldarch/com/datadog/reactnative/webview/DdSdkReactNativeWebViewPackage.kt +36 -0
  9. package/android/src/test/kotlin/com/datadog/reactnative/tools/unit/GenericAssert.kt +18 -0
  10. package/android/src/test/kotlin/com/datadog/reactnative/webview/DatadogWebViewTest.kt +126 -0
  11. package/android/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +1 -0
  12. package/ios/DatadogSDKReactNativeWebView.xcodeproj/project.pbxproj +272 -0
  13. package/ios/DatadogSDKReactNativeWebView.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
  14. package/ios/Sources/DatadogSDKReactNativeWebView.h +12 -0
  15. package/ios/Sources/RCTDatadogWebView.h +21 -0
  16. package/ios/Sources/RCTDatadogWebView.mm +53 -0
  17. package/ios/Sources/RCTDatadogWebViewManager.h +10 -0
  18. package/ios/Sources/RCTDatadogWebViewManager.mm +84 -0
  19. package/ios/Sources/RCTDatadogWebViewTracking.swift +67 -0
  20. package/lib/commonjs/ext-specs/NativeDdLogs.js +19 -0
  21. package/lib/commonjs/ext-specs/NativeDdLogs.js.map +1 -0
  22. package/lib/commonjs/ext-specs/NativeDdSdk.js.map +1 -0
  23. package/lib/commonjs/index.js +40 -7
  24. package/lib/commonjs/index.js.map +1 -1
  25. package/lib/commonjs/specs/NativeDdWebView.js +16 -0
  26. package/lib/commonjs/specs/NativeDdWebView.js.map +1 -0
  27. package/lib/commonjs/utils/env-utils.js +17 -0
  28. package/lib/commonjs/utils/env-utils.js.map +1 -0
  29. package/lib/commonjs/utils/webview-js-utils.js +124 -0
  30. package/lib/commonjs/utils/webview-js-utils.js.map +1 -0
  31. package/lib/module/ext-specs/NativeDdLogs.js +17 -0
  32. package/lib/module/ext-specs/NativeDdLogs.js.map +1 -0
  33. package/lib/module/ext-specs/NativeDdSdk.js.map +1 -0
  34. package/lib/module/index.js +39 -7
  35. package/lib/module/index.js.map +1 -1
  36. package/lib/module/specs/NativeDdWebView.js +11 -0
  37. package/lib/module/specs/NativeDdWebView.js.map +1 -0
  38. package/lib/module/utils/env-utils.js +10 -0
  39. package/lib/module/utils/env-utils.js.map +1 -0
  40. package/lib/module/utils/webview-js-utils.js +115 -0
  41. package/lib/module/utils/webview-js-utils.js.map +1 -0
  42. package/lib/typescript/ext-specs/NativeDdLogs.d.ts +16 -0
  43. package/lib/typescript/ext-specs/NativeDdLogs.d.ts.map +1 -0
  44. package/lib/typescript/ext-specs/NativeDdSdk.d.ts.map +1 -0
  45. package/lib/typescript/index.d.ts +20 -0
  46. package/lib/typescript/index.d.ts.map +1 -1
  47. package/lib/typescript/specs/NativeDdWebView.d.ts +4 -0
  48. package/lib/typescript/specs/NativeDdWebView.d.ts.map +1 -0
  49. package/lib/typescript/utils/env-utils.d.ts +2 -0
  50. package/lib/typescript/utils/env-utils.d.ts.map +1 -0
  51. package/lib/typescript/utils/webview-js-utils.d.ts +34 -0
  52. package/lib/typescript/utils/webview-js-utils.d.ts.map +1 -0
  53. package/package.json +22 -4
  54. package/src/__tests__/WebviewDatadog.test.tsx +39 -43
  55. package/src/__tests__/WebviewDatadogInjectedJS.test.tsx +200 -1
  56. package/src/__tests__/WebviewDatadogPerformance.test.tsx +12 -0
  57. package/src/__tests__/__utils__/string-utils.ts +13 -0
  58. package/src/__tests__/webview-js-utils.test.ts +51 -0
  59. package/src/ext-specs/NativeDdLogs.ts +25 -0
  60. package/src/{NativeDdSdk.ts → ext-specs/NativeDdSdk.ts} +1 -0
  61. package/src/index.tsx +70 -13
  62. package/src/specs/NativeDdWebView.ts +16 -0
  63. package/src/utils/env-utils.ts +9 -0
  64. package/src/utils/webview-js-utils.ts +150 -0
  65. package/lib/commonjs/NativeDdSdk.js.map +0 -1
  66. package/lib/commonjs/__utils__/formatAllowedHosts.js +0 -65
  67. package/lib/commonjs/__utils__/formatAllowedHosts.js.map +0 -1
  68. package/lib/commonjs/__utils__/getInjectedJavaScriptBeforeContentLoaded.js +0 -32
  69. package/lib/commonjs/__utils__/getInjectedJavaScriptBeforeContentLoaded.js.map +0 -1
  70. package/lib/module/NativeDdSdk.js.map +0 -1
  71. package/lib/module/__utils__/formatAllowedHosts.js +0 -58
  72. package/lib/module/__utils__/formatAllowedHosts.js.map +0 -1
  73. package/lib/module/__utils__/getInjectedJavaScriptBeforeContentLoaded.js +0 -24
  74. package/lib/module/__utils__/getInjectedJavaScriptBeforeContentLoaded.js.map +0 -1
  75. package/lib/typescript/NativeDdSdk.d.ts.map +0 -1
  76. package/lib/typescript/__utils__/formatAllowedHosts.d.ts +0 -2
  77. package/lib/typescript/__utils__/formatAllowedHosts.d.ts.map +0 -1
  78. package/lib/typescript/__utils__/getInjectedJavaScriptBeforeContentLoaded.d.ts +0 -3
  79. package/lib/typescript/__utils__/getInjectedJavaScriptBeforeContentLoaded.d.ts.map +0 -1
  80. package/src/__tests__/formatAllowedHosts.test.ts +0 -40
  81. package/src/__tests__/getInjectedJavaScriptBeforeContentLoaded.test.ts +0 -86
  82. package/src/__utils__/formatAllowedHosts.ts +0 -70
  83. package/src/__utils__/getInjectedJavaScriptBeforeContentLoaded.ts +0 -29
  84. /package/lib/commonjs/{NativeDdSdk.js → ext-specs/NativeDdSdk.js} +0 -0
  85. /package/lib/module/{NativeDdSdk.js → ext-specs/NativeDdSdk.js} +0 -0
  86. /package/lib/typescript/{NativeDdSdk.d.ts → ext-specs/NativeDdSdk.d.ts} +0 -0
@@ -0,0 +1,112 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ package com.datadog.reactnative.webview
8
+
9
+ import android.annotation.SuppressLint
10
+ import com.datadog.android.api.SdkCore
11
+ import com.datadog.android.webview.WebViewTracking
12
+ import com.datadog.reactnative.DatadogSDKWrapperStorage
13
+ import com.facebook.react.bridge.ReactContext
14
+ import com.facebook.react.bridge.ReadableArray
15
+ import com.facebook.react.uimanager.ThemedReactContext
16
+ import com.facebook.react.uimanager.annotations.ReactProp
17
+ import com.reactnativecommunity.webview.RNCWebView
18
+ import com.reactnativecommunity.webview.RNCWebViewClient
19
+ import com.reactnativecommunity.webview.RNCWebViewManager
20
+ import com.reactnativecommunity.webview.RNCWebViewWrapper
21
+
22
+ /**
23
+ * The entry point to use Datadog auto-instrumented WebView feature.
24
+ */
25
+ class DdSdkReactNativeWebViewManager(
26
+ private val reactContext: ReactContext
27
+ ) : RNCWebViewManager() {
28
+ // The name used to reference this custom View from React Native.
29
+ companion object {
30
+ const val VIEW_NAME = "DdReactNativeWebView"
31
+ }
32
+
33
+ /**
34
+ * The instance of Datadog SDK Core.
35
+ */
36
+ @Volatile private var _datadogCore: SdkCore? = null
37
+ val datadogCore: SdkCore?
38
+ get() = _datadogCore
39
+
40
+ /**
41
+ * Whether WebView tracking has been enabled or not.
42
+ */
43
+ @Volatile private var _isWebViewTrackingEnabled: Boolean = false
44
+ val isWebViewTrackingEnabled: Boolean
45
+ get() = _isWebViewTrackingEnabled
46
+
47
+ init {
48
+ DatadogSDKWrapperStorage.addOnInitializedListener { core ->
49
+ _datadogCore = core
50
+ }
51
+ }
52
+
53
+ // The Custom WebView exposed properties.
54
+ @ReactProp(name = "allowedHosts")
55
+ fun setAllowedHosts(view: RNCWebViewWrapper, allowedHosts: ReadableArray) {
56
+ // TODO: RUM-7218 (Log failures w Telemetry)
57
+ val webView = view.webView as? RNCWebView ?: return
58
+ val datadogCore = _datadogCore
59
+ val hosts = toStringList(allowedHosts)
60
+ if (datadogCore != null) {
61
+ this.enableWebViewTracking(webView, datadogCore, hosts)
62
+ } else {
63
+ DatadogSDKWrapperStorage.addOnInitializedListener { core ->
64
+ reactContext.runOnUiQueueThread {
65
+ this.enableWebViewTracking(webView, core, hosts)
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ @SuppressLint("SetJavaScriptEnabled")
72
+ override fun createViewInstance(context: ThemedReactContext): RNCWebViewWrapper {
73
+ val webView = RNCWebView(context)
74
+ webView.settings.javaScriptEnabled = true
75
+ return super.createViewInstance(context, webView)
76
+ }
77
+
78
+ override fun addEventEmitters(
79
+ reactContext: ThemedReactContext,
80
+ view: RNCWebViewWrapper
81
+ ) {
82
+ view.webView.webViewClient = RNCWebViewClient()
83
+ }
84
+
85
+ private fun toStringList(props: ReadableArray): List<String> {
86
+ return props.toArrayList().filterIsInstance<String>()
87
+ }
88
+
89
+ // Utility function to enable WebView tracking
90
+ private fun enableWebViewTracking(
91
+ webView: RNCWebView,
92
+ sdkCore: SdkCore,
93
+ allowedHosts: List<String>
94
+ ) {
95
+ if (_isWebViewTrackingEnabled) {
96
+ return
97
+ }
98
+
99
+ WebViewTracking.enable(
100
+ webView,
101
+ allowedHosts = allowedHosts,
102
+ sdkCore = sdkCore
103
+ )
104
+
105
+ _isWebViewTrackingEnabled = true
106
+ }
107
+
108
+ // The name used to reference this custom View from React Native.
109
+ override fun getName(): String {
110
+ return VIEW_NAME
111
+ }
112
+ }
@@ -0,0 +1,36 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ package com.datadog.reactnative.webview
8
+
9
+ import com.facebook.react.TurboReactPackage
10
+ import com.facebook.react.bridge.NativeModule
11
+ import com.facebook.react.bridge.ReactApplicationContext
12
+ import com.facebook.react.module.model.ReactModuleInfo
13
+ import com.facebook.react.module.model.ReactModuleInfoProvider
14
+ import com.facebook.react.uimanager.ViewManager
15
+
16
+ class DdSdkReactNativeWebViewPackage : TurboReactPackage() {
17
+ override fun createViewManagers(
18
+ reactContext: ReactApplicationContext
19
+ ): MutableList<ViewManager<*, *>> {
20
+ return mutableListOf(
21
+ DdSdkReactNativeWebViewManager(
22
+ reactContext
23
+ )
24
+ )
25
+ }
26
+
27
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
28
+ return null
29
+ }
30
+
31
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
32
+ return ReactModuleInfoProvider {
33
+ mapOf<String, ReactModuleInfo>()
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,18 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ package com.datadog.reactnative.tools.unit
8
+
9
+ import org.assertj.core.api.AbstractAssert
10
+
11
+ class GenericAssert(actual: Any?) :
12
+ AbstractAssert<GenericAssert, Any>(actual, GenericAssert::class.java) {
13
+ companion object {
14
+ fun assertThat(actual: Any?): GenericAssert {
15
+ return GenericAssert(actual)
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,126 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ package com.datadog.reactnative.webview
8
+
9
+ import com.datadog.android.api.SdkCore
10
+ import com.datadog.android.core.InternalSdkCore
11
+ import com.datadog.android.webview.WebViewTracking
12
+ import com.datadog.reactnative.DatadogSDKWrapperStorage
13
+ import com.datadog.reactnative.tools.unit.GenericAssert.Companion.assertThat
14
+ import com.facebook.react.bridge.JavaOnlyArray
15
+ import com.facebook.react.uimanager.ThemedReactContext
16
+ import com.reactnativecommunity.webview.RNCWebView
17
+ import com.reactnativecommunity.webview.RNCWebViewWrapper
18
+ import org.junit.jupiter.api.AfterEach
19
+ import org.junit.jupiter.api.BeforeEach
20
+ import org.junit.jupiter.api.Test
21
+ import org.junit.jupiter.api.extension.ExtendWith
22
+ import org.junit.jupiter.api.extension.Extensions
23
+ import org.mockito.Mock
24
+ import org.mockito.MockedStatic
25
+ import org.mockito.Mockito
26
+ import org.mockito.Mockito.mock
27
+ import org.mockito.junit.jupiter.MockitoExtension
28
+ import org.mockito.junit.jupiter.MockitoSettings
29
+ import org.mockito.kotlin.any
30
+ import org.mockito.kotlin.doReturn
31
+ import org.mockito.kotlin.verify
32
+ import org.mockito.kotlin.whenever
33
+ import org.mockito.quality.Strictness
34
+
35
+ @Extensions(
36
+ ExtendWith(MockitoExtension::class)
37
+ )
38
+ @MockitoSettings(strictness = Strictness.LENIENT)
39
+ internal class DatadogWebViewTest {
40
+
41
+ @Mock
42
+ lateinit var themedReactContext: ThemedReactContext
43
+
44
+ @Mock
45
+ lateinit var datadogCore: InternalSdkCore
46
+
47
+ private lateinit var webViewTrackingMockedStatic: MockedStatic<WebViewTracking>
48
+
49
+ @BeforeEach
50
+ fun `set up`() {
51
+ whenever(themedReactContext.runOnUiQueueThread(any())).thenAnswer { answer ->
52
+ answer.getArgument<Runnable>(0).run()
53
+ true
54
+ }
55
+
56
+ webViewTrackingMockedStatic = Mockito.mockStatic(WebViewTracking::class.java)
57
+ webViewTrackingMockedStatic.`when`<Unit> {
58
+ WebViewTracking.enable(
59
+ webView = any(), // Mock the WebView parameter
60
+ allowedHosts = any(), // Mock the list of allowed hosts
61
+ logsSampleRate = any(), // Mock the logsSampleRate parameter
62
+ sdkCore = any() // Mock the SdkCore parameter
63
+ )
64
+ }.then {} // Return Unit as the function has no return value
65
+ }
66
+
67
+ @AfterEach
68
+ fun `tear down`() {
69
+ webViewTrackingMockedStatic.close()
70
+ }
71
+
72
+ @Test
73
+ fun `Datadog Core is set once initialized`() {
74
+ val manager = DdSdkReactNativeWebViewManager(themedReactContext)
75
+ assertThat(manager.datadogCore).isNull()
76
+
77
+ DatadogSDKWrapperStorage.notifyOnInitializedListeners(datadogCore)
78
+
79
+ assertThat(manager.datadogCore).isNotNull()
80
+ assertThat(manager.datadogCore).isInstanceOf(SdkCore::class.java)
81
+ }
82
+
83
+ @Test
84
+ fun `Registers to SdkCore listener if the SDK is not initialized`() {
85
+ // =========
86
+ // Given
87
+ // =========
88
+ val manager = DdSdkReactNativeWebViewManager(themedReactContext)
89
+
90
+ // When first initialized, the WebView manager core should be null
91
+ assertThat(manager.datadogCore).isNull()
92
+
93
+ // When first initialized, the WebView tracking should be disabled
94
+ assertThat(manager.isWebViewTrackingEnabled).isEqualTo(false)
95
+
96
+ // =========
97
+ // When
98
+ // =========
99
+ val rncWebView = mock(RNCWebView::class.java)
100
+ val rncWebViewWrapper = mock(RNCWebViewWrapper::class.java)
101
+ whenever(rncWebViewWrapper.webView) doReturn rncWebView
102
+
103
+ // When tracking is enabled with a null core...
104
+ val allowedHosts = JavaOnlyArray()
105
+ allowedHosts.pushString("example.com")
106
+ manager.setAllowedHosts(rncWebViewWrapper, allowedHosts)
107
+
108
+ // =========
109
+ // Then
110
+ // =========
111
+
112
+ // When we notify listeners that the core is available...
113
+ DatadogSDKWrapperStorage.notifyOnInitializedListeners(datadogCore)
114
+
115
+ // ...the WebView should enable WebView tracking in the UI Thread.
116
+ verify(themedReactContext).runOnUiQueueThread(any())
117
+
118
+ // Native WebView tracking should be called
119
+ webViewTrackingMockedStatic.verify {
120
+ WebViewTracking.enable(rncWebView, listOf("example.com"), 100.0f, datadogCore)
121
+ }
122
+
123
+ // At this point 'isWebViewTrackingEnabled' should be true.
124
+ assertThat(manager.isWebViewTrackingEnabled).isEqualTo(true)
125
+ }
126
+ }
@@ -0,0 +1,272 @@
1
+ // !$*UTF8*$!
2
+ {
3
+ archiveVersion = 1;
4
+ classes = {
5
+ };
6
+ objectVersion = 46;
7
+ objects = {
8
+
9
+ /* Begin PBXCopyFilesBuildPhase section */
10
+ 58B511D91A9E6C8500147676 /* CopyFiles */ = {
11
+ isa = PBXCopyFilesBuildPhase;
12
+ buildActionMask = 2147483647;
13
+ dstPath = "include/$(PRODUCT_NAME)";
14
+ dstSubfolderSpec = 16;
15
+ files = (
16
+ );
17
+ runOnlyForDeploymentPostprocessing = 0;
18
+ };
19
+ /* End PBXCopyFilesBuildPhase section */
20
+
21
+ /* Begin PBXFileReference section */
22
+ 134814201AA4EA6300B7C361 /* libDatadogSDKReactNativeWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libDatadogSDKReactNativeWebView.a; sourceTree = BUILT_PRODUCTS_DIR; };
23
+ F625545A26A82D430033052D /* Sources */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Sources; sourceTree = "<group>"; };
24
+ F625545B26A82D430033052D /* Tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Tests; sourceTree = "<group>"; };
25
+ /* End PBXFileReference section */
26
+
27
+ /* Begin PBXFrameworksBuildPhase section */
28
+ 58B511D81A9E6C8500147676 /* Frameworks */ = {
29
+ isa = PBXFrameworksBuildPhase;
30
+ buildActionMask = 2147483647;
31
+ files = (
32
+ );
33
+ runOnlyForDeploymentPostprocessing = 0;
34
+ };
35
+ /* End PBXFrameworksBuildPhase section */
36
+
37
+ /* Begin PBXGroup section */
38
+ 134814211AA4EA7D00B7C361 /* Products */ = {
39
+ isa = PBXGroup;
40
+ children = (
41
+ 134814201AA4EA6300B7C361 /* libDatadogSDKReactNativeWebView.a */,
42
+ );
43
+ name = Products;
44
+ sourceTree = "<group>";
45
+ };
46
+ 58B511D21A9E6C8500147676 = {
47
+ isa = PBXGroup;
48
+ children = (
49
+ F625545A26A82D430033052D /* Sources */,
50
+ F625545B26A82D430033052D /* Tests */,
51
+ 134814211AA4EA7D00B7C361 /* Products */,
52
+ );
53
+ sourceTree = "<group>";
54
+ };
55
+ /* End PBXGroup section */
56
+
57
+ /* Begin PBXNativeTarget section */
58
+ 58B511DA1A9E6C8500147676 /* DatadogSDKReactNativeWebView */ = {
59
+ isa = PBXNativeTarget;
60
+ buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "DatadogSDKReactNativeWebView" */;
61
+ buildPhases = (
62
+ 58B511D71A9E6C8500147676 /* Sources */,
63
+ 58B511D81A9E6C8500147676 /* Frameworks */,
64
+ 58B511D91A9E6C8500147676 /* CopyFiles */,
65
+ );
66
+ buildRules = (
67
+ );
68
+ dependencies = (
69
+ );
70
+ name = DatadogSDKReactNativeWebView;
71
+ productName = RCTDataManager;
72
+ productReference = 134814201AA4EA6300B7C361 /* libDatadogSDKReactNativeWebView.a */;
73
+ productType = "com.apple.product-type.library.static";
74
+ };
75
+ /* End PBXNativeTarget section */
76
+
77
+ /* Begin PBXProject section */
78
+ 58B511D31A9E6C8500147676 /* Project object */ = {
79
+ isa = PBXProject;
80
+ attributes = {
81
+ LastUpgradeCheck = 0920;
82
+ ORGANIZATIONNAME = Facebook;
83
+ TargetAttributes = {
84
+ 58B511DA1A9E6C8500147676 = {
85
+ CreatedOnToolsVersion = 6.1.1;
86
+ };
87
+ };
88
+ };
89
+ buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "DatadogSDKReactNativeWebView" */;
90
+ compatibilityVersion = "Xcode 3.2";
91
+ developmentRegion = English;
92
+ hasScannedForEncodings = 0;
93
+ knownRegions = (
94
+ English,
95
+ en,
96
+ );
97
+ mainGroup = 58B511D21A9E6C8500147676;
98
+ productRefGroup = 58B511D21A9E6C8500147676;
99
+ projectDirPath = "";
100
+ projectRoot = "";
101
+ targets = (
102
+ 58B511DA1A9E6C8500147676 /* DatadogSDKReactNativeWebView */,
103
+ );
104
+ };
105
+ /* End PBXProject section */
106
+
107
+ /* Begin PBXSourcesBuildPhase section */
108
+ 58B511D71A9E6C8500147676 /* Sources */ = {
109
+ isa = PBXSourcesBuildPhase;
110
+ buildActionMask = 2147483647;
111
+ files = (
112
+ );
113
+ runOnlyForDeploymentPostprocessing = 0;
114
+ };
115
+ /* End PBXSourcesBuildPhase section */
116
+
117
+ /* Begin XCBuildConfiguration section */
118
+ 58B511ED1A9E6C8500147676 /* Debug */ = {
119
+ isa = XCBuildConfiguration;
120
+ buildSettings = {
121
+ ALWAYS_SEARCH_USER_PATHS = NO;
122
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
123
+ CLANG_CXX_LIBRARY = "libc++";
124
+ CLANG_ENABLE_MODULES = YES;
125
+ CLANG_ENABLE_OBJC_ARC = YES;
126
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
127
+ CLANG_WARN_BOOL_CONVERSION = YES;
128
+ CLANG_WARN_COMMA = YES;
129
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
130
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
131
+ CLANG_WARN_EMPTY_BODY = YES;
132
+ CLANG_WARN_ENUM_CONVERSION = YES;
133
+ CLANG_WARN_INFINITE_RECURSION = YES;
134
+ CLANG_WARN_INT_CONVERSION = YES;
135
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
136
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
137
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
138
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
139
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
140
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
141
+ CLANG_WARN_UNREACHABLE_CODE = YES;
142
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
143
+ COPY_PHASE_STRIP = NO;
144
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
145
+ ENABLE_TESTABILITY = YES;
146
+ GCC_C_LANGUAGE_STANDARD = gnu99;
147
+ GCC_DYNAMIC_NO_PIC = NO;
148
+ GCC_NO_COMMON_BLOCKS = YES;
149
+ GCC_OPTIMIZATION_LEVEL = 0;
150
+ GCC_PREPROCESSOR_DEFINITIONS = (
151
+ "DEBUG=1",
152
+ "$(inherited)",
153
+ );
154
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
155
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
156
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
157
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
158
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
159
+ GCC_WARN_UNUSED_FUNCTION = YES;
160
+ GCC_WARN_UNUSED_VARIABLE = YES;
161
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
162
+ MTL_ENABLE_DEBUG_INFO = YES;
163
+ ONLY_ACTIVE_ARCH = YES;
164
+ SDKROOT = iphoneos;
165
+ };
166
+ name = Debug;
167
+ };
168
+ 58B511EE1A9E6C8500147676 /* Release */ = {
169
+ isa = XCBuildConfiguration;
170
+ buildSettings = {
171
+ ALWAYS_SEARCH_USER_PATHS = NO;
172
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
173
+ CLANG_CXX_LIBRARY = "libc++";
174
+ CLANG_ENABLE_MODULES = YES;
175
+ CLANG_ENABLE_OBJC_ARC = YES;
176
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
177
+ CLANG_WARN_BOOL_CONVERSION = YES;
178
+ CLANG_WARN_COMMA = YES;
179
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
180
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
181
+ CLANG_WARN_EMPTY_BODY = YES;
182
+ CLANG_WARN_ENUM_CONVERSION = YES;
183
+ CLANG_WARN_INFINITE_RECURSION = YES;
184
+ CLANG_WARN_INT_CONVERSION = YES;
185
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
186
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
187
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
188
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
189
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
190
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
191
+ CLANG_WARN_UNREACHABLE_CODE = YES;
192
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
193
+ COPY_PHASE_STRIP = YES;
194
+ ENABLE_NS_ASSERTIONS = NO;
195
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
196
+ GCC_C_LANGUAGE_STANDARD = gnu99;
197
+ GCC_NO_COMMON_BLOCKS = YES;
198
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
199
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
200
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
201
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
202
+ GCC_WARN_UNUSED_FUNCTION = YES;
203
+ GCC_WARN_UNUSED_VARIABLE = YES;
204
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
205
+ MTL_ENABLE_DEBUG_INFO = NO;
206
+ SDKROOT = iphoneos;
207
+ VALIDATE_PRODUCT = YES;
208
+ };
209
+ name = Release;
210
+ };
211
+ 58B511F01A9E6C8500147676 /* Debug */ = {
212
+ isa = XCBuildConfiguration;
213
+ buildSettings = {
214
+ HEADER_SEARCH_PATHS = (
215
+ "$(inherited)",
216
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
217
+ "$(SRCROOT)/../../../React/**",
218
+ "$(SRCROOT)/../../react-native/React/**",
219
+ );
220
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
221
+ OTHER_LDFLAGS = "-ObjC";
222
+ PRODUCT_NAME = DatadogSDKReactNativeWebView;
223
+ SKIP_INSTALL = YES;
224
+ SWIFT_OBJC_BRIDGING_HEADER = "DatadogSDKReactNativeWebView-Bridging-Header.h";
225
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
226
+ SWIFT_VERSION = 5.0;
227
+ };
228
+ name = Debug;
229
+ };
230
+ 58B511F11A9E6C8500147676 /* Release */ = {
231
+ isa = XCBuildConfiguration;
232
+ buildSettings = {
233
+ HEADER_SEARCH_PATHS = (
234
+ "$(inherited)",
235
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
236
+ "$(SRCROOT)/../../../React/**",
237
+ "$(SRCROOT)/../../react-native/React/**",
238
+ );
239
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
240
+ OTHER_LDFLAGS = "-ObjC";
241
+ PRODUCT_NAME = DatadogSDKReactNativeWebView;
242
+ SKIP_INSTALL = YES;
243
+ SWIFT_OBJC_BRIDGING_HEADER = "DatadogSDKReactNativeWebView-Bridging-Header.h";
244
+ SWIFT_VERSION = 5.0;
245
+ };
246
+ name = Release;
247
+ };
248
+ /* End XCBuildConfiguration section */
249
+
250
+ /* Begin XCConfigurationList section */
251
+ 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "DatadogSDKReactNativeWebView" */ = {
252
+ isa = XCConfigurationList;
253
+ buildConfigurations = (
254
+ 58B511ED1A9E6C8500147676 /* Debug */,
255
+ 58B511EE1A9E6C8500147676 /* Release */,
256
+ );
257
+ defaultConfigurationIsVisible = 0;
258
+ defaultConfigurationName = Release;
259
+ };
260
+ 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "DatadogSDKReactNativeWebView" */ = {
261
+ isa = XCConfigurationList;
262
+ buildConfigurations = (
263
+ 58B511F01A9E6C8500147676 /* Debug */,
264
+ 58B511F11A9E6C8500147676 /* Release */,
265
+ );
266
+ defaultConfigurationIsVisible = 0;
267
+ defaultConfigurationName = Release;
268
+ };
269
+ /* End XCConfigurationList section */
270
+ };
271
+ rootObject = 58B511D31A9E6C8500147676 /* Project object */;
272
+ }
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Workspace
3
+ version = "1.0">
4
+ </Workspace>
@@ -0,0 +1,12 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ // This file is imported in the auto-generated DatadogSDKReactNative-Swift.h header file.
8
+ // Deleting it could result in iOS builds failing.
9
+
10
+ #import "RCTDatadogWebView.h"
11
+ #import "RCTDatadogWebViewManager.h"
12
+ #import <react-native-webview/RNCWebViewImpl.h>
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ #import <react-native-webview/RNCWebViewImpl.h>
8
+
9
+ @class RCTDatadogWebView;
10
+
11
+ @protocol RCTDatadogWebViewDelegate <NSObject>
12
+ - (void)didCreateWebView:(RCTDatadogWebView *)webView;
13
+ @end
14
+
15
+ @interface RCTDatadogWebView : RNCWebViewImpl
16
+
17
+ @property (nonatomic, weak) id<RCTDatadogWebViewDelegate> ddWebViewDelegate;
18
+ @property (nonatomic, assign) BOOL isTrackingEnabled;
19
+
20
+ - (WKWebView*) getWKWebView;
21
+ @end
@@ -0,0 +1,53 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ #import "RCTDatadogWebView.h"
8
+ #import <WebKit/WKUIDelegate.h>
9
+
10
+ @interface RCTDatadogWebView () <WKUIDelegate>
11
+ @end
12
+
13
+ @implementation RCTDatadogWebView { }
14
+
15
+ - (instancetype)init
16
+ {
17
+ self = [super init];
18
+ if (self) {
19
+ _isTrackingEnabled = false;
20
+ }
21
+ return self;
22
+ }
23
+
24
+ - (WKWebView *)getWKWebView {
25
+ return [self findWKWebViewInView: self];
26
+ }
27
+
28
+ - (WKWebView *)findWKWebViewInView:(UIView *)view {
29
+ // Check if the current view is a WKWebView
30
+ if ([view isKindOfClass:[WKWebView class]]) {
31
+ return (WKWebView *)view;
32
+ }
33
+
34
+ // Iterate through the subviews recursively
35
+ for (UIView *subview in view.subviews) {
36
+ WKWebView *webView = [self findWKWebViewInView:subview];
37
+ if (webView) {
38
+ return webView; // Return the first WKWebView found
39
+ }
40
+ }
41
+
42
+ return nil;
43
+ }
44
+
45
+ - (void)didMoveToWindow {
46
+ [super didMoveToWindow];
47
+
48
+ if (self.ddWebViewDelegate != nil && [self.ddWebViewDelegate respondsToSelector:@selector(didCreateWebView:)]) {
49
+ [self.ddWebViewDelegate didCreateWebView:self];
50
+ }
51
+ }
52
+
53
+ @end
@@ -0,0 +1,10 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ #import <react-native-webview/RNCWebViewManager.h>
8
+
9
+ @interface RCTDatadogWebViewManager : RNCWebViewManager
10
+ @end