react-native-empower-mobile-ads 1.0.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 (69) hide show
  1. package/README.md +149 -0
  2. package/ios/EmpowerAdsModule.m +21 -0
  3. package/ios/EmpowerAdsModule.swift +111 -0
  4. package/ios/EmpowerAppOpenModule.m +16 -0
  5. package/ios/EmpowerAppOpenModule.swift +55 -0
  6. package/ios/EmpowerBannerViewManager.m +14 -0
  7. package/ios/EmpowerBannerViewManager.swift +121 -0
  8. package/ios/EmpowerInterstitialModule.m +18 -0
  9. package/ios/EmpowerInterstitialModule.swift +62 -0
  10. package/ios/EmpowerRewardedModule.m +18 -0
  11. package/ios/EmpowerRewardedModule.swift +70 -0
  12. package/lib/commonjs/AppOpenAd.js +40 -0
  13. package/lib/commonjs/AppOpenAd.js.map +1 -0
  14. package/lib/commonjs/BannerAd.js +69 -0
  15. package/lib/commonjs/BannerAd.js.map +1 -0
  16. package/lib/commonjs/EmpowerAds.js +62 -0
  17. package/lib/commonjs/EmpowerAds.js.map +1 -0
  18. package/lib/commonjs/InterstitialAd.js +40 -0
  19. package/lib/commonjs/InterstitialAd.js.map +1 -0
  20. package/lib/commonjs/RewardedAd.js +41 -0
  21. package/lib/commonjs/RewardedAd.js.map +1 -0
  22. package/lib/commonjs/StickyAd.js +71 -0
  23. package/lib/commonjs/StickyAd.js.map +1 -0
  24. package/lib/commonjs/index.js +61 -0
  25. package/lib/commonjs/index.js.map +1 -0
  26. package/lib/commonjs/types.js +34 -0
  27. package/lib/commonjs/types.js.map +1 -0
  28. package/lib/module/AppOpenAd.js +34 -0
  29. package/lib/module/AppOpenAd.js.map +1 -0
  30. package/lib/module/BannerAd.js +61 -0
  31. package/lib/module/BannerAd.js.map +1 -0
  32. package/lib/module/EmpowerAds.js +56 -0
  33. package/lib/module/EmpowerAds.js.map +1 -0
  34. package/lib/module/InterstitialAd.js +34 -0
  35. package/lib/module/InterstitialAd.js.map +1 -0
  36. package/lib/module/RewardedAd.js +35 -0
  37. package/lib/module/RewardedAd.js.map +1 -0
  38. package/lib/module/StickyAd.js +63 -0
  39. package/lib/module/StickyAd.js.map +1 -0
  40. package/lib/module/index.js +15 -0
  41. package/lib/module/index.js.map +1 -0
  42. package/lib/module/types.js +37 -0
  43. package/lib/module/types.js.map +1 -0
  44. package/lib/typescript/AppOpenAd.d.ts +21 -0
  45. package/lib/typescript/AppOpenAd.d.ts.map +1 -0
  46. package/lib/typescript/BannerAd.d.ts +4 -0
  47. package/lib/typescript/BannerAd.d.ts.map +1 -0
  48. package/lib/typescript/EmpowerAds.d.ts +37 -0
  49. package/lib/typescript/EmpowerAds.d.ts.map +1 -0
  50. package/lib/typescript/InterstitialAd.d.ts +24 -0
  51. package/lib/typescript/InterstitialAd.d.ts.map +1 -0
  52. package/lib/typescript/RewardedAd.d.ts +25 -0
  53. package/lib/typescript/RewardedAd.d.ts.map +1 -0
  54. package/lib/typescript/StickyAd.d.ts +4 -0
  55. package/lib/typescript/StickyAd.d.ts.map +1 -0
  56. package/lib/typescript/index.d.ts +8 -0
  57. package/lib/typescript/index.d.ts.map +1 -0
  58. package/lib/typescript/types.d.ts +80 -0
  59. package/lib/typescript/types.d.ts.map +1 -0
  60. package/package.json +63 -0
  61. package/react-native-empower-mobile-ads.podspec +27 -0
  62. package/src/AppOpenAd.ts +43 -0
  63. package/src/BannerAd.tsx +81 -0
  64. package/src/EmpowerAds.ts +63 -0
  65. package/src/InterstitialAd.ts +50 -0
  66. package/src/RewardedAd.ts +51 -0
  67. package/src/StickyAd.tsx +84 -0
  68. package/src/index.ts +23 -0
  69. package/src/types.ts +95 -0
package/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # react-native-empower-mobile-ads
2
+
3
+ React Native bridge for EmpowerMobileAds SDK. Supports banner, sticky, interstitial, rewarded and app open ad formats.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install react-native-empower-mobile-ads
9
+ ```
10
+
11
+ ### iOS Setup
12
+
13
+ **1.** Add the Empower private spec repo to your `Podfile`:
14
+
15
+ ```ruby
16
+ source 'https://github.com/empowernet/specs.git'
17
+ source 'https://cdn.cocoapods.org/'
18
+ ```
19
+
20
+ **2.** Install pods:
21
+
22
+ ```bash
23
+ cd ios && pod install
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ### Initialize SDK
29
+
30
+ Call this once on app startup, before loading any ads:
31
+
32
+ ```tsx
33
+ import { EmpowerAds } from 'react-native-empower-mobile-ads';
34
+
35
+ await EmpowerAds.initialize('YOUR_APP_IDENTIFIER', {
36
+ testMode: false,
37
+ logLevel: 'all',
38
+ });
39
+ ```
40
+
41
+ ### Banner Ad
42
+
43
+ ```tsx
44
+ import { BannerAd } from 'react-native-empower-mobile-ads';
45
+
46
+ <BannerAd
47
+ zoneId="your_zone_id"
48
+ style={{ width: 320, height: 50 }}
49
+ onAdLoaded={() => console.log('Ad loaded')}
50
+ onAdFailed={(error) => console.log('Ad failed:', error)}
51
+ onAdClicked={() => console.log('Ad clicked')}
52
+ onSizeChanged={({ width, height }) => console.log('New size:', width, height)}
53
+ />
54
+ ```
55
+
56
+ ### Sticky Ad
57
+
58
+ ```tsx
59
+ import { StickyAd } from 'react-native-empower-mobile-ads';
60
+
61
+ <StickyAd
62
+ zoneId="your_zone_id"
63
+ style={{ width: 320, height: 50 }}
64
+ onAdLoaded={() => console.log('Sticky loaded')}
65
+ />
66
+ ```
67
+
68
+ ### Interstitial Ad
69
+
70
+ ```tsx
71
+ import { InterstitialAd } from 'react-native-empower-mobile-ads';
72
+
73
+ // Load
74
+ await InterstitialAd.load('your_zone_id');
75
+
76
+ // Show when ready
77
+ if (await InterstitialAd.isReady()) {
78
+ await InterstitialAd.show();
79
+ }
80
+
81
+ // Listen for status changes
82
+ const remove = InterstitialAd.addEventListener('statusChanged', (event) => {
83
+ console.log('Interstitial status:', event.status);
84
+ });
85
+
86
+ // Cleanup
87
+ remove();
88
+ ```
89
+
90
+ ### Rewarded Ad
91
+
92
+ ```tsx
93
+ import { RewardedAd } from 'react-native-empower-mobile-ads';
94
+
95
+ // Listen for reward
96
+ const remove = RewardedAd.addEventListener('statusChanged', (event) => {
97
+ if (event.status === 'rewarded') {
98
+ // Grant the reward
99
+ }
100
+ });
101
+
102
+ // Load & show
103
+ await RewardedAd.load('your_zone_id');
104
+ if (await RewardedAd.isReady()) {
105
+ await RewardedAd.show();
106
+ }
107
+ ```
108
+
109
+ ### App Open Ad
110
+
111
+ ```tsx
112
+ import { AppOpenAd } from 'react-native-empower-mobile-ads';
113
+
114
+ await AppOpenAd.load('your_zone_id');
115
+ if (await AppOpenAd.isReady()) {
116
+ await AppOpenAd.show();
117
+ }
118
+ ```
119
+
120
+ ## Configuration
121
+
122
+ ```tsx
123
+ // Content page for ad targeting
124
+ EmpowerAds.setContentPage('https://example.com/article/123');
125
+
126
+ // Global targeting parameters
127
+ EmpowerAds.setGlobalTargeting({
128
+ category: ['sports', 'news'],
129
+ section: ['homepage'],
130
+ });
131
+
132
+ // User segments
133
+ EmpowerAds.setSegments(['premium_user']);
134
+
135
+ // GDPR - non-personalized ads
136
+ EmpowerAds.setNonPersonalized(true);
137
+
138
+ // Disable all ads
139
+ EmpowerAds.setAdsDisabled(true);
140
+
141
+ // Show remove ads button
142
+ EmpowerAds.setShowRemoveAdsButton(true);
143
+ ```
144
+
145
+ ## Requirements
146
+
147
+ - React Native >= 0.71
148
+ - iOS >= 13.0
149
+ - EmpowerMobileAds SDK (via CocoaPods private spec repo)
@@ -0,0 +1,21 @@
1
+ #import <React/RCTBridgeModule.h>
2
+ #import <React/RCTEventEmitter.h>
3
+
4
+ @interface RCT_EXTERN_MODULE(EmpowerAdsModule, RCTEventEmitter)
5
+
6
+ RCT_EXTERN_METHOD(initialize:(NSString *)appId
7
+ options:(NSDictionary *)options
8
+ resolver:(RCTPromiseResolveBlock)resolver
9
+ rejecter:(RCTPromiseRejectBlock)rejecter)
10
+
11
+ RCT_EXTERN_METHOD(setContentPage:(NSString *)url)
12
+ RCT_EXTERN_METHOD(setGlobalTargeting:(NSDictionary *)targeting)
13
+ RCT_EXTERN_METHOD(setSegments:(NSArray *)segments)
14
+ RCT_EXTERN_METHOD(setNonPersonalized:(BOOL)value)
15
+ RCT_EXTERN_METHOD(setAdsDisabled:(BOOL)value)
16
+ RCT_EXTERN_METHOD(setShowRemoveAdsButton:(BOOL)value)
17
+
18
+ RCT_EXTERN_METHOD(getNoktaId:(RCTPromiseResolveBlock)resolver
19
+ rejecter:(RCTPromiseRejectBlock)rejecter)
20
+
21
+ @end
@@ -0,0 +1,111 @@
1
+ import Foundation
2
+ import React
3
+ import EmpowerMobileAds
4
+
5
+ @objc(EmpowerAdsModule)
6
+ class EmpowerAdsModule: RCTEventEmitter {
7
+
8
+ override static func moduleName() -> String! { "EmpowerAdsModule" }
9
+ override static func requiresMainQueueSetup() -> Bool { true }
10
+
11
+ override func supportedEvents() -> [String]! {
12
+ ["onAdsReady", "onAdsFailed"]
13
+ }
14
+
15
+ @objc func initialize(_ appId: String, options: NSDictionary, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
16
+ DispatchQueue.main.async {
17
+ let testMode = options["testMode"] as? Bool ?? false
18
+ let appVersion = options["appVersion"] as? String ?? "1"
19
+ let vParam = options["vParam"] as? String
20
+
21
+ if let logLevel = options["logLevel"] as? String {
22
+ switch logLevel {
23
+ case "none": EMASettings.shared.logLevel = .none
24
+ case "error": EMASettings.shared.logLevel = .error
25
+ default: EMASettings.shared.logLevel = .all
26
+ }
27
+ }
28
+
29
+ if let nonPersonalized = options["nonPersonalized"] as? Bool {
30
+ EMASettings.shared.isAdsNonPersonalized = nonPersonalized
31
+ }
32
+
33
+ // Set root view controller
34
+ EMASettings.shared.rootViewController = RCTPresentedViewController()
35
+
36
+ EMAManager.shared.initAd(appId, appVersion, testMode, vParam)
37
+
38
+ // Listen for config ready
39
+ EMAManager.shared.appViewDelegates.append(AppViewBridge(onComplete: { [weak self] in
40
+ self?.sendEvent(withName: "onAdsReady", body: nil)
41
+ resolver(nil)
42
+ }, onFail: { [weak self] in
43
+ self?.sendEvent(withName: "onAdsFailed", body: nil)
44
+ rejecter("ADS_INIT_FAILED", "EmpowerMobileAds initialization failed", nil)
45
+ }))
46
+ }
47
+ }
48
+
49
+ @objc func setContentPage(_ url: String) {
50
+ DispatchQueue.main.async {
51
+ EMAManager.shared.contentPage = url
52
+ }
53
+ }
54
+
55
+ @objc func setGlobalTargeting(_ targeting: NSDictionary) {
56
+ DispatchQueue.main.async {
57
+ var result: [String: [String]] = [:]
58
+ for (key, value) in targeting {
59
+ if let k = key as? String, let v = value as? [String] {
60
+ result[k] = v
61
+ }
62
+ }
63
+ EMAManager.shared.globalTargeting = result
64
+ }
65
+ }
66
+
67
+ @objc func setSegments(_ segments: NSArray) {
68
+ DispatchQueue.main.async {
69
+ EMAManager.shared.segments = segments as? [String] ?? []
70
+ }
71
+ }
72
+
73
+ @objc func setNonPersonalized(_ value: Bool) {
74
+ DispatchQueue.main.async {
75
+ EMASettings.shared.isAdsNonPersonalized = value
76
+ }
77
+ }
78
+
79
+ @objc func setAdsDisabled(_ value: Bool) {
80
+ DispatchQueue.main.async {
81
+ EMASettings.shared.isAdsDisabled = value
82
+ }
83
+ }
84
+
85
+ @objc func setShowRemoveAdsButton(_ value: Bool) {
86
+ DispatchQueue.main.async {
87
+ EMASettings.shared.showRemoveAdsButton = value
88
+ }
89
+ }
90
+
91
+ @objc func getNoktaId(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
92
+ DispatchQueue.main.async {
93
+ let noktaId = EMAManager.shared.getNoktaId()
94
+ resolver(noktaId)
95
+ }
96
+ }
97
+ }
98
+
99
+ // MARK: - AppViewDelegate Bridge
100
+ private class AppViewBridge: NSObject, AppViewDelegate {
101
+ let onComplete: () -> Void
102
+ let onFail: () -> Void
103
+
104
+ init(onComplete: @escaping () -> Void, onFail: @escaping () -> Void) {
105
+ self.onComplete = onComplete
106
+ self.onFail = onFail
107
+ }
108
+
109
+ func appViewCompleted() { onComplete() }
110
+ func appViewFailed() { onFail() }
111
+ }
@@ -0,0 +1,16 @@
1
+ #import <React/RCTBridgeModule.h>
2
+ #import <React/RCTEventEmitter.h>
3
+
4
+ @interface RCT_EXTERN_MODULE(EmpowerAppOpenModule, RCTEventEmitter)
5
+
6
+ RCT_EXTERN_METHOD(load:(NSString *)zoneId
7
+ resolver:(RCTPromiseResolveBlock)resolver
8
+ rejecter:(RCTPromiseRejectBlock)rejecter)
9
+
10
+ RCT_EXTERN_METHOD(isReady:(RCTPromiseResolveBlock)resolver
11
+ rejecter:(RCTPromiseRejectBlock)rejecter)
12
+
13
+ RCT_EXTERN_METHOD(show:(RCTPromiseResolveBlock)resolver
14
+ rejecter:(RCTPromiseRejectBlock)rejecter)
15
+
16
+ @end
@@ -0,0 +1,55 @@
1
+ import Foundation
2
+ import React
3
+ import EmpowerMobileAds
4
+
5
+ @objc(EmpowerAppOpenModule)
6
+ class EmpowerAppOpenModule: RCTEventEmitter, AdStatusDelegate {
7
+
8
+ override static func moduleName() -> String! { "EmpowerAppOpenModule" }
9
+ override static func requiresMainQueueSetup() -> Bool { true }
10
+
11
+ override func supportedEvents() -> [String]! {
12
+ ["onAppOpenStatusChanged"]
13
+ }
14
+
15
+ @objc func load(_ zoneId: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
16
+ DispatchQueue.main.async {
17
+ EMAManager.shared.loadAppOpen(zoneId: zoneId)
18
+ resolver(nil)
19
+ }
20
+ }
21
+
22
+ @objc func isReady(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
23
+ DispatchQueue.main.async {
24
+ resolver(EMAManager.shared.isAppOpenReady())
25
+ }
26
+ }
27
+
28
+ @objc func show(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
29
+ DispatchQueue.main.async {
30
+ guard let rootVC = EMASettings.shared.rootViewController ?? RCTPresentedViewController() else {
31
+ rejecter("NO_VC", "No root view controller available", nil)
32
+ return
33
+ }
34
+ EMAManager.shared.showAppOpen(from: rootVC)
35
+ resolver(nil)
36
+ }
37
+ }
38
+
39
+ // MARK: - AdStatusDelegate
40
+
41
+ func empowerAppOpenStatusChanged(_ manager: EmpowerAppOpenManager) {
42
+ let statusString: String
43
+ switch manager.status {
44
+ case .ready: statusString = "ready"
45
+ case .failed: statusString = "failed"
46
+ case .used: statusString = "used"
47
+ case .willPresent: statusString = "willPresent"
48
+ default: statusString = "unknown"
49
+ }
50
+
51
+ sendEvent(withName: "onAppOpenStatusChanged", body: [
52
+ "status": statusString,
53
+ ])
54
+ }
55
+ }
@@ -0,0 +1,14 @@
1
+ #import <React/RCTViewManager.h>
2
+
3
+ @interface RCT_EXTERN_MODULE(EmpowerBannerViewManager, RCTViewManager)
4
+
5
+ RCT_EXPORT_VIEW_PROPERTY(zoneId, NSString)
6
+ RCT_EXPORT_VIEW_PROPERTY(adType, NSString)
7
+ RCT_EXPORT_VIEW_PROPERTY(keywords, NSString)
8
+ RCT_EXPORT_VIEW_PROPERTY(customParameters, NSDictionary)
9
+ RCT_EXPORT_VIEW_PROPERTY(onAdLoaded, RCTDirectEventBlock)
10
+ RCT_EXPORT_VIEW_PROPERTY(onAdFailed, RCTDirectEventBlock)
11
+ RCT_EXPORT_VIEW_PROPERTY(onAdClicked, RCTDirectEventBlock)
12
+ RCT_EXPORT_VIEW_PROPERTY(onSizeChanged, RCTDirectEventBlock)
13
+
14
+ @end
@@ -0,0 +1,121 @@
1
+ import Foundation
2
+ import UIKit
3
+ import React
4
+ import EmpowerMobileAds
5
+
6
+ @objc(EmpowerBannerViewManager)
7
+ class EmpowerBannerViewManager: RCTViewManager {
8
+
9
+ override static func moduleName() -> String! { "EmpowerBannerView" }
10
+ override static func requiresMainQueueSetup() -> Bool { true }
11
+
12
+ override func view() -> UIView! {
13
+ return EmpowerBannerView(bridge: self.bridge)
14
+ }
15
+ }
16
+
17
+ // MARK: - EmpowerBannerView
18
+ class EmpowerBannerView: UIView, AdStatusDelegate {
19
+
20
+ private var bridge: RCTBridge?
21
+ private var zoneManager: EmpowerZoneManager?
22
+ private var containerView: UIView!
23
+ private var isAdLoaded = false
24
+
25
+ // React props
26
+ @objc var zoneId: String = "" { didSet { loadAdIfReady() } }
27
+ @objc var adType: String = "banner"
28
+ @objc var keywords: String?
29
+ @objc var customParameters: NSDictionary?
30
+
31
+ // React event callbacks
32
+ @objc var onAdLoaded: RCTDirectEventBlock?
33
+ @objc var onAdFailed: RCTDirectEventBlock?
34
+ @objc var onAdClicked: RCTDirectEventBlock?
35
+ @objc var onSizeChanged: RCTDirectEventBlock?
36
+
37
+ init(bridge: RCTBridge?) {
38
+ self.bridge = bridge
39
+ super.init(frame: .zero)
40
+
41
+ containerView = UIView()
42
+ containerView.translatesAutoresizingMaskIntoConstraints = false
43
+ addSubview(containerView)
44
+
45
+ NSLayoutConstraint.activate([
46
+ containerView.topAnchor.constraint(equalTo: topAnchor),
47
+ containerView.leadingAnchor.constraint(equalTo: leadingAnchor),
48
+ containerView.trailingAnchor.constraint(equalTo: trailingAnchor),
49
+ containerView.bottomAnchor.constraint(equalTo: bottomAnchor),
50
+ ])
51
+ }
52
+
53
+ required init?(coder: NSCoder) { fatalError("init(coder:) not supported") }
54
+
55
+ // MARK: - Load
56
+
57
+ private func loadAdIfReady() {
58
+ guard !zoneId.isEmpty, !isAdLoaded else { return }
59
+ guard let rootVC = EMASettings.shared.rootViewController ?? RCTPresentedViewController() else { return }
60
+
61
+ isAdLoaded = true
62
+
63
+ var customParams: [String: [String]]? = nil
64
+ if let cp = customParameters as? [String: [String]] {
65
+ customParams = cp
66
+ }
67
+
68
+ DispatchQueue.main.async { [weak self] in
69
+ guard let self = self else { return }
70
+
71
+ self.zoneManager = EMAManager.shared.loadBannerAd(
72
+ viewController: rootVC,
73
+ zoneId: self.zoneId,
74
+ bannerContainer: self.containerView,
75
+ delegate: self,
76
+ adConfiguration: nil,
77
+ customParameters: customParams,
78
+ category: nil,
79
+ keywords: self.keywords
80
+ )
81
+ }
82
+ }
83
+
84
+ // MARK: - AdStatusDelegate
85
+
86
+ func bannerStatusChanged(_ manager: EmpowerBannerManager) {
87
+ DispatchQueue.main.async { [weak self] in
88
+ guard let self = self else { return }
89
+
90
+ switch manager.status {
91
+ case .ready:
92
+ self.onAdLoaded?([:])
93
+
94
+ // Report actual size back to RN so the JS side can adjust layout
95
+ let adWidth = manager.bannerModel.width
96
+ let adHeight = manager.bannerModel.height
97
+ if adWidth > 0, adHeight > 0 {
98
+ self.onSizeChanged?([
99
+ "width": adWidth,
100
+ "height": adHeight,
101
+ ])
102
+ }
103
+
104
+ case .failed:
105
+ self.onAdFailed?(["error": "Ad failed to load"])
106
+
107
+ case .willPresent, .willLeave:
108
+ self.onAdClicked?([:])
109
+
110
+ default:
111
+ break
112
+ }
113
+ }
114
+ }
115
+
116
+ // MARK: - Cleanup
117
+
118
+ deinit {
119
+ zoneManager?.destroy()
120
+ }
121
+ }
@@ -0,0 +1,18 @@
1
+ #import <React/RCTBridgeModule.h>
2
+ #import <React/RCTEventEmitter.h>
3
+
4
+ @interface RCT_EXTERN_MODULE(EmpowerInterstitialModule, RCTEventEmitter)
5
+
6
+ RCT_EXTERN_METHOD(load:(NSString *)zoneId
7
+ keywords:(NSString *)keywords
8
+ customParameters:(NSDictionary *)customParameters
9
+ resolver:(RCTPromiseResolveBlock)resolver
10
+ rejecter:(RCTPromiseRejectBlock)rejecter)
11
+
12
+ RCT_EXTERN_METHOD(isReady:(RCTPromiseResolveBlock)resolver
13
+ rejecter:(RCTPromiseRejectBlock)rejecter)
14
+
15
+ RCT_EXTERN_METHOD(show:(RCTPromiseResolveBlock)resolver
16
+ rejecter:(RCTPromiseRejectBlock)rejecter)
17
+
18
+ @end
@@ -0,0 +1,62 @@
1
+ import Foundation
2
+ import React
3
+ import EmpowerMobileAds
4
+
5
+ @objc(EmpowerInterstitialModule)
6
+ class EmpowerInterstitialModule: RCTEventEmitter, AdStatusDelegate {
7
+
8
+ private var zoneManager: EmpowerZoneManager?
9
+
10
+ override static func moduleName() -> String! { "EmpowerInterstitialModule" }
11
+ override static func requiresMainQueueSetup() -> Bool { true }
12
+
13
+ override func supportedEvents() -> [String]! {
14
+ ["onInterstitialStatusChanged"]
15
+ }
16
+
17
+ @objc func load(_ zoneId: String?, keywords: String?, customParameters: NSDictionary?,
18
+ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
19
+ DispatchQueue.main.async { [weak self] in
20
+ guard let self = self else { return }
21
+
22
+ var customParams: [String: [String]]? = nil
23
+ if let cp = customParameters as? [String: [String]] {
24
+ customParams = cp
25
+ }
26
+
27
+ EMAManager.shared.loadInterstitial(
28
+ zoneId: zoneId,
29
+ delegate: self,
30
+ customParameters: customParams,
31
+ keywords: keywords
32
+ )
33
+
34
+ resolver(nil)
35
+ }
36
+ }
37
+
38
+ @objc func isReady(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
39
+ DispatchQueue.main.async {
40
+ resolver(EMAManager.shared.isInterstitialReady())
41
+ }
42
+ }
43
+
44
+ @objc func show(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
45
+ DispatchQueue.main.async {
46
+ guard let rootVC = EMASettings.shared.rootViewController ?? RCTPresentedViewController() else {
47
+ rejecter("NO_VC", "No root view controller available", nil)
48
+ return
49
+ }
50
+ EMAManager.shared.showInterstitial(from: rootVC)
51
+ resolver(nil)
52
+ }
53
+ }
54
+
55
+ // MARK: - AdStatusDelegate
56
+
57
+ func interstitialStatusChanged(_ manager: EmpowerInterstitialManager) {
58
+ sendEvent(withName: "onInterstitialStatusChanged", body: [
59
+ "status": manager.status.rawValue,
60
+ ])
61
+ }
62
+ }
@@ -0,0 +1,18 @@
1
+ #import <React/RCTBridgeModule.h>
2
+ #import <React/RCTEventEmitter.h>
3
+
4
+ @interface RCT_EXTERN_MODULE(EmpowerRewardedModule, RCTEventEmitter)
5
+
6
+ RCT_EXTERN_METHOD(load:(NSString *)zoneId
7
+ keywords:(NSString *)keywords
8
+ customParameters:(NSDictionary *)customParameters
9
+ resolver:(RCTPromiseResolveBlock)resolver
10
+ rejecter:(RCTPromiseRejectBlock)rejecter)
11
+
12
+ RCT_EXTERN_METHOD(isReady:(RCTPromiseResolveBlock)resolver
13
+ rejecter:(RCTPromiseRejectBlock)rejecter)
14
+
15
+ RCT_EXTERN_METHOD(show:(RCTPromiseResolveBlock)resolver
16
+ rejecter:(RCTPromiseRejectBlock)rejecter)
17
+
18
+ @end
@@ -0,0 +1,70 @@
1
+ import Foundation
2
+ import React
3
+ import EmpowerMobileAds
4
+
5
+ @objc(EmpowerRewardedModule)
6
+ class EmpowerRewardedModule: RCTEventEmitter, AdStatusDelegate {
7
+
8
+ override static func moduleName() -> String! { "EmpowerRewardedModule" }
9
+ override static func requiresMainQueueSetup() -> Bool { true }
10
+
11
+ override func supportedEvents() -> [String]! {
12
+ ["onRewardedStatusChanged"]
13
+ }
14
+
15
+ @objc func load(_ zoneId: String?, keywords: String?, customParameters: NSDictionary?,
16
+ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
17
+ DispatchQueue.main.async { [weak self] in
18
+ guard let self = self else { return }
19
+
20
+ var customParams: [String: [String]]? = nil
21
+ if let cp = customParameters as? [String: [String]] {
22
+ customParams = cp
23
+ }
24
+
25
+ EMAManager.shared.loadRewarded(
26
+ zoneId: zoneId,
27
+ delegate: self,
28
+ customParameters: customParams,
29
+ keywords: keywords
30
+ )
31
+
32
+ resolver(nil)
33
+ }
34
+ }
35
+
36
+ @objc func isReady(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
37
+ DispatchQueue.main.async {
38
+ resolver(EMAManager.shared.isRewardedReady())
39
+ }
40
+ }
41
+
42
+ @objc func show(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
43
+ DispatchQueue.main.async {
44
+ guard let rootVC = EMASettings.shared.rootViewController ?? RCTPresentedViewController() else {
45
+ rejecter("NO_VC", "No root view controller available", nil)
46
+ return
47
+ }
48
+ EMAManager.shared.showRewarded(from: rootVC)
49
+ resolver(nil)
50
+ }
51
+ }
52
+
53
+ // MARK: - AdStatusDelegate
54
+
55
+ func rewardedStatusChanged(_ manager: EmpowerRewardedManager) {
56
+ let statusString: String
57
+ switch manager.status {
58
+ case .rewarded: statusString = "rewarded"
59
+ case .ready: statusString = "ready"
60
+ case .failed: statusString = "failed"
61
+ case .used: statusString = "used"
62
+ case .willPresent: statusString = "willPresent"
63
+ default: statusString = "unknown"
64
+ }
65
+
66
+ sendEvent(withName: "onRewardedStatusChanged", body: [
67
+ "status": statusString,
68
+ ])
69
+ }
70
+ }