@rafaykhan021/mas-capacitor 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.
@@ -0,0 +1,241 @@
1
+ import Foundation
2
+ import Yodo1MasCore
3
+
4
+ @objc public class Yodo1Mas: NSObject,
5
+ Yodo1MasAppOpenAdDelegate,
6
+ Yodo1MasInterstitialDelegate,
7
+ Yodo1MasRewardDelegate {
8
+
9
+ private var isInitialized = false
10
+ private var initCallbackFired = false
11
+
12
+ private var emitEvent: ((String, [String: Any]) -> Void)?
13
+
14
+ private var lastPlacementIdByAdType: [String: String] = [
15
+ "appopen": "default",
16
+ "interstitial": "default",
17
+ "rewarded": "default"
18
+ ]
19
+
20
+ public func setEventEmitter(_ emitter: @escaping (String, [String: Any]) -> Void) {
21
+ emitEvent = emitter
22
+ }
23
+
24
+ public func attachDelegates() {
25
+ DispatchQueue.main.async {
26
+ Yodo1MasCore.Yodo1MasAppOpenAd.sharedInstance().adDelegate = self
27
+ Yodo1MasCore.Yodo1MasInterstitialAd.sharedInstance().adDelegate = self
28
+ Yodo1MasCore.Yodo1MasRewardAd.sharedInstance().adDelegate = self
29
+ }
30
+ }
31
+
32
+ public func initialize(
33
+ appKey: String,
34
+ coppa: Bool,
35
+ gdpr: Bool,
36
+ ccpa: Bool,
37
+ autoDelayIfLoadFail: Bool,
38
+ completion: @escaping ([String: Any]) -> Void
39
+ ) {
40
+ DispatchQueue.main.async {
41
+ Yodo1MasCore.Yodo1Mas.sharedInstance().isCOPPAAgeRestricted = coppa
42
+ Yodo1MasCore.Yodo1Mas.sharedInstance().isGDPRUserConsent = gdpr
43
+ Yodo1MasCore.Yodo1Mas.sharedInstance().isCCPADoNotSell = ccpa
44
+
45
+ Yodo1MasAppOpenAd.sharedInstance().autoDelayIfLoadFail = autoDelayIfLoadFail
46
+ Yodo1MasRewardAd.sharedInstance().autoDelayIfLoadFail = autoDelayIfLoadFail
47
+ Yodo1MasInterstitialAd.sharedInstance().autoDelayIfLoadFail = autoDelayIfLoadFail
48
+
49
+ if self.isInitialized {
50
+ self.emitEvent?("initialized", [:])
51
+ completion(["initialized": true])
52
+ return
53
+ }
54
+
55
+ self.initCallbackFired = false
56
+
57
+ Yodo1MasCore.Yodo1Mas.sharedInstance().initMas(withAppKey: appKey) {
58
+ if self.initCallbackFired { return }
59
+ self.initCallbackFired = true
60
+ self.isInitialized = true
61
+
62
+ self.emitEvent?("initialized", [:])
63
+ completion(["initialized": true])
64
+ } fail: { error in
65
+ if self.initCallbackFired { return }
66
+ self.initCallbackFired = true
67
+ self.isInitialized = false
68
+
69
+ let payload: [String: Any] = [
70
+ "errorCode": "\(error.code)",
71
+ "message": error.description ?? "MAS init failed"
72
+ ]
73
+ self.emitEvent?("initFailed", payload)
74
+ completion(payload.merging(["initialized": false]) { (_, old) in old })
75
+ }
76
+ }
77
+ }
78
+
79
+ public func loadAd(adType: String, completion: @escaping ([String: Any]) -> Void) {
80
+ guard isInitialized else {
81
+ completion(["ok": false, "action": "loadAd", "adType": adType, "message": "MAS is not initialized"])
82
+ return
83
+ }
84
+
85
+ DispatchQueue.main.async {
86
+ switch adType {
87
+ case "appopen":
88
+ Yodo1MasAppOpenAd.sharedInstance().load()
89
+ case "interstitial":
90
+ Yodo1MasInterstitialAd.sharedInstance().load()
91
+ case "rewarded":
92
+ Yodo1MasRewardAd.sharedInstance().load()
93
+ default:
94
+ completion(["ok": false, "action": "loadAd", "adType": adType, "message": "Unsupported adType"])
95
+ return
96
+ }
97
+
98
+ completion(["ok": true, "action": "loadAd", "adType": adType])
99
+ }
100
+ }
101
+
102
+ public func showAd(adType: String, placementId: String, completion: @escaping ([String: Any]) -> Void) {
103
+ guard isInitialized else {
104
+ completion(["ok": false, "action": "showAd", "adType": adType, "message": "MAS is not initialized"])
105
+ return
106
+ }
107
+
108
+ let trimmed = placementId.trimmingCharacters(in: .whitespacesAndNewlines)
109
+ let safePlacementId = trimmed.isEmpty ? "default" : trimmed
110
+ lastPlacementIdByAdType[adType] = safePlacementId
111
+
112
+ DispatchQueue.main.async {
113
+ switch adType {
114
+ case "appopen":
115
+ if Yodo1MasAppOpenAd.sharedInstance().isLoaded() {
116
+ Yodo1MasAppOpenAd.sharedInstance().show(withPlacement: safePlacementId)
117
+ } else {
118
+ self.emitEvent?("appOpenOpenFailed", ["placementId": safePlacementId, "message": "AppOpen ad not loaded"])
119
+ }
120
+
121
+ case "interstitial":
122
+ if Yodo1MasInterstitialAd.sharedInstance().isLoaded() {
123
+ Yodo1MasInterstitialAd.sharedInstance().show(withPlacement: safePlacementId)
124
+ } else {
125
+ self.emitEvent?("interstitialOpenFailed", ["placementId": safePlacementId, "message": "Interstitial ad not loaded"])
126
+ }
127
+
128
+ case "rewarded":
129
+ if Yodo1MasRewardAd.sharedInstance().isLoaded() {
130
+ Yodo1MasRewardAd.sharedInstance().show(withPlacement: safePlacementId)
131
+ } else {
132
+ self.emitEvent?("rewardedOpenFailed", ["placementId": safePlacementId, "message": "Rewarded ad not loaded"])
133
+ }
134
+
135
+ default:
136
+ completion(["ok": false, "action": "showAd", "adType": adType, "placementId": safePlacementId, "message": "Unsupported adType"])
137
+ return
138
+ }
139
+
140
+ completion(["ok": true, "action": "showAd", "adType": adType, "placementId": safePlacementId])
141
+ }
142
+ }
143
+
144
+ public func isAdLoaded(adType: String, completion: @escaping ([String: Any]) -> Void) {
145
+ guard isInitialized else {
146
+ completion(["isLoaded": false, "adType": adType])
147
+ return
148
+ }
149
+
150
+ DispatchQueue.main.async {
151
+ let loaded: Bool
152
+ switch adType {
153
+ case "appopen":
154
+ loaded = Yodo1MasAppOpenAd.sharedInstance().isLoaded()
155
+ case "interstitial":
156
+ loaded = Yodo1MasInterstitialAd.sharedInstance().isLoaded()
157
+ case "rewarded":
158
+ loaded = Yodo1MasRewardAd.sharedInstance().isLoaded()
159
+ default:
160
+ completion(["isLoaded": false, "adType": adType])
161
+ return
162
+ }
163
+
164
+ completion(["isLoaded": loaded, "adType": adType])
165
+ }
166
+ }
167
+
168
+ private func placementId(for adType: String) -> String {
169
+ return lastPlacementIdByAdType[adType] ?? "default"
170
+ }
171
+
172
+ // MARK: - AppOpen events
173
+
174
+ public func onAppOpenAdLoaded(_ ad: Yodo1MasAppOpenAd) {
175
+ emitEvent?("appOpenLoaded", ["placementId": placementId(for: "appopen")])
176
+ }
177
+
178
+ public func onAppOpenAdFailedToLoad(_ ad: Yodo1MasAppOpenAd, _ error: Yodo1MasError) {
179
+ emitEvent?("appOpenLoadFailed", ["placementId": placementId(for: "appopen"), "errorCode": "\(error.code)", "message": error.description ?? ""])
180
+ }
181
+
182
+ public func onAppOpenAdOpened(_ ad: Yodo1MasAppOpenAd) {
183
+ emitEvent?("appOpenOpened", ["placementId": placementId(for: "appopen")])
184
+ }
185
+
186
+ public func onAppOpenAdFailedToOpen(_ ad: Yodo1MasAppOpenAd, _ error: Yodo1MasError) {
187
+ emitEvent?("appOpenOpenFailed", ["placementId": placementId(for: "appopen"), "errorCode": "\(error.code)", "message": error.description ?? ""])
188
+ }
189
+
190
+ public func onAppOpenAdClosed(_ ad: Yodo1MasAppOpenAd) {
191
+ emitEvent?("appOpenClosed", ["placementId": placementId(for: "appopen")])
192
+ }
193
+
194
+ // MARK: - Interstitial events
195
+
196
+ public func onInterstitialAdLoaded(_ ad: Yodo1MasInterstitialAd) {
197
+ emitEvent?("interstitialLoaded", ["placementId": placementId(for: "interstitial")])
198
+ }
199
+
200
+ public func onInterstitialAdFailedToLoad(_ ad: Yodo1MasInterstitialAd, _ error: Yodo1MasError) {
201
+ emitEvent?("interstitialLoadFailed", ["placementId": placementId(for: "interstitial"), "errorCode": "\(error.code)", "message": error.description ?? ""])
202
+ }
203
+
204
+ public func onInterstitialAdOpened(_ ad: Yodo1MasInterstitialAd) {
205
+ emitEvent?("interstitialOpened", ["placementId": placementId(for: "interstitial")])
206
+ }
207
+
208
+ public func onInterstitialAdFailedToOpen(_ ad: Yodo1MasInterstitialAd, _ error: Yodo1MasError) {
209
+ emitEvent?("interstitialOpenFailed", ["placementId": placementId(for: "interstitial"), "errorCode": "\(error.code)", "message": error.description ?? ""])
210
+ }
211
+
212
+ public func onInterstitialAdClosed(_ ad: Yodo1MasInterstitialAd) {
213
+ emitEvent?("interstitialClosed", ["placementId": placementId(for: "interstitial")])
214
+ }
215
+
216
+ // MARK: - Rewarded events
217
+
218
+ public func onRewardAdLoaded(_ ad: Yodo1MasRewardAd) {
219
+ emitEvent?("rewardedLoaded", ["placementId": placementId(for: "rewarded")])
220
+ }
221
+
222
+ public func onRewardAdFailedToLoad(_ ad: Yodo1MasRewardAd, _ error: Yodo1MasError) {
223
+ emitEvent?("rewardedLoadFailed", ["placementId": placementId(for: "rewarded"), "errorCode": "\(error.code)", "message": error.description ?? ""])
224
+ }
225
+
226
+ public func onRewardAdOpened(_ ad: Yodo1MasRewardAd) {
227
+ emitEvent?("rewardedOpened", ["placementId": placementId(for: "rewarded")])
228
+ }
229
+
230
+ public func onRewardAdFailedToOpen(_ ad: Yodo1MasRewardAd, _ error: Yodo1MasError) {
231
+ emitEvent?("rewardedOpenFailed", ["placementId": placementId(for: "rewarded"), "errorCode": "\(error.code)", "message": error.description ?? ""])
232
+ }
233
+
234
+ public func onRewardAdClosed(_ ad: Yodo1MasRewardAd) {
235
+ emitEvent?("rewardedClosed", ["placementId": placementId(for: "rewarded")])
236
+ }
237
+
238
+ public func onRewardAdEarned(_ ad: Yodo1MasRewardAd) {
239
+ emitEvent?("rewardedEarned", ["placementId": placementId(for: "rewarded")])
240
+ }
241
+ }
@@ -0,0 +1,84 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ @objc(Yodo1MasPlugin)
5
+ public class Yodo1MasPlugin: CAPPlugin, CAPBridgedPlugin {
6
+ public let identifier = "Yodo1MasPlugin"
7
+ public let jsName = "Yodo1Mas"
8
+ public let pluginMethods: [CAPPluginMethod] = [
9
+ CAPPluginMethod(name: "initialize", returnType: CAPPluginReturnPromise),
10
+ CAPPluginMethod(name: "loadAd", returnType: CAPPluginReturnPromise),
11
+ CAPPluginMethod(name: "showAd", returnType: CAPPluginReturnPromise),
12
+ CAPPluginMethod(name: "isAdLoaded", returnType: CAPPluginReturnPromise),
13
+ ]
14
+
15
+ private let implementation = Yodo1Mas()
16
+
17
+ public override func load() {
18
+ implementation.setEventEmitter { [weak self] eventName, payload in
19
+ self?.notifyListeners(eventName, data: payload)
20
+ }
21
+ implementation.attachDelegates()
22
+ }
23
+
24
+ @objc func initialize(_ call: CAPPluginCall) {
25
+ let appKey = call.getString("appKey") ?? ""
26
+ if appKey.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
27
+ call.reject("Missing required field: appKey")
28
+ return
29
+ }
30
+
31
+ let coppa = call.getBool("coppa") ?? false
32
+ let gdpr = call.getBool("gdpr") ?? true
33
+ let ccpa = call.getBool("ccpa") ?? false
34
+ let autoDelayIfLoadFail = call.getBool("autoDelayIfLoadFail") ?? true
35
+
36
+ implementation.initialize(
37
+ appKey: appKey,
38
+ coppa: coppa,
39
+ gdpr: gdpr,
40
+ ccpa: ccpa,
41
+ autoDelayIfLoadFail: autoDelayIfLoadFail
42
+ ) { result in
43
+ call.resolve(result)
44
+ }
45
+ }
46
+
47
+ @objc func loadAd(_ call: CAPPluginCall) {
48
+ let adType = call.getString("adType") ?? ""
49
+ if adType.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
50
+ call.reject("Missing required field: adType")
51
+ return
52
+ }
53
+
54
+ implementation.loadAd(adType: adType) { result in
55
+ call.resolve(result)
56
+ }
57
+ }
58
+
59
+ @objc func showAd(_ call: CAPPluginCall) {
60
+ let adType = call.getString("adType") ?? ""
61
+ if adType.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
62
+ call.reject("Missing required field: adType")
63
+ return
64
+ }
65
+
66
+ let placementId = call.getString("placementId") ?? "default"
67
+
68
+ implementation.showAd(adType: adType, placementId: placementId) { result in
69
+ call.resolve(result)
70
+ }
71
+ }
72
+
73
+ @objc func isAdLoaded(_ call: CAPPluginCall) {
74
+ let adType = call.getString("adType") ?? ""
75
+ if adType.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
76
+ call.reject("Missing required field: adType")
77
+ return
78
+ }
79
+
80
+ implementation.isAdLoaded(adType: adType) { result in
81
+ call.resolve(result)
82
+ }
83
+ }
84
+ }
@@ -0,0 +1,15 @@
1
+ import XCTest
2
+ @testable import Yodo1MasPlugin
3
+
4
+ class Yodo1MasTests: XCTestCase {
5
+ func testEcho() {
6
+ // This is an example of a functional test case for a plugin.
7
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
8
+
9
+ let implementation = Yodo1Mas()
10
+ let value = "Hello, World!"
11
+ let result = implementation.echo(value)
12
+
13
+ XCTAssertEqual(value, result)
14
+ }
15
+ }
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "publishConfig": {
3
+ "access": "public"
4
+ },
5
+
6
+ "name": "@rafaykhan021/mas-capacitor",
7
+ "version": "1.0.0",
8
+ "description": "A Capacitor Plugin for Yodo1 MAS",
9
+ "main": "dist/plugin.cjs.js",
10
+ "module": "dist/esm/index.js",
11
+ "types": "dist/esm/index.d.ts",
12
+ "unpkg": "dist/plugin.js",
13
+ "files": [
14
+ "android/src/main/",
15
+ "android/build.gradle",
16
+ "dist/",
17
+ "ios/Sources",
18
+ "ios/Tests",
19
+ "Package.swift",
20
+ "Yodo1MasCapacitor.podspec"
21
+ ],
22
+ "author": "Yodo1",
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/rafaykhan99/yodo1-mas-capacitor.git"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/rafaykhan99/yodo1-mas-capacitor/issues"
30
+ },
31
+ "keywords": [
32
+ "capacitor",
33
+ "plugin",
34
+ "native"
35
+ ],
36
+ "scripts": {
37
+ "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
38
+ "verify:ios": "xcodebuild -scheme Yodo1MasCapacitor -destination generic/platform=iOS",
39
+ "verify:android": "cd android && ./gradlew clean build test && cd ..",
40
+ "verify:web": "npm run build",
41
+ "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
42
+ "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
43
+ "eslint": "eslint . --ext ts",
44
+ "prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
45
+ "swiftlint": "node-swiftlint",
46
+ "docgen": "docgen --api Yodo1MasPlugin --output-readme README.md --output-json dist/docs.json",
47
+ "build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
48
+ "clean": "rimraf ./dist",
49
+ "watch": "tsc --watch",
50
+ "prepublishOnly": "npm run build"
51
+ },
52
+ "devDependencies": {
53
+ "@capacitor/android": "^8.0.0",
54
+ "@capacitor/core": "^8.0.0",
55
+ "@capacitor/docgen": "^0.3.1",
56
+ "@capacitor/ios": "^8.0.0",
57
+ "@ionic/eslint-config": "^0.4.0",
58
+ "@ionic/prettier-config": "^4.0.0",
59
+ "@ionic/swiftlint-config": "^2.0.0",
60
+ "eslint": "^8.57.1",
61
+ "prettier": "^3.6.2",
62
+ "prettier-plugin-java": "^2.7.7",
63
+ "rimraf": "^6.1.0",
64
+ "rollup": "^4.53.2",
65
+ "swiftlint": "^2.0.0",
66
+ "typescript": "^5.9.3"
67
+ },
68
+ "peerDependencies": {
69
+ "@capacitor/core": ">=8.0.0"
70
+ },
71
+ "prettier": "@ionic/prettier-config",
72
+ "swiftlint": "@ionic/swiftlint-config",
73
+ "eslintConfig": {
74
+ "extends": "@ionic/eslint-config/recommended"
75
+ },
76
+ "capacitor": {
77
+ "ios": {
78
+ "src": "ios"
79
+ },
80
+ "android": {
81
+ "src": "android"
82
+ }
83
+ }
84
+ }