@thealteroffice/react-native-adgeist 0.0.27-beta → 0.0.29-beta

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 (66) hide show
  1. package/Adgeist.podspec +3 -4
  2. package/README.md +51 -2
  3. package/android/app/build/generated/source/codegen/java/com/facebook/fbreact/specs/NativeAdgeistSpec.java +4 -0
  4. package/android/app/build/generated/source/codegen/java/com/facebook/react/viewmanagers/HTML5AdNativeComponentManagerDelegate.java +1 -1
  5. package/android/app/build/generated/source/codegen/jni/RNAdgeistSpec-generated.cpp +6 -0
  6. package/android/app/build/generated/source/codegen/jni/react/renderer/components/RNAdgeistSpec/Props.cpp +1 -1
  7. package/android/app/build/generated/source/codegen/jni/react/renderer/components/RNAdgeistSpec/Props.h +18 -1
  8. package/android/app/build/generated/source/codegen/jni/react/renderer/components/RNAdgeistSpec/RNAdgeistSpecJSI-generated.cpp +8 -0
  9. package/android/app/build/generated/source/codegen/jni/react/renderer/components/RNAdgeistSpec/RNAdgeistSpecJSI.h +9 -0
  10. package/android/build.gradle +22 -1
  11. package/android/libs/adgeistkit-beta-release.aar +0 -0
  12. package/android/src/main/java/com/adgeist/components/HTML5AdViewManagerImpl.kt +31 -11
  13. package/android/src/main/java/com/adgeist/modules/AdgeistImpl.kt +8 -3
  14. package/android/src/main/java/com/adgeist/utils/CreativeExtensions.kt +76 -36
  15. package/android/src/newarch/java/com/Adgeist.kt +5 -1
  16. package/android/src/oldarch/java/com/Adgeist.kt +6 -1
  17. package/ios/Adgeist.mm +4 -0
  18. package/ios/AdgeistImpl.swift +16 -13
  19. package/ios/NativeHTML5AdManager.h +12 -1
  20. package/ios/NativeHTML5AdManager.mm +120 -7
  21. package/ios/NativeHTML5AdView.swift +77 -15
  22. package/ios/adgeist-Bridging-Header.h +1 -0
  23. package/lib/module/components/deprecated/BannerAdView.js +6 -5
  24. package/lib/module/components/deprecated/BannerAdView.js.map +1 -1
  25. package/lib/module/constants.js +1 -1
  26. package/lib/module/index.js +2 -0
  27. package/lib/module/index.js.map +1 -1
  28. package/lib/module/providers/AdgeistProvider.js +8 -0
  29. package/lib/module/providers/AdgeistProvider.js.map +1 -1
  30. package/lib/module/specs/HTML5AdNativeComponent.ts +16 -5
  31. package/lib/module/specs/NativeAdgeist.js.map +1 -1
  32. package/lib/module/types/AdType.js +16 -0
  33. package/lib/module/types/AdType.js.map +1 -0
  34. package/lib/module/utmtracker/index.js +25 -0
  35. package/lib/module/utmtracker/index.js.map +1 -0
  36. package/lib/typescript/src/components/deprecated/BannerAdView.d.ts.map +1 -1
  37. package/lib/typescript/src/constants.d.ts +1 -1
  38. package/lib/typescript/src/index.d.ts +2 -0
  39. package/lib/typescript/src/index.d.ts.map +1 -1
  40. package/lib/typescript/src/providers/AdgeistProvider.d.ts.map +1 -1
  41. package/lib/typescript/src/specs/HTML5AdNativeComponent.d.ts +3 -2
  42. package/lib/typescript/src/specs/HTML5AdNativeComponent.d.ts.map +1 -1
  43. package/lib/typescript/src/specs/NativeAdgeist.d.ts +1 -0
  44. package/lib/typescript/src/specs/NativeAdgeist.d.ts.map +1 -1
  45. package/lib/typescript/src/types/AdType.d.ts +14 -0
  46. package/lib/typescript/src/types/AdType.d.ts.map +1 -0
  47. package/lib/typescript/src/types/CPMAdResponse.d.ts +6 -2
  48. package/lib/typescript/src/types/CPMAdResponse.d.ts.map +1 -1
  49. package/lib/typescript/src/types/FixedAdResponse.d.ts +69 -38
  50. package/lib/typescript/src/types/FixedAdResponse.d.ts.map +1 -1
  51. package/lib/typescript/src/types/HTML5AdNativeComponentProps.d.ts +2 -1
  52. package/lib/typescript/src/types/HTML5AdNativeComponentProps.d.ts.map +1 -1
  53. package/lib/typescript/src/utmtracker/index.d.ts +6 -0
  54. package/lib/typescript/src/utmtracker/index.d.ts.map +1 -0
  55. package/package.json +1 -1
  56. package/src/components/deprecated/BannerAdView.tsx +7 -5
  57. package/src/constants.ts +1 -1
  58. package/src/index.tsx +5 -0
  59. package/src/providers/AdgeistProvider.tsx +9 -0
  60. package/src/specs/HTML5AdNativeComponent.ts +16 -5
  61. package/src/specs/NativeAdgeist.ts +2 -0
  62. package/src/types/AdType.ts +16 -0
  63. package/src/types/CPMAdResponse.ts +7 -2
  64. package/src/types/FixedAdResponse.ts +77 -38
  65. package/src/types/HTML5AdNativeComponentProps.ts +2 -1
  66. package/src/utmtracker/index.ts +26 -0
package/Adgeist.podspec CHANGED
@@ -16,14 +16,13 @@ Pod::Spec.new do |s|
16
16
  s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
17
17
  s.private_header_files = "ios/**/*.h"
18
18
 
19
- s.dependency "AdgeistKit", '= 1.0.7-beta'
19
+ s.dependency "AdgeistKit", '= 1.0.12-beta'
20
20
 
21
21
  # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
22
22
  # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
23
23
  if respond_to?(:install_modules_dependencies, true)
24
24
  install_modules_dependencies(s)
25
25
  else
26
- s.dependency "React-Core"
27
-
28
- end
26
+ s.dependency "React-Core"
27
+ end
29
28
  end
package/README.md CHANGED
@@ -99,7 +99,7 @@ export default function App() {
99
99
  Use the `HTML5AdView` component to display banner ads anywhere in your app. Place this component where you want the ads to appear and the SDK will automatically load and render the ad content.
100
100
 
101
101
  ```tsx
102
- import { HTML5AdView } from '@thealteroffice/react-native-adgeist';
102
+ import { HTML5AdView, AdTypes } from '@thealteroffice/react-native-adgeist';
103
103
 
104
104
  <HTML5AdView
105
105
  adUnitID="6932a4c022f6786424ce3b84"
@@ -109,6 +109,55 @@ import { HTML5AdView } from '@thealteroffice/react-native-adgeist';
109
109
  onAdOpened={}
110
110
  onAdClosed={}
111
111
  onAdClicked={}
112
- adType="display"
112
+ adType={AdTypes.DISPLAY}
113
113
  />;
114
114
  ```
115
+
116
+ **Ad Types:**
117
+ - `AdTypes.BANNER` - Small rectangular banner ads
118
+ - `AdTypes.DISPLAY` - Standard display ads
119
+ - `AdTypes.COMPANION` - Companion ads (requires minimum 320x320 dimensions)
120
+
121
+
122
+ ### Campaign Conversion Analytics
123
+
124
+ #### Prerequisites
125
+
126
+ Before implementing campaign conversion analytics, ensure your app has deeplink support configured. Refer to these resources for setup guidance:
127
+
128
+ - [React Navigation - Deep Linking](https://reactnavigation.org/docs/deep-linking/)
129
+ - [React Native - Linking](https://reactnative.dev/docs/linking)
130
+ - [Expo - Linking into your app](https://docs.expo.dev/linking/into-your-app/)
131
+
132
+ #### Implementation
133
+
134
+ Tracks deeplink UTM parameters for attribution and analytics. This method should be called whenever your app is opened via a deeplink to capture campaign attribution data.
135
+
136
+ ```tsx
137
+ // Example usage with React Navigation
138
+ import { Linking } from 'react-native';
139
+ import { trackConversionsWithDeepLinks } from '@thealteroffice/react-native-adgeist';
140
+
141
+ useEffect(() => {
142
+ const handleUrl = (url: string) => {
143
+ trackConversionsWithDeepLinks(url);
144
+ // Continue with your normal deeplink handling
145
+ };
146
+
147
+ // Handle initial URL if app was opened from link
148
+ Linking.getInitialURL().then((url) => {
149
+ if (url) {
150
+ handleUrl(url);
151
+ }
152
+ });
153
+
154
+ // Handle URL changes while app is running
155
+ const subscription = Linking.addEventListener('url', (event) => {
156
+ handleUrl(event.url);
157
+ });
158
+
159
+ return () => subscription?.remove();
160
+ }, []);
161
+ ```
162
+
163
+ **Important**: This method should be called as early as possible when handling deeplinks to ensure accurate attribution tracking.
@@ -81,4 +81,8 @@ public abstract class NativeAdgeistSpec extends ReactContextBaseJavaModule imple
81
81
  @ReactMethod
82
82
  @DoNotStrip
83
83
  public abstract void trackVideoPlayback(String campaignId, String adSpaceId, String bidId, String bidMeta, String buyType, boolean isTestEnvironment, double totalPlaybackTime, Promise promise);
84
+
85
+ @ReactMethod
86
+ @DoNotStrip
87
+ public abstract void trackDeeplinkUtm(String url);
84
88
  }
@@ -34,7 +34,7 @@ public class HTML5AdNativeComponentManagerDelegate<T extends View, U extends Bas
34
34
  mViewManager.setAdSize(view, (ReadableMap) value);
35
35
  break;
36
36
  case "adType":
37
- mViewManager.setAdType(view, value == null ? null : (String) value);
37
+ mViewManager.setAdType(view, (String) value);
38
38
  break;
39
39
  default:
40
40
  super.setProperty(view, propName, value);
@@ -72,6 +72,11 @@ static facebook::jsi::Value __hostFunction_NativeAdgeistSpecJSI_trackVideoPlayba
72
72
  return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "trackVideoPlayback", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZDLcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
73
73
  }
74
74
 
75
+ static facebook::jsi::Value __hostFunction_NativeAdgeistSpecJSI_trackDeeplinkUtm(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
76
+ static jmethodID cachedMethodId = nullptr;
77
+ return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, VoidKind, "trackDeeplinkUtm", "(Ljava/lang/String;)V", args, count, cachedMethodId);
78
+ }
79
+
75
80
  NativeAdgeistSpecJSI::NativeAdgeistSpecJSI(const JavaTurboModule::InitParams &params)
76
81
  : JavaTurboModule(params) {
77
82
  methodMap_["initializeSdk"] = MethodMetadata {4, __hostFunction_NativeAdgeistSpecJSI_initializeSdk};
@@ -86,6 +91,7 @@ NativeAdgeistSpecJSI::NativeAdgeistSpecJSI(const JavaTurboModule::InitParams &pa
86
91
  methodMap_["trackTotalView"] = MethodMetadata {7, __hostFunction_NativeAdgeistSpecJSI_trackTotalView};
87
92
  methodMap_["trackClick"] = MethodMetadata {6, __hostFunction_NativeAdgeistSpecJSI_trackClick};
88
93
  methodMap_["trackVideoPlayback"] = MethodMetadata {7, __hostFunction_NativeAdgeistSpecJSI_trackVideoPlayback};
94
+ methodMap_["trackDeeplinkUtm"] = MethodMetadata {1, __hostFunction_NativeAdgeistSpecJSI_trackDeeplinkUtm};
89
95
  }
90
96
 
91
97
  std::shared_ptr<TurboModule> RNAdgeistSpec_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams &params) {
@@ -22,7 +22,7 @@ HTML5AdNativeComponentProps::HTML5AdNativeComponentProps(
22
22
  adUnitID(convertRawProp(context, rawProps, "adUnitID", sourceProps.adUnitID, {})),
23
23
  adIsResponsive(convertRawProp(context, rawProps, "adIsResponsive", sourceProps.adIsResponsive, {false})),
24
24
  adSize(convertRawProp(context, rawProps, "adSize", sourceProps.adSize, {})),
25
- adType(convertRawProp(context, rawProps, "adType", sourceProps.adType, {}))
25
+ adType(convertRawProp(context, rawProps, "adType", sourceProps.adType, {HTML5AdNativeComponentAdType::BANNER}))
26
26
  {}
27
27
 
28
28
  } // namespace facebook::react
@@ -15,6 +15,23 @@
15
15
 
16
16
  namespace facebook::react {
17
17
 
18
+ enum class HTML5AdNativeComponentAdType { BANNER, DISPLAY, COMPANION };
19
+
20
+ static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, HTML5AdNativeComponentAdType &result) {
21
+ auto string = (std::string)value;
22
+ if (string == "BANNER") { result = HTML5AdNativeComponentAdType::BANNER; return; }
23
+ if (string == "DISPLAY") { result = HTML5AdNativeComponentAdType::DISPLAY; return; }
24
+ if (string == "COMPANION") { result = HTML5AdNativeComponentAdType::COMPANION; return; }
25
+ abort();
26
+ }
27
+
28
+ static inline std::string toString(const HTML5AdNativeComponentAdType &value) {
29
+ switch (value) {
30
+ case HTML5AdNativeComponentAdType::BANNER: return "BANNER";
31
+ case HTML5AdNativeComponentAdType::DISPLAY: return "DISPLAY";
32
+ case HTML5AdNativeComponentAdType::COMPANION: return "COMPANION";
33
+ }
34
+ }
18
35
  struct HTML5AdNativeComponentAdSizeStruct {
19
36
  double width{0.0};
20
37
  double height{0.0};
@@ -46,7 +63,7 @@ class HTML5AdNativeComponentProps final : public ViewProps {
46
63
  std::string adUnitID{};
47
64
  bool adIsResponsive{false};
48
65
  HTML5AdNativeComponentAdSizeStruct adSize{};
49
- std::string adType{};
66
+ HTML5AdNativeComponentAdType adType{HTML5AdNativeComponentAdType::BANNER};
50
67
  };
51
68
 
52
69
  } // namespace facebook::react
@@ -121,6 +121,13 @@ static jsi::Value __hostFunction_NativeAdgeistCxxSpecJSI_trackVideoPlayback(jsi:
121
121
  count <= 6 ? throw jsi::JSError(rt, "Expected argument in position 6 to be passed") : args[6].asNumber()
122
122
  );
123
123
  }
124
+ static jsi::Value __hostFunction_NativeAdgeistCxxSpecJSI_trackDeeplinkUtm(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
125
+ static_cast<NativeAdgeistCxxSpecJSI *>(&turboModule)->trackDeeplinkUtm(
126
+ rt,
127
+ count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt)
128
+ );
129
+ return jsi::Value::undefined();
130
+ }
124
131
 
125
132
  NativeAdgeistCxxSpecJSI::NativeAdgeistCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
126
133
  : TurboModule("Adgeist", jsInvoker) {
@@ -136,6 +143,7 @@ NativeAdgeistCxxSpecJSI::NativeAdgeistCxxSpecJSI(std::shared_ptr<CallInvoker> js
136
143
  methodMap_["trackTotalView"] = MethodMetadata {7, __hostFunction_NativeAdgeistCxxSpecJSI_trackTotalView};
137
144
  methodMap_["trackClick"] = MethodMetadata {6, __hostFunction_NativeAdgeistCxxSpecJSI_trackClick};
138
145
  methodMap_["trackVideoPlayback"] = MethodMetadata {7, __hostFunction_NativeAdgeistCxxSpecJSI_trackVideoPlayback};
146
+ methodMap_["trackDeeplinkUtm"] = MethodMetadata {1, __hostFunction_NativeAdgeistCxxSpecJSI_trackDeeplinkUtm};
139
147
  }
140
148
 
141
149
 
@@ -32,6 +32,7 @@ public:
32
32
  virtual jsi::Value trackTotalView(jsi::Runtime &rt, jsi::String campaignId, jsi::String adSpaceId, jsi::String bidId, jsi::String bidMeta, jsi::String buyType, bool isTestEnvironment, double totalViewTime) = 0;
33
33
  virtual jsi::Value trackClick(jsi::Runtime &rt, jsi::String campaignId, jsi::String adSpaceId, jsi::String bidId, jsi::String bidMeta, jsi::String buyType, bool isTestEnvironment) = 0;
34
34
  virtual jsi::Value trackVideoPlayback(jsi::Runtime &rt, jsi::String campaignId, jsi::String adSpaceId, jsi::String bidId, jsi::String bidMeta, jsi::String buyType, bool isTestEnvironment, double totalPlaybackTime) = 0;
35
+ virtual void trackDeeplinkUtm(jsi::Runtime &rt, jsi::String url) = 0;
35
36
 
36
37
  };
37
38
 
@@ -158,6 +159,14 @@ private:
158
159
  return bridging::callFromJs<jsi::Value>(
159
160
  rt, &T::trackVideoPlayback, jsInvoker_, instance_, std::move(campaignId), std::move(adSpaceId), std::move(bidId), std::move(bidMeta), std::move(buyType), std::move(isTestEnvironment), std::move(totalPlaybackTime));
160
161
  }
162
+ void trackDeeplinkUtm(jsi::Runtime &rt, jsi::String url) override {
163
+ static_assert(
164
+ bridging::getParameterCount(&T::trackDeeplinkUtm) == 2,
165
+ "Expected trackDeeplinkUtm(...) to have 2 parameters");
166
+
167
+ return bridging::callFromJs<void>(
168
+ rt, &T::trackDeeplinkUtm, jsInvoker_, instance_, std::move(url));
169
+ }
161
170
 
162
171
  private:
163
172
  friend class NativeAdgeistCxxSpec;
@@ -98,14 +98,35 @@ android {
98
98
  repositories {
99
99
  mavenCentral()
100
100
  google()
101
+ /*
102
+ * Alternative: Use local AAR file instead of remote package
103
+ * Uncomment the lines below and comment out the remote dependency above to use a local AAR file.
104
+ * This is useful for testing unreleased versions or when working with custom builds.
105
+ * Place your AAR file in the 'libs' folder.
106
+ */
107
+ // flatDir {
108
+ // dirs 'libs'
109
+ // }
101
110
  }
102
111
 
103
112
  def kotlin_version = getExtOrDefault("kotlinVersion")
104
113
 
105
114
  dependencies {
106
115
  implementation "com.facebook.react:react-android"
107
- implementation "ai.adgeist:adgeistkit:1.1.16-beta"
116
+ implementation "ai.adgeist:adgeistkit:1.1.20-beta"
108
117
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
118
+
119
+ /*
120
+ * Alternative: Use local AAR file instead of remote package
121
+ * Uncomment the lines below and comment out the remote dependency above to use a local AAR file.
122
+ * This is useful for testing unreleased versions or when working with custom builds.
123
+ * Place your AAR file in the 'libs' folder.
124
+ */
125
+ // implementation(name: 'adgeistkit-beta-release', ext: 'aar')
126
+ // implementation "androidx.work:work-runtime-ktx:2.11.1"
127
+ // implementation 'com.google.code.gson:gson:2.10.1'
128
+ // implementation 'com.squareup.okhttp3:okhttp:4.12.0'
129
+ // implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
109
130
  }
110
131
 
111
132
  if (isNewArchitectureEnabled()) {
@@ -5,8 +5,9 @@ import android.view.View
5
5
  import androidx.annotation.RequiresPermission
6
6
  import com.adgeistkit.ads.AdListener
7
7
  import com.adgeistkit.ads.AdSize
8
+ import com.adgeistkit.ads.AdType
8
9
  import com.adgeistkit.ads.AdView
9
- import com.adgeistkit.ads.network.AdRequest
10
+ import com.adgeistkit.request.AdRequest
10
11
  import com.facebook.react.bridge.Arguments
11
12
  import com.facebook.react.bridge.ReadableMap
12
13
  import com.facebook.react.bridge.WritableMap
@@ -23,9 +24,13 @@ object HTML5AdViewManagerImpl {
23
24
  const val EVENT_AD_CLOSED = "onAdClosed"
24
25
  const val EVENT_AD_CLICKED = "onAdClicked"
25
26
 
27
+ private val viewContextMap = mutableMapOf<Int, ThemedReactContext>()
28
+
26
29
  fun createViewInstance(reactContext: ThemedReactContext): AdView {
27
- val adView = AdView(reactContext.applicationContext)
28
- adView.setTag(com.facebook.react.R.id.view_tag_native_id, reactContext)
30
+ Log.d(TAG, "Creating AdView with ThemedReactContext: ${reactContext.hashCode()}")
31
+ val adView = AdView(reactContext)
32
+ viewContextMap[System.identityHashCode(adView)] = reactContext
33
+ Log.d(TAG, "AdView created with hash: ${System.identityHashCode(adView)} and context hash: ${reactContext.hashCode()}")
29
34
  return adView
30
35
  }
31
36
 
@@ -55,8 +60,12 @@ object HTML5AdViewManagerImpl {
55
60
  }
56
61
 
57
62
  fun setAdType(view: AdView, adType: String?) {
58
- if (adType != null) {
59
- view.adType = adType
63
+ val typeToSet = adType ?: "BANNER"
64
+ try {
65
+ view.adType = AdType.valueOf(typeToSet)
66
+ } catch (e: IllegalArgumentException) {
67
+ Log.e(TAG, "Invalid ad type: $typeToSet. Must be BANNER, DISPLAY, or COMPANION", e)
68
+ view.adType = AdType.BANNER
60
69
  }
61
70
  }
62
71
 
@@ -107,7 +116,14 @@ object HTML5AdViewManagerImpl {
107
116
  }
108
117
 
109
118
  fun destroyAd(view: AdView) {
110
- view.destroy()
119
+ try {
120
+ view.destroy()
121
+ } catch (e: Exception) {
122
+ Log.e(TAG, "Error destroying ad view", e)
123
+ } finally {
124
+ // Clean up the context reference
125
+ viewContextMap.remove(System.identityHashCode(view))
126
+ }
111
127
  }
112
128
 
113
129
  private fun measureAndLayout(view: AdView) {
@@ -119,13 +135,17 @@ object HTML5AdViewManagerImpl {
119
135
  }
120
136
 
121
137
  private fun sendEvent(view: AdView, eventName: String, params: WritableMap) {
122
- val reactContext = view.getTag(com.facebook.react.R.id.view_tag_native_id) as? ThemedReactContext
138
+ val reactContext = viewContextMap[System.identityHashCode(view)]
123
139
  if (reactContext != null) {
124
- reactContext
125
- .getJSModule(RCTEventEmitter::class.java)
126
- .receiveEvent(view.id, eventName, params)
140
+ try {
141
+ reactContext
142
+ .getJSModule(RCTEventEmitter::class.java)
143
+ .receiveEvent(view.id, eventName, params)
144
+ } catch (e: Exception) {
145
+ Log.e(TAG, "Error sending event $eventName", e)
146
+ }
127
147
  } else {
128
- Log.e(TAG, "Unable to send event $eventName: ThemedReactContext not found")
148
+ Log.w(TAG, "Unable to send event $eventName: ThemedReactContext not found or view already destroyed")
129
149
  }
130
150
  }
131
151
  }
@@ -1,5 +1,6 @@
1
1
  package com.adgeist.modules
2
2
 
3
+ import android.net.Uri
3
4
  import android.util.Log
4
5
  import com.facebook.react.bridge.Promise
5
6
  import com.facebook.react.bridge.ReactApplicationContext
@@ -13,17 +14,16 @@ import com.adgeistkit.data.network.FetchCreative
13
14
 
14
15
  import com.facebook.react.bridge.ReadableMap
15
16
  import com.adgeist.utils.toWritableMap
16
- import com.adgeistkit.ads.network.AnalyticsRequest
17
- import com.adgeistkit.ads.network.AnalyticsRequestDEPRECATED
17
+ import com.adgeistkit.request.AnalyticsRequestDEPRECATED
18
18
 
19
19
  class AdgeistImpl internal constructor(private val context: ReactApplicationContext) {
20
-
21
20
  private var adgeistInstance: AdgeistCore? = null
22
21
  private var getAd: FetchCreative? = null
23
22
  private var postCreativeAnalytic: CreativeAnalytics? = null
24
23
 
25
24
  fun initializeSdk(customBidRequestBackendDomain: String?, customPackageOrBundleID: String?, customAdgeistAppID: String?, customVersioning: String?, promise: Promise) {
26
25
  try {
26
+ Log.d("AdgeistImpl", "SDK initialized with domain: ${customBidRequestBackendDomain ?: "default"}, package/bundle ID: ${customPackageOrBundleID ?: "default"}, app ID: ${customAdgeistAppID ?: "default"}, versioning: ${customVersioning ?: "default"}")
27
27
  adgeistInstance = AdgeistCore.initialize(context.applicationContext, customBidRequestBackendDomain, customPackageOrBundleID, customAdgeistAppID, customVersioning)
28
28
  getAd = adgeistInstance?.getCreative()
29
29
  postCreativeAnalytic = adgeistInstance?.postCreativeAnalytics()
@@ -105,6 +105,11 @@ class AdgeistImpl internal constructor(private val context: ReactApplicationCont
105
105
  adgeistInstance?.updateConsentStatus(consent)
106
106
  }
107
107
 
108
+ fun trackDeeplinkUtm(url: String) {
109
+ val uri = Uri.parse(url)
110
+ adgeistInstance?.trackUtmFromDeeplink(uri)
111
+ }
112
+
108
113
  companion object {
109
114
  const val NAME = "Adgeist"
110
115
  }
@@ -53,13 +53,16 @@ fun CPMAdResponse.toWritableMap(): WritableMap {
53
53
  fun FixedAdResponse.toWritableMap(): WritableMap {
54
54
  val map = Arguments.createMap()
55
55
 
56
+ isTest?.let { map.putBoolean("isTest", it) }
57
+ expiresAt?.let { map.putString("expiresAt", it) }
56
58
  map.putString("metaData", metaData)
57
59
  map.putString("id", id)
58
- map.putString("generatedAt", generatedAt)
59
- map.putString("campaignId", campaignId)
60
- map.putString("type", type)
61
- map.putString("loadType", loadType)
62
- map.putInt("frontendCacheDurationSeconds", frontendCacheDurationSeconds ?: 0)
60
+ generatedAt?.let { map.putString("generatedAt", it) }
61
+ signature?.let { map.putString("signature", it) }
62
+ campaignId?.let { map.putString("campaignId", it) }
63
+ type?.let { map.putString("type", it) }
64
+ loadType?.let { map.putString("loadType", it) }
65
+ frontendCacheDurationSeconds?.let { map.putInt("frontendCacheDurationSeconds", it) }
63
66
 
64
67
  advertiser?.let {
65
68
  val advMap = Arguments.createMap()
@@ -76,41 +79,74 @@ fun FixedAdResponse.toWritableMap(): WritableMap {
76
79
  map.putMap("campaignValidity", cvMap)
77
80
  }
78
81
 
79
- creatives?.let { list ->
80
- val arr = Arguments.createArray()
81
- list.forEach { creative ->
82
- val cMap = Arguments.createMap()
83
- cMap.putString("ctaUrl", creative.ctaUrl)
84
- cMap.putString("description", creative.description)
85
- cMap.putString("fileName", creative.fileName)
86
- cMap.putInt("fileSize", creative.fileSize ?: 0)
87
- cMap.putString("fileUrl", creative.fileUrl)
88
- cMap.putString("thumbnailUrl", creative.thumbnailUrl)
89
- cMap.putString("title", creative.title)
90
- cMap.putString("type", creative.type)
91
-
92
- creative.contentModerationResult?.let {
93
- val cm = Arguments.createMap()
94
- cm.putString("\$oid", it.`$oid`)
95
- cMap.putMap("contentModerationResult", cm)
96
- }
82
+ val creativesArr = Arguments.createArray()
83
+ creatives.forEach { creative ->
84
+ val cMap = Arguments.createMap()
85
+ cMap.putString("ctaUrl", creative.ctaUrl)
86
+ cMap.putString("description", creative.description)
87
+ cMap.putString("fileName", creative.fileName)
88
+ cMap.putInt("fileSize", creative.fileSize ?: 0)
89
+ cMap.putString("fileUrl", creative.fileUrl)
90
+ cMap.putString("thumbnailUrl", creative.thumbnailUrl)
91
+ cMap.putString("title", creative.title)
92
+ cMap.putString("type", creative.type)
93
+
94
+ creative.contentModerationResult?.let {
95
+ val cm = Arguments.createMap()
96
+ cm.putString("\$oid", it.`$oid`)
97
+ cMap.putMap("contentModerationResult", cm)
98
+ }
97
99
 
98
- creative.createdAt?.let {
99
- val cm = Arguments.createMap()
100
- cm.putDouble("\$date", it.`$date`?.toDouble() ?: 0.0)
101
- cMap.putMap("createdAt", cm)
102
- }
100
+ creative.createdAt?.let {
101
+ val cm = Arguments.createMap()
102
+ cm.putDouble("\$date", it.`$date`?.toDouble() ?: 0.0)
103
+ cMap.putMap("createdAt", cm)
104
+ }
103
105
 
104
- creative.updatedAt?.let {
105
- val cm = Arguments.createMap()
106
- cm.putDouble("\$date", it.`$date`?.toDouble() ?: 0.0)
107
- cMap.putMap("updatedAt", cm)
108
- }
106
+ creative.updatedAt?.let {
107
+ val cm = Arguments.createMap()
108
+ cm.putDouble("\$date", it.`$date`?.toDouble() ?: 0.0)
109
+ cMap.putMap("updatedAt", cm)
110
+ }
109
111
 
110
- arr.pushMap(cMap)
112
+ creativesArr.pushMap(cMap)
113
+ }
114
+ map.putArray("creatives", creativesArr)
115
+
116
+ val creativesV1Arr = Arguments.createArray()
117
+ creativesV1.forEach { creativeV1 ->
118
+ val cv1Map = Arguments.createMap()
119
+ cv1Map.putString("title", creativeV1.title)
120
+ cv1Map.putString("description", creativeV1.description)
121
+ cv1Map.putString("ctaUrl", creativeV1.ctaUrl)
122
+
123
+ creativeV1.primary?.let {
124
+ val primMap = Arguments.createMap()
125
+ primMap.putString("type", it.type)
126
+ primMap.putString("fileName", it.fileName)
127
+ primMap.putInt("fileSize", it.fileSize ?: 0)
128
+ primMap.putString("fileUrl", it.fileUrl)
129
+ primMap.putString("thumbnailUrl", it.thumbnailUrl)
130
+ cv1Map.putMap("primary", primMap)
131
+ }
132
+
133
+ creativeV1.companions?.let { companions ->
134
+ val companionsArr = Arguments.createArray()
135
+ companions.forEach { companion ->
136
+ val compMap = Arguments.createMap()
137
+ compMap.putString("type", companion.type)
138
+ compMap.putString("fileName", companion.fileName)
139
+ compMap.putInt("fileSize", companion.fileSize ?: 0)
140
+ compMap.putString("fileUrl", companion.fileUrl)
141
+ compMap.putString("thumbnailUrl", companion.thumbnailUrl)
142
+ companionsArr.pushMap(compMap)
143
+ }
144
+ cv1Map.putArray("companions", companionsArr)
111
145
  }
112
- map.putArray("creatives", arr)
146
+
147
+ creativesV1Arr.pushMap(cv1Map)
113
148
  }
149
+ map.putArray("creativesV1", creativesV1Arr)
114
150
 
115
151
  displayOptions?.let { opt ->
116
152
  val opMap = Arguments.createMap()
@@ -142,7 +178,11 @@ fun FixedAdResponse.toWritableMap(): WritableMap {
142
178
 
143
179
  impressionRequirements?.let {
144
180
  val ir = Arguments.createMap()
145
- ir.putString("impressionType", it.impressionType)
181
+ it.impressionType?.let { types ->
182
+ val typesArr = Arguments.createArray()
183
+ types.forEach { type -> typesArr.pushString(type) }
184
+ ir.putArray("impressionType", typesArr)
185
+ }
146
186
  ir.putInt("minViewDurationSeconds", it.minViewDurationSeconds ?: 0)
147
187
  map.putMap("impressionRequirements", ir)
148
188
  }
@@ -3,7 +3,7 @@ package com.adgeist
3
3
  import com.facebook.react.bridge.Promise
4
4
  import com.facebook.react.bridge.ReactApplicationContext
5
5
  import com.adgeist.modules.AdgeistImpl
6
- import com.adgeistkit.ads.network.AnalyticsRequestDEPRECATED
6
+ import com.adgeistkit.request.AnalyticsRequestDEPRECATED
7
7
  import com.facebook.react.bridge.ReadableMap
8
8
 
9
9
  class Adgeist internal constructor(reactContext: ReactApplicationContext) :
@@ -115,4 +115,8 @@ class Adgeist internal constructor(reactContext: ReactApplicationContext) :
115
115
  override fun updateConsentStatus(consent: Boolean) {
116
116
  implementation.updateConsentStatus(consent)
117
117
  }
118
+
119
+ override fun trackDeeplinkUtm(url: String) {
120
+ implementation.trackDeeplinkUtm(url)
121
+ }
118
122
  }
@@ -5,7 +5,7 @@ import com.facebook.react.bridge.ReactApplicationContext
5
5
  import com.facebook.react.bridge.ReactContextBaseJavaModule
6
6
  import com.facebook.react.bridge.ReactMethod
7
7
  import com.adgeist.modules.AdgeistImpl
8
- import com.adgeistkit.ads.network.AnalyticsRequestDEPRECATED
8
+ import com.adgeistkit.request.AnalyticsRequestDEPRECATED
9
9
  import com.facebook.react.bridge.ReadableMap
10
10
 
11
11
  class Adgeist internal constructor(reactContext: ReactApplicationContext) :
@@ -129,4 +129,9 @@ class Adgeist internal constructor(reactContext: ReactApplicationContext) :
129
129
  fun updateConsentStatus(consent: Boolean) {
130
130
  implementation.updateConsentStatus(consent)
131
131
  }
132
+
133
+ @ReactMethod
134
+ fun trackDeeplinkUtm(url: String) {
135
+ implementation.trackDeeplinkUtm(url)
136
+ }
132
137
  }
package/ios/Adgeist.mm CHANGED
@@ -70,6 +70,10 @@ RCT_EXPORT_METHOD(updateConsentStatus:(BOOL)consent) {
70
70
  [adgeist updateConsentStatus:consent];
71
71
  }
72
72
 
73
+ RCT_EXPORT_METHOD(trackDeeplinkUtm:(NSString *)url) {
74
+ [adgeist trackDeeplinkUtmWithUrl:url];
75
+ }
76
+
73
77
  RCT_EXPORT_METHOD(logEvent:(NSDictionary *)eventDict) {
74
78
  [adgeist logEventWithEventDict:eventDict];
75
79
  }
@@ -53,21 +53,17 @@ import React
53
53
  buyType: buyType,
54
54
  isTestEnvironment: isTestEnvironment
55
55
  ) { creativeData in
56
- if let creativeData = creativeData {
57
- var result: [String: Any] = [:]
58
-
59
- // Use Mirror to reflect the object's properties
60
- let mirror = Mirror(reflecting: creativeData)
61
- for child in mirror.children {
62
- if let label = child.label {
63
- result[label] = child.value
64
- }
56
+ var result: [String: Any] = [:]
57
+
58
+ // Use Mirror to reflect the object's properties
59
+ let mirror = Mirror(reflecting: creativeData)
60
+ for child in mirror.children {
61
+ if let label = child.label {
62
+ result[label] = child.value
65
63
  }
66
-
67
- resolver(result)
68
- } else {
69
- rejecter("NO_AD", "Ad data not available", nil)
70
64
  }
65
+
66
+ resolver(result)
71
67
  }
72
68
  }
73
69
 
@@ -100,6 +96,13 @@ import React
100
96
  adgeistInstance?.updateConsentStatus(consent)
101
97
  }
102
98
 
99
+ @objc public func trackDeeplinkUtm(url: String) {
100
+ guard let urlObj = URL(string: url) else {
101
+ print("Invalid URL provided for UTM tracking")
102
+ return
103
+ }
104
+ adgeistInstance?.trackDeeplink(url: urlObj)
105
+ }
103
106
 
104
107
  @objc public func logEvent(eventDict: [String: Any]) {
105
108
  let filtered = eventDict.compactMapValues { value -> Any? in
@@ -1,3 +1,4 @@
1
+ #ifdef RCT_NEW_ARCH_ENABLED
1
2
  #import <React/RCTViewComponentView.h>
2
3
  #import <UIKit/UIKit.h>
3
4
 
@@ -6,4 +7,14 @@ NS_ASSUME_NONNULL_BEGIN
6
7
  @interface RCTNativeHTML5AdManager : RCTViewComponentView
7
8
  @end
8
9
 
9
- NS_ASSUME_NONNULL_END
10
+ NS_ASSUME_NONNULL_END
11
+ #else
12
+ #import <React/RCTViewManager.h>
13
+
14
+ NS_ASSUME_NONNULL_BEGIN
15
+
16
+ @interface RCTNativeHTML5AdManager : RCTViewManager
17
+ @end
18
+
19
+ NS_ASSUME_NONNULL_END
20
+ #endif