@capgo/capacitor-admob 7.1.0 → 7.4.4
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.
- package/CapgoCapacitorAdmob.podspec +1 -0
- package/Package.swift +4 -2
- package/README.md +102 -44
- package/android/src/main/kotlin/admob/plus/capacitor/AdMobPlusPlugin.kt +12 -0
- package/dist/docs.json +283 -51
- package/dist/esm/definitions.d.ts +206 -3
- package/dist/esm/definitions.js +19 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/plugin.cjs.js +19 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +19 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/AdmobPlusPlugin/AdmobPlusPlugin.swift +223 -10
- package/ios/Sources/AdmobPlusPlugin/BannerAd.swift +143 -0
- package/ios/Sources/AdmobPlusPlugin/Generated.swift +40 -0
- package/ios/Sources/AdmobPlusPlugin/Helper.swift +68 -0
- package/ios/Sources/AdmobPlusPlugin/InterstitialAd.swift +92 -0
- package/ios/Sources/AdmobPlusPlugin/RewardedAd.swift +102 -0
- package/ios/Sources/AdmobPlusPlugin/RewardedInterstitialAd.swift +102 -0
- package/package.json +1 -1
- package/ios/Sources/AdmobPlusPlugin/AdmobPlus.swift +0 -8
|
@@ -1,26 +1,239 @@
|
|
|
1
1
|
import Capacitor
|
|
2
2
|
import Foundation
|
|
3
|
+
import GoogleMobileAds
|
|
4
|
+
import AppTrackingTransparency
|
|
3
5
|
|
|
4
6
|
@objc(AdmobPlusPlugin)
|
|
5
7
|
public class AdmobPlusPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
6
|
-
private let
|
|
8
|
+
private let pluginVersion: String = "7.4.4"
|
|
7
9
|
public let identifier = "AdmobPlusPlugin"
|
|
8
10
|
public let jsName = "AdMobPlus"
|
|
9
11
|
public let pluginMethods: [CAPPluginMethod] = [
|
|
10
|
-
CAPPluginMethod(name: "
|
|
12
|
+
CAPPluginMethod(name: "start", returnType: CAPPluginReturnPromise),
|
|
13
|
+
CAPPluginMethod(name: "configure", returnType: CAPPluginReturnPromise),
|
|
14
|
+
CAPPluginMethod(name: "configRequest", returnType: CAPPluginReturnPromise),
|
|
15
|
+
CAPPluginMethod(name: "adCreate", returnType: CAPPluginReturnPromise),
|
|
16
|
+
CAPPluginMethod(name: "adIsLoaded", returnType: CAPPluginReturnPromise),
|
|
17
|
+
CAPPluginMethod(name: "adLoad", returnType: CAPPluginReturnPromise),
|
|
18
|
+
CAPPluginMethod(name: "adShow", returnType: CAPPluginReturnPromise),
|
|
19
|
+
CAPPluginMethod(name: "adHide", returnType: CAPPluginReturnPromise),
|
|
20
|
+
CAPPluginMethod(name: "trackingAuthorizationStatus", returnType: CAPPluginReturnPromise),
|
|
21
|
+
CAPPluginMethod(name: "requestTrackingAuthorization", returnType: CAPPluginReturnPromise),
|
|
11
22
|
CAPPluginMethod(name: "getPluginVersion", returnType: CAPPluginReturnPromise)
|
|
12
23
|
]
|
|
13
|
-
private let implementation = AdmobPlus()
|
|
14
24
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
25
|
+
private var nextAdId = 1
|
|
26
|
+
private let adManager = AdManager.shared
|
|
27
|
+
|
|
28
|
+
@objc func start(_ call: CAPPluginCall) {
|
|
29
|
+
DispatchQueue.main.async {
|
|
30
|
+
GADMobileAds.sharedInstance().start { _ in
|
|
31
|
+
call.resolve()
|
|
32
|
+
}
|
|
33
|
+
}
|
|
20
34
|
}
|
|
21
35
|
|
|
22
|
-
@objc func
|
|
23
|
-
call.
|
|
36
|
+
@objc func configure(_ call: CAPPluginCall) {
|
|
37
|
+
let appMuted = call.getBool("appMuted")
|
|
38
|
+
let appVolume = call.getFloat("appVolume")
|
|
39
|
+
|
|
40
|
+
if let muted = appMuted {
|
|
41
|
+
GADMobileAds.sharedInstance().applicationMuted = muted
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if let volume = appVolume {
|
|
45
|
+
GADMobileAds.sharedInstance().applicationVolume = volume
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
call.resolve()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@objc func configRequest(_ call: CAPPluginCall) {
|
|
52
|
+
let requestConfiguration = GADMobileAds.sharedInstance().requestConfiguration
|
|
53
|
+
|
|
54
|
+
if let maxAdContentRating = call.getString("maxAdContentRating") {
|
|
55
|
+
switch maxAdContentRating {
|
|
56
|
+
case "G":
|
|
57
|
+
requestConfiguration.maxAdContentRating = .general
|
|
58
|
+
case "PG":
|
|
59
|
+
requestConfiguration.maxAdContentRating = .parentalGuidance
|
|
60
|
+
case "T":
|
|
61
|
+
requestConfiguration.maxAdContentRating = .teen
|
|
62
|
+
case "MA":
|
|
63
|
+
requestConfiguration.maxAdContentRating = .matureAudience
|
|
64
|
+
default:
|
|
65
|
+
break
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if let tagForChildDirectedTreatment = call.getBool("tagForChildDirectedTreatment") {
|
|
70
|
+
requestConfiguration.tagForChildDirectedTreatment = NSNumber(value: tagForChildDirectedTreatment)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if let tagForUnderAgeOfConsent = call.getBool("tagForUnderAgeOfConsent") {
|
|
74
|
+
requestConfiguration.tagForUnderAgeOfConsent = NSNumber(value: tagForUnderAgeOfConsent)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if let testDeviceIds = call.getArray("testDeviceIds", String.self) {
|
|
78
|
+
requestConfiguration.testDeviceIdentifiers = testDeviceIds
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
call.resolve()
|
|
24
82
|
}
|
|
25
83
|
|
|
84
|
+
@objc func adCreate(_ call: CAPPluginCall) {
|
|
85
|
+
guard let adUnitId = call.getString("adUnitId") else {
|
|
86
|
+
call.reject("adUnitId is required")
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
guard let adClass = call.getString("cls") else {
|
|
91
|
+
call.reject("cls (ad class) is required")
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let adId = call.getInt("id") ?? nextAdId
|
|
96
|
+
nextAdId = adId + 1
|
|
97
|
+
|
|
98
|
+
let position = call.getString("position") ?? "bottom"
|
|
99
|
+
|
|
100
|
+
DispatchQueue.main.async { [weak self] in
|
|
101
|
+
guard let self = self else {
|
|
102
|
+
call.reject("Plugin instance not available")
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
let ad: Ad?
|
|
107
|
+
switch adClass {
|
|
108
|
+
case "BannerAd":
|
|
109
|
+
ad = BannerAd(id: adId, adUnitId: adUnitId, position: position, plugin: self)
|
|
110
|
+
case "InterstitialAd":
|
|
111
|
+
ad = InterstitialAd(id: adId, adUnitId: adUnitId, plugin: self)
|
|
112
|
+
case "RewardedAd":
|
|
113
|
+
ad = RewardedAd(id: adId, adUnitId: adUnitId, plugin: self)
|
|
114
|
+
case "RewardedInterstitialAd":
|
|
115
|
+
ad = RewardedInterstitialAd(id: adId, adUnitId: adUnitId, plugin: self)
|
|
116
|
+
default:
|
|
117
|
+
call.reject("Unsupported ad class: \(adClass)")
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if let ad = ad {
|
|
122
|
+
self.adManager.addAd(ad, withId: adId)
|
|
123
|
+
call.resolve(["id": adId])
|
|
124
|
+
} else {
|
|
125
|
+
call.reject("Failed to create ad")
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@objc func adIsLoaded(_ call: CAPPluginCall) {
|
|
131
|
+
guard let adId = call.getInt("id") else {
|
|
132
|
+
call.reject("id is required")
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
DispatchQueue.main.async { [weak self] in
|
|
137
|
+
guard let ad = self?.adManager.getAd(adId) else {
|
|
138
|
+
call.resolve(["value": false])
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
call.resolve(["value": ad.isLoaded])
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@objc func adLoad(_ call: CAPPluginCall) {
|
|
147
|
+
guard let adId = call.getInt("id") else {
|
|
148
|
+
call.reject("id is required")
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
DispatchQueue.main.async { [weak self] in
|
|
153
|
+
guard let ad = self?.adManager.getAd(adId) else {
|
|
154
|
+
call.reject("Ad not found")
|
|
155
|
+
return
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
ad.load { error in
|
|
159
|
+
if let error = error {
|
|
160
|
+
call.reject("Failed to load ad: \(error.localizedDescription)")
|
|
161
|
+
} else {
|
|
162
|
+
call.resolve()
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
@objc func adShow(_ call: CAPPluginCall) {
|
|
169
|
+
guard let adId = call.getInt("id") else {
|
|
170
|
+
call.reject("id is required")
|
|
171
|
+
return
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
DispatchQueue.main.async { [weak self] in
|
|
175
|
+
guard let ad = self?.adManager.getAd(adId) else {
|
|
176
|
+
call.reject("Ad not found")
|
|
177
|
+
return
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if !ad.isLoaded {
|
|
181
|
+
call.reject("Ad is not loaded")
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
ad.show { error in
|
|
186
|
+
if let error = error {
|
|
187
|
+
call.reject("Failed to show ad: \(error.localizedDescription)")
|
|
188
|
+
} else {
|
|
189
|
+
call.resolve()
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@objc func adHide(_ call: CAPPluginCall) {
|
|
196
|
+
guard let adId = call.getInt("id") else {
|
|
197
|
+
call.reject("id is required")
|
|
198
|
+
return
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
DispatchQueue.main.async { [weak self] in
|
|
202
|
+
guard let ad = self?.adManager.getAd(adId) else {
|
|
203
|
+
call.reject("Ad not found")
|
|
204
|
+
return
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
ad.hide { error in
|
|
208
|
+
if let error = error {
|
|
209
|
+
call.reject("Failed to hide ad: \(error.localizedDescription)")
|
|
210
|
+
} else {
|
|
211
|
+
call.resolve()
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
@objc func trackingAuthorizationStatus(_ call: CAPPluginCall) {
|
|
218
|
+
if #available(iOS 14, *) {
|
|
219
|
+
let status = ATTrackingManager.trackingAuthorizationStatus
|
|
220
|
+
call.resolve(["status": status.rawValue])
|
|
221
|
+
} else {
|
|
222
|
+
call.resolve(["status": false])
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
@objc func requestTrackingAuthorization(_ call: CAPPluginCall) {
|
|
227
|
+
if #available(iOS 14, *) {
|
|
228
|
+
ATTrackingManager.requestTrackingAuthorization { status in
|
|
229
|
+
call.resolve(["status": status.rawValue])
|
|
230
|
+
}
|
|
231
|
+
} else {
|
|
232
|
+
call.resolve(["status": false])
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
@objc func getPluginVersion(_ call: CAPPluginCall) {
|
|
237
|
+
call.resolve(["version": self.pluginVersion])
|
|
238
|
+
}
|
|
26
239
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import UIKit
|
|
3
|
+
import GoogleMobileAds
|
|
4
|
+
import Capacitor
|
|
5
|
+
|
|
6
|
+
class BannerAd: NSObject, Ad {
|
|
7
|
+
let id: Int
|
|
8
|
+
let adUnitId: String
|
|
9
|
+
private var bannerView: GADBannerView?
|
|
10
|
+
private weak var plugin: AdmobPlusPlugin?
|
|
11
|
+
private let position: String
|
|
12
|
+
private var bannerContainer: UIView?
|
|
13
|
+
|
|
14
|
+
var isLoaded: Bool {
|
|
15
|
+
return bannerView != nil
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
init(id: Int, adUnitId: String, position: String, plugin: AdmobPlusPlugin) {
|
|
19
|
+
self.id = id
|
|
20
|
+
self.adUnitId = adUnitId
|
|
21
|
+
self.position = position
|
|
22
|
+
self.plugin = plugin
|
|
23
|
+
super.init()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
func load(completion: @escaping (Error?) -> Void) {
|
|
27
|
+
DispatchQueue.main.async { [weak self] in
|
|
28
|
+
guard let self = self else { return }
|
|
29
|
+
|
|
30
|
+
if self.bannerView == nil {
|
|
31
|
+
let banner = GADBannerView(adSize: GADAdSizeBanner)
|
|
32
|
+
banner.adUnitID = self.adUnitId
|
|
33
|
+
banner.delegate = self
|
|
34
|
+
banner.rootViewController = self.plugin?.bridge?.viewController
|
|
35
|
+
self.bannerView = banner
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let request = AdMobHelper.buildAdRequest()
|
|
39
|
+
self.bannerView?.load(request)
|
|
40
|
+
completion(nil)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
func show(completion: @escaping (Error?) -> Void) {
|
|
45
|
+
DispatchQueue.main.async { [weak self] in
|
|
46
|
+
guard let self = self, let banner = self.bannerView else {
|
|
47
|
+
completion(AdMobError.adNotLoaded)
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
guard let webView = self.plugin?.bridge?.webView,
|
|
52
|
+
let viewController = self.plugin?.bridge?.viewController else {
|
|
53
|
+
completion(AdMobError.unknown("Unable to access view hierarchy"))
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Remove existing container if any
|
|
58
|
+
self.bannerContainer?.removeFromSuperview()
|
|
59
|
+
|
|
60
|
+
// Create a new container
|
|
61
|
+
let container = UIView()
|
|
62
|
+
container.translatesAutoresizingMaskIntoConstraints = false
|
|
63
|
+
banner.translatesAutoresizingMaskIntoConstraints = false
|
|
64
|
+
|
|
65
|
+
container.addSubview(banner)
|
|
66
|
+
|
|
67
|
+
// Add container to the view hierarchy
|
|
68
|
+
viewController.view.addSubview(container)
|
|
69
|
+
|
|
70
|
+
// Setup constraints
|
|
71
|
+
NSLayoutConstraint.activate([
|
|
72
|
+
container.leadingAnchor.constraint(equalTo: viewController.view.leadingAnchor),
|
|
73
|
+
container.trailingAnchor.constraint(equalTo: viewController.view.trailingAnchor),
|
|
74
|
+
container.heightAnchor.constraint(equalToConstant: 50),
|
|
75
|
+
|
|
76
|
+
banner.centerXAnchor.constraint(equalTo: container.centerXAnchor),
|
|
77
|
+
banner.centerYAnchor.constraint(equalTo: container.centerYAnchor)
|
|
78
|
+
])
|
|
79
|
+
|
|
80
|
+
if self.position == "top" {
|
|
81
|
+
NSLayoutConstraint.activate([
|
|
82
|
+
container.topAnchor.constraint(equalTo: viewController.view.safeAreaLayoutGuide.topAnchor)
|
|
83
|
+
])
|
|
84
|
+
} else {
|
|
85
|
+
NSLayoutConstraint.activate([
|
|
86
|
+
container.bottomAnchor.constraint(equalTo: viewController.view.safeAreaLayoutGuide.bottomAnchor)
|
|
87
|
+
])
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
self.bannerContainer = container
|
|
91
|
+
container.isHidden = false
|
|
92
|
+
banner.isHidden = false
|
|
93
|
+
|
|
94
|
+
completion(nil)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
func hide(completion: @escaping (Error?) -> Void) {
|
|
99
|
+
DispatchQueue.main.async { [weak self] in
|
|
100
|
+
self?.bannerContainer?.isHidden = true
|
|
101
|
+
self?.bannerView?.isHidden = true
|
|
102
|
+
completion(nil)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
func destroy() {
|
|
107
|
+
DispatchQueue.main.async { [weak self] in
|
|
108
|
+
self?.bannerContainer?.removeFromSuperview()
|
|
109
|
+
self?.bannerView?.removeFromSuperview()
|
|
110
|
+
self?.bannerView = nil
|
|
111
|
+
self?.bannerContainer = nil
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
extension BannerAd: GADBannerViewDelegate {
|
|
117
|
+
func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
|
|
118
|
+
plugin?.notifyListeners(Events.bannerLoad, data: ["id": id])
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) {
|
|
122
|
+
plugin?.notifyListeners(Events.bannerLoadFail, data: [
|
|
123
|
+
"id": id,
|
|
124
|
+
"error": error.localizedDescription
|
|
125
|
+
])
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
func bannerViewDidRecordImpression(_ bannerView: GADBannerView) {
|
|
129
|
+
plugin?.notifyListeners(Events.bannerImpression, data: ["id": id])
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
func bannerViewWillPresentScreen(_ bannerView: GADBannerView) {
|
|
133
|
+
plugin?.notifyListeners(Events.bannerOpen, data: ["id": id])
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
func bannerViewWillDismissScreen(_ bannerView: GADBannerView) {
|
|
137
|
+
plugin?.notifyListeners(Events.bannerClose, data: ["id": id])
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
func bannerViewDidRecordClick(_ bannerView: GADBannerView) {
|
|
141
|
+
plugin?.notifyListeners(Events.bannerClick, data: ["id": id])
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
struct Events {
|
|
5
|
+
static let adClick = "ad.click"
|
|
6
|
+
static let adDismiss = "ad.dismiss"
|
|
7
|
+
static let adImpression = "ad.impression"
|
|
8
|
+
static let adLoad = "ad.load"
|
|
9
|
+
static let adLoadFail = "ad.loadfail"
|
|
10
|
+
static let adReward = "ad.reward"
|
|
11
|
+
static let adShow = "ad.show"
|
|
12
|
+
static let adShowFail = "ad.showfail"
|
|
13
|
+
static let bannerClick = "banner.click"
|
|
14
|
+
static let bannerClose = "banner.close"
|
|
15
|
+
static let bannerImpression = "banner.impression"
|
|
16
|
+
static let bannerLoad = "banner.load"
|
|
17
|
+
static let bannerLoadFail = "banner.loadfail"
|
|
18
|
+
static let bannerOpen = "banner.open"
|
|
19
|
+
static let bannerSizeChange = "banner.sizechange"
|
|
20
|
+
static let interstitialDismiss = "interstitial.dismiss"
|
|
21
|
+
static let interstitialImpression = "interstitial.impression"
|
|
22
|
+
static let interstitialLoad = "interstitial.load"
|
|
23
|
+
static let interstitialLoadFail = "interstitial.loadfail"
|
|
24
|
+
static let interstitialShow = "interstitial.show"
|
|
25
|
+
static let interstitialShowFail = "interstitial.showfail"
|
|
26
|
+
static let rewardedDismiss = "rewarded.dismiss"
|
|
27
|
+
static let rewardedImpression = "rewarded.impression"
|
|
28
|
+
static let rewardedInterstitialDismiss = "rewardedi.dismiss"
|
|
29
|
+
static let rewardedInterstitialImpression = "rewardedi.impression"
|
|
30
|
+
static let rewardedInterstitialLoad = "rewardedi.load"
|
|
31
|
+
static let rewardedInterstitialLoadFail = "rewardedi.loadfail"
|
|
32
|
+
static let rewardedInterstitialReward = "rewardedi.reward"
|
|
33
|
+
static let rewardedInterstitialShow = "rewardedi.show"
|
|
34
|
+
static let rewardedInterstitialShowFail = "rewardedi.showfail"
|
|
35
|
+
static let rewardedLoad = "rewarded.load"
|
|
36
|
+
static let rewardedLoadFail = "rewarded.loadfail"
|
|
37
|
+
static let rewardedReward = "rewarded.reward"
|
|
38
|
+
static let rewardedShow = "rewarded.show"
|
|
39
|
+
static let rewardedShowFail = "rewarded.showfail"
|
|
40
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import GoogleMobileAds
|
|
3
|
+
|
|
4
|
+
class AdManager {
|
|
5
|
+
static let shared = AdManager()
|
|
6
|
+
private var ads: [Int: Ad] = [:]
|
|
7
|
+
|
|
8
|
+
private init() {}
|
|
9
|
+
|
|
10
|
+
func addAd(_ ad: Ad, withId id: Int) {
|
|
11
|
+
ads[id] = ad
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
func getAd(_ id: Int) -> Ad? {
|
|
15
|
+
return ads[id]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
func removeAd(_ id: Int) {
|
|
19
|
+
ads.removeValue(forKey: id)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
protocol Ad {
|
|
24
|
+
var id: Int { get }
|
|
25
|
+
var adUnitId: String { get }
|
|
26
|
+
var isLoaded: Bool { get }
|
|
27
|
+
|
|
28
|
+
func load(completion: @escaping (Error?) -> Void)
|
|
29
|
+
func show(completion: @escaping (Error?) -> Void)
|
|
30
|
+
func hide(completion: @escaping (Error?) -> Void)
|
|
31
|
+
func destroy()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
extension Ad {
|
|
35
|
+
func hide(completion: @escaping (Error?) -> Void) {
|
|
36
|
+
completion(NSError(domain: "AdMobPlus", code: -1, userInfo: [NSLocalizedDescriptionKey: "Hide not supported for this ad type"]))
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
class AdMobHelper {
|
|
41
|
+
static func buildAdRequest() -> GADRequest {
|
|
42
|
+
let request = GADRequest()
|
|
43
|
+
return request
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
enum AdMobError: Error {
|
|
48
|
+
case adNotFound
|
|
49
|
+
case adNotLoaded
|
|
50
|
+
case adAlreadyExists
|
|
51
|
+
case invalidAdType
|
|
52
|
+
case unknown(String)
|
|
53
|
+
|
|
54
|
+
var localizedDescription: String {
|
|
55
|
+
switch self {
|
|
56
|
+
case .adNotFound:
|
|
57
|
+
return "Ad not found"
|
|
58
|
+
case .adNotLoaded:
|
|
59
|
+
return "Ad is not loaded"
|
|
60
|
+
case .adAlreadyExists:
|
|
61
|
+
return "Ad already exists"
|
|
62
|
+
case .invalidAdType:
|
|
63
|
+
return "Invalid ad type"
|
|
64
|
+
case .unknown(let message):
|
|
65
|
+
return message
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import UIKit
|
|
3
|
+
import GoogleMobileAds
|
|
4
|
+
import Capacitor
|
|
5
|
+
|
|
6
|
+
class InterstitialAd: NSObject, Ad {
|
|
7
|
+
let id: Int
|
|
8
|
+
let adUnitId: String
|
|
9
|
+
private var interstitial: GADInterstitialAd?
|
|
10
|
+
private weak var plugin: AdmobPlusPlugin?
|
|
11
|
+
|
|
12
|
+
var isLoaded: Bool {
|
|
13
|
+
return interstitial != nil
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
init(id: Int, adUnitId: String, plugin: AdmobPlusPlugin) {
|
|
17
|
+
self.id = id
|
|
18
|
+
self.adUnitId = adUnitId
|
|
19
|
+
self.plugin = plugin
|
|
20
|
+
super.init()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
func load(completion: @escaping (Error?) -> Void) {
|
|
24
|
+
let request = AdMobHelper.buildAdRequest()
|
|
25
|
+
|
|
26
|
+
GADInterstitialAd.load(withAdUnitID: adUnitId, request: request) { [weak self] ad, error in
|
|
27
|
+
guard let self = self else { return }
|
|
28
|
+
|
|
29
|
+
if let error = error {
|
|
30
|
+
self.plugin?.notifyListeners(Events.interstitialLoadFail, data: [
|
|
31
|
+
"id": self.id,
|
|
32
|
+
"error": error.localizedDescription
|
|
33
|
+
])
|
|
34
|
+
completion(error)
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
self.interstitial = ad
|
|
39
|
+
self.interstitial?.fullScreenContentDelegate = self
|
|
40
|
+
|
|
41
|
+
self.plugin?.notifyListeners(Events.interstitialLoad, data: ["id": self.id])
|
|
42
|
+
completion(nil)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
func show(completion: @escaping (Error?) -> Void) {
|
|
47
|
+
DispatchQueue.main.async { [weak self] in
|
|
48
|
+
guard let self = self, let interstitial = self.interstitial else {
|
|
49
|
+
completion(AdMobError.adNotLoaded)
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
guard let viewController = self.plugin?.bridge?.viewController else {
|
|
54
|
+
completion(AdMobError.unknown("Unable to access view controller"))
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interstitial.present(fromRootViewController: viewController)
|
|
59
|
+
completion(nil)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
func destroy() {
|
|
64
|
+
interstitial = nil
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
extension InterstitialAd: GADFullScreenContentDelegate {
|
|
69
|
+
func adDidRecordImpression(_ ad: GADFullScreenPresentingAd) {
|
|
70
|
+
plugin?.notifyListeners(Events.interstitialImpression, data: ["id": id])
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
func adDidRecordClick(_ ad: GADFullScreenPresentingAd) {
|
|
74
|
+
plugin?.notifyListeners(Events.adClick, data: ["id": id])
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
|
|
78
|
+
plugin?.notifyListeners(Events.interstitialShowFail, data: [
|
|
79
|
+
"id": id,
|
|
80
|
+
"error": error.localizedDescription
|
|
81
|
+
])
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
|
85
|
+
plugin?.notifyListeners(Events.interstitialShow, data: ["id": id])
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
|
89
|
+
plugin?.notifyListeners(Events.interstitialDismiss, data: ["id": id])
|
|
90
|
+
interstitial = nil
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import UIKit
|
|
3
|
+
import GoogleMobileAds
|
|
4
|
+
import Capacitor
|
|
5
|
+
|
|
6
|
+
class RewardedAd: NSObject, Ad {
|
|
7
|
+
let id: Int
|
|
8
|
+
let adUnitId: String
|
|
9
|
+
private var rewardedAd: GADRewardedAd?
|
|
10
|
+
private weak var plugin: AdmobPlusPlugin?
|
|
11
|
+
|
|
12
|
+
var isLoaded: Bool {
|
|
13
|
+
return rewardedAd != nil
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
init(id: Int, adUnitId: String, plugin: AdmobPlusPlugin) {
|
|
17
|
+
self.id = id
|
|
18
|
+
self.adUnitId = adUnitId
|
|
19
|
+
self.plugin = plugin
|
|
20
|
+
super.init()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
func load(completion: @escaping (Error?) -> Void) {
|
|
24
|
+
let request = AdMobHelper.buildAdRequest()
|
|
25
|
+
|
|
26
|
+
GADRewardedAd.load(withAdUnitID: adUnitId, request: request) { [weak self] ad, error in
|
|
27
|
+
guard let self = self else { return }
|
|
28
|
+
|
|
29
|
+
if let error = error {
|
|
30
|
+
self.plugin?.notifyListeners(Events.rewardedLoadFail, data: [
|
|
31
|
+
"id": self.id,
|
|
32
|
+
"error": error.localizedDescription
|
|
33
|
+
])
|
|
34
|
+
completion(error)
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
self.rewardedAd = ad
|
|
39
|
+
self.rewardedAd?.fullScreenContentDelegate = self
|
|
40
|
+
|
|
41
|
+
self.plugin?.notifyListeners(Events.rewardedLoad, data: ["id": self.id])
|
|
42
|
+
completion(nil)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
func show(completion: @escaping (Error?) -> Void) {
|
|
47
|
+
DispatchQueue.main.async { [weak self] in
|
|
48
|
+
guard let self = self, let rewardedAd = self.rewardedAd else {
|
|
49
|
+
completion(AdMobError.adNotLoaded)
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
guard let viewController = self.plugin?.bridge?.viewController else {
|
|
54
|
+
completion(AdMobError.unknown("Unable to access view controller"))
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
rewardedAd.present(fromRootViewController: viewController) { [weak self] in
|
|
59
|
+
guard let self = self else { return }
|
|
60
|
+
let reward = rewardedAd.adReward
|
|
61
|
+
self.plugin?.notifyListeners(Events.rewardedReward, data: [
|
|
62
|
+
"id": self.id,
|
|
63
|
+
"reward": [
|
|
64
|
+
"amount": reward.amount.intValue,
|
|
65
|
+
"type": reward.type
|
|
66
|
+
]
|
|
67
|
+
])
|
|
68
|
+
}
|
|
69
|
+
completion(nil)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
func destroy() {
|
|
74
|
+
rewardedAd = nil
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
extension RewardedAd: GADFullScreenContentDelegate {
|
|
79
|
+
func adDidRecordImpression(_ ad: GADFullScreenPresentingAd) {
|
|
80
|
+
plugin?.notifyListeners(Events.rewardedImpression, data: ["id": id])
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
func adDidRecordClick(_ ad: GADFullScreenPresentingAd) {
|
|
84
|
+
plugin?.notifyListeners(Events.adClick, data: ["id": id])
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
|
|
88
|
+
plugin?.notifyListeners(Events.rewardedShowFail, data: [
|
|
89
|
+
"id": id,
|
|
90
|
+
"error": error.localizedDescription
|
|
91
|
+
])
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
|
95
|
+
plugin?.notifyListeners(Events.rewardedShow, data: ["id": id])
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
|
99
|
+
plugin?.notifyListeners(Events.rewardedDismiss, data: ["id": id])
|
|
100
|
+
rewardedAd = nil
|
|
101
|
+
}
|
|
102
|
+
}
|