Fix AdMob history banner and refine Felica history mapping
This commit is contained in:
@ -623,7 +623,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Emoney Info/Emoney Info.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 10;
|
||||
CURRENT_PROJECT_VERSION = 11;
|
||||
DEVELOPMENT_TEAM = 6S5573WXX4;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@ -643,7 +643,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.1;
|
||||
MARKETING_VERSION = 1.0.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.iiyh.emoneyinfo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -666,7 +666,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Emoney Info/Emoney Info.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 10;
|
||||
CURRENT_PROJECT_VERSION = 11;
|
||||
DEVELOPMENT_TEAM = 6S5573WXX4;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@ -686,7 +686,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.1;
|
||||
MARKETING_VERSION = 1.0.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.iiyh.emoneyinfo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
||||
@ -229,25 +229,12 @@ public class UnifiedNfcApi {
|
||||
if (uid == 0){
|
||||
normal = false
|
||||
}
|
||||
if (data.count > 10){
|
||||
let type = data[10]
|
||||
debugLog(type)
|
||||
switch type {
|
||||
case 0x01:
|
||||
riwayat.setProsesTipe(1)
|
||||
riwayat.setTitle("payment".localizeString(string: self.langCode!))
|
||||
debugLog("Pembayaran")
|
||||
case 0x00, 0x03:
|
||||
riwayat.setProsesTipe(0)
|
||||
riwayat.setTitle("topup".localizeString(string: self.langCode!))
|
||||
debugLog("Topup")
|
||||
default:
|
||||
riwayat.setProsesTipe(1)
|
||||
riwayat.setTitle("payment".localizeString(string: self.langCode!))
|
||||
debugLog("Other")
|
||||
}
|
||||
|
||||
|
||||
if data.count >= 13 {
|
||||
let transactionKind = self.felicaTransactionKind(for: [UInt8](data))
|
||||
riwayat.setProsesTipe(transactionKind.prosesTipe)
|
||||
riwayat.setTitle(transactionKind.title.localizeString(string: self.langCode!))
|
||||
debugLog("signature: \(transactionKind.signature)")
|
||||
debugLog(transactionKind.logLabel)
|
||||
}
|
||||
if let station = self.stationMap[uid]{
|
||||
debugLog("station", station.name)
|
||||
@ -391,6 +378,33 @@ public class UnifiedNfcApi {
|
||||
return Int(bytes.withUnsafeBytes { $0.load(as: Int32.self).bigEndian })
|
||||
}
|
||||
}
|
||||
|
||||
private func felicaTransactionKind(for bytes: [UInt8]) -> (prosesTipe: Int, title: String, logLabel: String, signature: String) {
|
||||
let signatureBytes = Array(bytes[10...12])
|
||||
let signature = signatureBytes.map { String(format: "%02X", $0) }.joined(separator: " ")
|
||||
|
||||
switch signatureBytes {
|
||||
case [0x00, 0x02, 0x00],
|
||||
[0x03, 0x01, 0x00]:
|
||||
return (0, "topup", "Topup", signature)
|
||||
case [0x01, 0x01, 0x01],
|
||||
[0x01, 0x58, 0x01],
|
||||
[0x03, 0x61, 0x01]:
|
||||
return (1, "payment", "Pembayaran", signature)
|
||||
default:
|
||||
let type = bytes[10]
|
||||
switch type {
|
||||
case 0x00:
|
||||
return (0, "topup", "Topup (fallback)", signature)
|
||||
case 0x01:
|
||||
return (1, "payment", "Pembayaran (fallback)", signature)
|
||||
case 0x03:
|
||||
return (1, "payment", "Pembayaran (fallback 0x03)", signature)
|
||||
default:
|
||||
return (1, "payment", "Other", signature)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func stopCheckCard(message : String){
|
||||
apduRunner.sessionEx?.invalidate(errorMessage: message)
|
||||
|
||||
@ -223,38 +223,133 @@ private struct BannerAdView: UIViewRepresentable {
|
||||
|
||||
func makeCoordinator() -> Coordinator { Coordinator(self) }
|
||||
|
||||
func makeUIView(context: Context) -> GADBannerView {
|
||||
let banner = GADBannerView(adSize: adSize)
|
||||
func makeUIView(context: Context) -> HistoryBannerView {
|
||||
let banner = HistoryBannerView(adSize: adSize)
|
||||
banner.adUnitID = adUnitID
|
||||
banner.delegate = context.coordinator
|
||||
banner.rootViewController = context.coordinator.findRootViewController()
|
||||
banner.load(GADRequest())
|
||||
banner.onDidMoveToWindow = { [weak coordinator = context.coordinator] bannerView in
|
||||
coordinator?.handleBannerDidMoveToWindow(bannerView)
|
||||
}
|
||||
return banner
|
||||
}
|
||||
|
||||
func updateUIView(_ uiView: GADBannerView, context: Context) {}
|
||||
func updateUIView(_ uiView: HistoryBannerView, context: Context) {
|
||||
context.coordinator.attachRootViewControllerIfNeeded(to: uiView)
|
||||
context.coordinator.loadBannerIfNeeded(uiView, reason: "updateUIView")
|
||||
}
|
||||
|
||||
// MARK: Coordinator
|
||||
|
||||
final class Coordinator: NSObject, GADBannerViewDelegate {
|
||||
let parent: BannerAdView
|
||||
private var retryWorkItem: DispatchWorkItem?
|
||||
private var isAdLoaded = false
|
||||
private var isLoadInFlight = false
|
||||
private let retryDelay: TimeInterval = 20
|
||||
|
||||
init(_ parent: BannerAdView) { self.parent = parent }
|
||||
|
||||
deinit {
|
||||
retryWorkItem?.cancel()
|
||||
}
|
||||
|
||||
func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
|
||||
retryWorkItem?.cancel()
|
||||
isLoadInFlight = false
|
||||
isAdLoaded = true
|
||||
log("banner loaded", bannerView: bannerView)
|
||||
DispatchQueue.main.async { self.parent.onAdLoaded?() }
|
||||
}
|
||||
|
||||
func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) {
|
||||
isLoadInFlight = false
|
||||
isAdLoaded = false
|
||||
log("banner failed", bannerView: bannerView, error: error)
|
||||
scheduleRetry(for: bannerView)
|
||||
DispatchQueue.main.async { self.parent.onAdFailed?() }
|
||||
}
|
||||
|
||||
func findRootViewController() -> UIViewController? {
|
||||
UIApplication.shared.connectedScenes
|
||||
.compactMap { $0 as? UIWindowScene }
|
||||
.flatMap { $0.windows }
|
||||
.first { $0.isKeyWindow }?
|
||||
.rootViewController
|
||||
func handleBannerDidMoveToWindow(_ bannerView: GADBannerView) {
|
||||
attachRootViewControllerIfNeeded(to: bannerView)
|
||||
loadBannerIfNeeded(bannerView, reason: "didMoveToWindow")
|
||||
}
|
||||
|
||||
func attachRootViewControllerIfNeeded(to bannerView: GADBannerView) {
|
||||
guard let rootViewController = findNearestViewController(from: bannerView) else {
|
||||
log("root view controller not ready", bannerView: bannerView)
|
||||
return
|
||||
}
|
||||
|
||||
if bannerView.rootViewController !== rootViewController {
|
||||
bannerView.rootViewController = rootViewController
|
||||
log("attached root view controller", bannerView: bannerView)
|
||||
}
|
||||
}
|
||||
|
||||
func loadBannerIfNeeded(_ bannerView: GADBannerView, reason: String) {
|
||||
guard !isAdLoaded, !isLoadInFlight else { return }
|
||||
guard bannerView.window != nil else {
|
||||
log("skip load: banner is not in window", bannerView: bannerView, reason: reason)
|
||||
return
|
||||
}
|
||||
guard bannerView.rootViewController != nil else {
|
||||
log("skip load: root view controller missing", bannerView: bannerView, reason: reason)
|
||||
return
|
||||
}
|
||||
|
||||
retryWorkItem?.cancel()
|
||||
isLoadInFlight = true
|
||||
log("loading banner", bannerView: bannerView, reason: reason)
|
||||
bannerView.load(GADRequest())
|
||||
}
|
||||
|
||||
private func scheduleRetry(for bannerView: GADBannerView) {
|
||||
retryWorkItem?.cancel()
|
||||
|
||||
let workItem = DispatchWorkItem { [weak self, weak bannerView] in
|
||||
guard let self, let bannerView else { return }
|
||||
self.attachRootViewControllerIfNeeded(to: bannerView)
|
||||
self.loadBannerIfNeeded(bannerView, reason: "retry")
|
||||
}
|
||||
retryWorkItem = workItem
|
||||
|
||||
log("scheduling retry in \(Int(retryDelay))s", bannerView: bannerView)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + retryDelay, execute: workItem)
|
||||
}
|
||||
|
||||
private func log(_ message: String, bannerView: GADBannerView, reason: String? = nil, error: Error? = nil) {
|
||||
var parts = ["[AdMob][History]", message]
|
||||
if let reason {
|
||||
parts.append("reason=\(reason)")
|
||||
}
|
||||
parts.append("adUnitID=\(bannerView.adUnitID ?? "-")")
|
||||
parts.append("visible=\(bannerView.window != nil)")
|
||||
parts.append("loaded=\(isAdLoaded)")
|
||||
parts.append("inFlight=\(isLoadInFlight)")
|
||||
parts.append("rootVC=\(String(describing: type(of: bannerView.rootViewController)))")
|
||||
|
||||
if let nsError = error as NSError? {
|
||||
parts.append("errorDomain=\(nsError.domain)")
|
||||
parts.append("errorCode=\(nsError.code)")
|
||||
parts.append("error=\(nsError.localizedDescription)")
|
||||
}
|
||||
|
||||
debugLog(parts.joined(separator: " | "))
|
||||
}
|
||||
|
||||
private func findNearestViewController(from view: UIView) -> UIViewController? {
|
||||
sequence(first: view.next, next: { $0?.next })
|
||||
.first { $0 is UIViewController } as? UIViewController
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class HistoryBannerView: GADBannerView {
|
||||
var onDidMoveToWindow: ((HistoryBannerView) -> Void)?
|
||||
|
||||
override func didMoveToWindow() {
|
||||
super.didMoveToWindow()
|
||||
onDidMoveToWindow?(self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,11 +495,19 @@ final class HistoryHostingController: UIViewController {
|
||||
}
|
||||
|
||||
private func loadInterstitial() {
|
||||
debugLog("[AdMob][HistoryInterstitial] loading interstitial | adUnitID=\(interstitialAdUnitID)")
|
||||
GADInterstitialAd.load(
|
||||
withAdUnitID: interstitialAdUnitID,
|
||||
request: GADRequest()
|
||||
) { [weak self] ad, _ in
|
||||
// Store ad if loaded; ignore error — fallback to direct export
|
||||
) { [weak self] ad, error in
|
||||
if let error = error as NSError? {
|
||||
debugLog(
|
||||
"[AdMob][HistoryInterstitial] failed | adUnitID=\(self?.interstitialAdUnitID ?? "-") | errorDomain=\(error.domain) | errorCode=\(error.code) | error=\(error.localizedDescription)"
|
||||
)
|
||||
} else {
|
||||
debugLog("[AdMob][HistoryInterstitial] loaded | adUnitID=\(self?.interstitialAdUnitID ?? "-")")
|
||||
}
|
||||
|
||||
self?.interstitial = ad
|
||||
self?.interstitial?.fullScreenContentDelegate = self
|
||||
}
|
||||
@ -645,6 +748,7 @@ extension HistoryHostingController: GADFullScreenContentDelegate {
|
||||
|
||||
// Called when the interstitial is dismissed — proceed with export
|
||||
func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
||||
debugLog("[AdMob][HistoryInterstitial] dismissed")
|
||||
interstitial = nil
|
||||
loadInterstitial() // pre-load for the next export attempt
|
||||
exportPDF()
|
||||
@ -652,6 +756,10 @@ extension HistoryHostingController: GADFullScreenContentDelegate {
|
||||
|
||||
// Called when the interstitial fails to present — fall back to direct export
|
||||
func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
|
||||
let nsError = error as NSError
|
||||
debugLog(
|
||||
"[AdMob][HistoryInterstitial] present failed | errorDomain=\(nsError.domain) | errorCode=\(nsError.code) | error=\(nsError.localizedDescription)"
|
||||
)
|
||||
interstitial = nil
|
||||
exportPDF()
|
||||
}
|
||||
|
||||
@ -63,6 +63,10 @@ final class HomeViewController: UIViewController {
|
||||
// Ads
|
||||
private let promoCard = UIView()
|
||||
private var bannerView = GADBannerView()
|
||||
private var bannerRetryWorkItem: DispatchWorkItem?
|
||||
private var isBannerAdLoaded = false
|
||||
private var isBannerLoadInFlight = false
|
||||
private let bannerRetryDelay: TimeInterval = 20
|
||||
|
||||
// Dynamic layout: toggle based on ad load state
|
||||
private var lastTxTopNoAd: NSLayoutConstraint!
|
||||
@ -106,6 +110,7 @@ final class HomeViewController: UIViewController {
|
||||
name: Notification.Name("refreshScreen"),
|
||||
object: nil
|
||||
)
|
||||
loadBannerAdIfNeeded(reason: "viewDidAppear")
|
||||
}
|
||||
|
||||
override func viewDidDisappear(_ animated: Bool) {
|
||||
@ -113,6 +118,10 @@ final class HomeViewController: UIViewController {
|
||||
NotificationCenter.default.removeObserver(self, name: Notification.Name("refreshScreen"), object: nil)
|
||||
}
|
||||
|
||||
deinit {
|
||||
bannerRetryWorkItem?.cancel()
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
super.viewDidLayoutSubviews()
|
||||
cardGradient.frame = cardView.bounds
|
||||
@ -266,9 +275,55 @@ final class HomeViewController: UIViewController {
|
||||
}
|
||||
|
||||
func loadBannerAd() {
|
||||
loadBannerAdIfNeeded(reason: "external")
|
||||
}
|
||||
|
||||
private func loadBannerAdIfNeeded(reason: String) {
|
||||
guard !isBannerAdLoaded, !isBannerLoadInFlight else { return }
|
||||
guard isViewLoaded, view.window != nil else {
|
||||
logAdMob("skip load: view is not visible", reason: reason)
|
||||
return
|
||||
}
|
||||
|
||||
bannerRetryWorkItem?.cancel()
|
||||
bannerView.rootViewController = self
|
||||
isBannerLoadInFlight = true
|
||||
logAdMob("loading banner", reason: reason)
|
||||
bannerView.load(GADRequest())
|
||||
}
|
||||
|
||||
private func scheduleBannerRetry(after delay: TimeInterval = 20) {
|
||||
bannerRetryWorkItem?.cancel()
|
||||
|
||||
let workItem = DispatchWorkItem { [weak self] in
|
||||
self?.loadBannerAdIfNeeded(reason: "retry")
|
||||
}
|
||||
bannerRetryWorkItem = workItem
|
||||
|
||||
logAdMob("scheduling retry in \(Int(delay))s")
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: workItem)
|
||||
}
|
||||
|
||||
private func logAdMob(_ message: String, reason: String? = nil, error: Error? = nil) {
|
||||
var parts = ["[AdMob][Home]", message]
|
||||
if let reason {
|
||||
parts.append("reason=\(reason)")
|
||||
}
|
||||
parts.append("adUnitID=\(bannerView.adUnitID ?? "-")")
|
||||
parts.append("visible=\(viewIfLoaded?.window != nil)")
|
||||
parts.append("loaded=\(isBannerAdLoaded)")
|
||||
parts.append("inFlight=\(isBannerLoadInFlight)")
|
||||
parts.append("rootVC=\(String(describing: type(of: bannerView.rootViewController)))")
|
||||
|
||||
if let nsError = error as NSError? {
|
||||
parts.append("errorDomain=\(nsError.domain)")
|
||||
parts.append("errorCode=\(nsError.code)")
|
||||
parts.append("error=\(nsError.localizedDescription)")
|
||||
}
|
||||
|
||||
debugLog(parts.joined(separator: " | "))
|
||||
}
|
||||
|
||||
private func setupLastTransaction() {
|
||||
lastTxHeader.text = L10n.lastTransaction
|
||||
lastTxHeader.font = Theme.Font.subtitle(weight: .bold)
|
||||
@ -562,6 +617,10 @@ struct LastTransactionItem {
|
||||
|
||||
extension HomeViewController: GADBannerViewDelegate {
|
||||
func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
|
||||
bannerRetryWorkItem?.cancel()
|
||||
isBannerLoadInFlight = false
|
||||
isBannerAdLoaded = true
|
||||
logAdMob("banner loaded")
|
||||
lastTxTopNoAd.isActive = false
|
||||
lastTxTopWithAd.isActive = true
|
||||
UIView.animate(withDuration: 0.3) {
|
||||
@ -571,12 +630,16 @@ extension HomeViewController: GADBannerViewDelegate {
|
||||
}
|
||||
|
||||
func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) {
|
||||
isBannerLoadInFlight = false
|
||||
isBannerAdLoaded = false
|
||||
logAdMob("banner failed", error: error)
|
||||
lastTxTopWithAd.isActive = false
|
||||
lastTxTopNoAd.isActive = true
|
||||
UIView.animate(withDuration: 0.3) {
|
||||
self.promoCard.isHidden = true
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
scheduleBannerRetry(after: bannerRetryDelay)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -156,7 +156,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
private func startAdMobSDKIfNeeded() {
|
||||
guard !hasStartedAdMob else { return }
|
||||
hasStartedAdMob = true
|
||||
// GADMobileAds.sharedInstance().requestConfiguration.testDeviceIdentifiers = ["7b42e513861d6b0c9f07529b748930c0"]
|
||||
// GADMobileAds.sharedInstance().requestConfiguration.testDeviceIdentifiers = ["ae454ddf2186e5ac7871bf705de41098"]
|
||||
GADMobileAds.sharedInstance().start { [weak self] _ in
|
||||
DispatchQueue.main.async {
|
||||
self?.homeVC?.loadBannerAd()
|
||||
|
||||
@ -34,6 +34,10 @@ final class SettingsViewController: UIViewController {
|
||||
// Ad banner
|
||||
private let adContainer = UIView()
|
||||
private var bannerView = GADBannerView()
|
||||
private var bannerRetryWorkItem: DispatchWorkItem?
|
||||
private var isBannerAdLoaded = false
|
||||
private var isBannerLoadInFlight = false
|
||||
private let bannerRetryDelay: TimeInterval = 20
|
||||
|
||||
// Dynamic constraints — toggled on ad load/fail
|
||||
private var generalTopNoAd: NSLayoutConstraint!
|
||||
@ -59,6 +63,15 @@ final class SettingsViewController: UIViewController {
|
||||
setupFooter()
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
loadBannerAdIfNeeded(reason: "viewDidAppear")
|
||||
}
|
||||
|
||||
deinit {
|
||||
bannerRetryWorkItem?.cancel()
|
||||
}
|
||||
|
||||
// MARK: - ScrollView
|
||||
|
||||
private func setupScrollView() {
|
||||
@ -132,10 +145,55 @@ final class SettingsViewController: UIViewController {
|
||||
bannerView.heightAnchor.constraint(equalToConstant: CGFloat(adSize.size.height))
|
||||
])
|
||||
|
||||
bannerView.load(GADRequest())
|
||||
lastBottomAnchor = adContainer.bottomAnchor
|
||||
}
|
||||
|
||||
private func loadBannerAdIfNeeded(reason: String) {
|
||||
guard !isBannerAdLoaded, !isBannerLoadInFlight else { return }
|
||||
guard isViewLoaded, view.window != nil else {
|
||||
logAdMob("skip load: view is not visible", reason: reason)
|
||||
return
|
||||
}
|
||||
|
||||
bannerRetryWorkItem?.cancel()
|
||||
bannerView.rootViewController = self
|
||||
isBannerLoadInFlight = true
|
||||
logAdMob("loading banner", reason: reason)
|
||||
bannerView.load(GADRequest())
|
||||
}
|
||||
|
||||
private func scheduleBannerRetry(after delay: TimeInterval = 20) {
|
||||
bannerRetryWorkItem?.cancel()
|
||||
|
||||
let workItem = DispatchWorkItem { [weak self] in
|
||||
self?.loadBannerAdIfNeeded(reason: "retry")
|
||||
}
|
||||
bannerRetryWorkItem = workItem
|
||||
|
||||
logAdMob("scheduling retry in \(Int(delay))s")
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: workItem)
|
||||
}
|
||||
|
||||
private func logAdMob(_ message: String, reason: String? = nil, error: Error? = nil) {
|
||||
var parts = ["[AdMob][Settings]", message]
|
||||
if let reason {
|
||||
parts.append("reason=\(reason)")
|
||||
}
|
||||
parts.append("adUnitID=\(bannerView.adUnitID ?? "-")")
|
||||
parts.append("visible=\(viewIfLoaded?.window != nil)")
|
||||
parts.append("loaded=\(isBannerAdLoaded)")
|
||||
parts.append("inFlight=\(isBannerLoadInFlight)")
|
||||
parts.append("rootVC=\(String(describing: type(of: bannerView.rootViewController)))")
|
||||
|
||||
if let nsError = error as NSError? {
|
||||
parts.append("errorDomain=\(nsError.domain)")
|
||||
parts.append("errorCode=\(nsError.code)")
|
||||
parts.append("error=\(nsError.localizedDescription)")
|
||||
}
|
||||
|
||||
debugLog(parts.joined(separator: " | "))
|
||||
}
|
||||
|
||||
// MARK: - General Section
|
||||
|
||||
private func setupGeneralSection() {
|
||||
@ -291,6 +349,10 @@ final class SettingsViewController: UIViewController {
|
||||
|
||||
extension SettingsViewController: GADBannerViewDelegate {
|
||||
func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
|
||||
bannerRetryWorkItem?.cancel()
|
||||
isBannerLoadInFlight = false
|
||||
isBannerAdLoaded = true
|
||||
logAdMob("banner loaded")
|
||||
generalTopNoAd.isActive = false
|
||||
generalTopWithAd.isActive = true
|
||||
UIView.animate(withDuration: 0.3) {
|
||||
@ -300,12 +362,16 @@ extension SettingsViewController: GADBannerViewDelegate {
|
||||
}
|
||||
|
||||
func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) {
|
||||
isBannerLoadInFlight = false
|
||||
isBannerAdLoaded = false
|
||||
logAdMob("banner failed", error: error)
|
||||
generalTopWithAd.isActive = false
|
||||
generalTopNoAd.isActive = true
|
||||
UIView.animate(withDuration: 0.3) {
|
||||
self.adContainer.isHidden = true
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
scheduleBannerRetry(after: bannerRetryDelay)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user