Home>

Implements AdMob rewarded advertising.
The following classes control the loading, display, etc. of AdMob rewarded ads.
If I've watched the AdMob Rewards ad to the end, the ad reload works fine,
If i stop watching your AdMob Rewards ads, reloading your ads won't work.
I understand that if you interrupt it in the middle, you can not reload because none of the delegate methods declared in the extension part are called.

Is it possible to detect that the viewing of rewarded ads was interrupted in the middle?
Is the only way to see rewarded ads next time is to restart the app?

import Foundation
import Firebase
// Define this protocol if I want to get reward values ​​from AdMobManager
public protocol AdMobManagerRewarder {
    func gotReward (amount: NSDecimalNumber)
}
public class AdMobRewardManager: NSObject, GADRewardedAdDelegate {
    var adMobId: String?
    var rewardedAd: GADRewardedAd?
    var parent: UIViewController?
    // AdMob Manager initializer
    public init (parent: UIViewController) {
        super.init ()
        self.parent = parent
    }
    // Set the ad ID of Admob's rewarded ad
    public func setReward (_ adMobId: String)->Void {
        self.adMobId = adMobId
        createAndLoadRewardedAd ()
    }
    public func displayReward () {
        if self.rewardedAd? .isReady == true {
            self.rewardedAd ?. present (fromRootViewController: self.parent !, delegate: self)
        } else {
            print ("reward is not Ready.")
        }
    }
    func createAndLoadRewardedAd () {
        self.rewardedAd = GADRewardedAd (adUnitID: self.adMobId!)
        self.rewardedAd? .load (GADRequest ()) {error in
        if let error = error {
          print ("AdMobRewardManager: Loading failed: \ (error)")
        } else {
          print ("AdMobRewardManager: Loading Succeeded")
        }
      }
    }
    // A method that returns true if the reward ad is ready, false if not clean
    public func rewardAdIsReady ()->Bool {
        if self.rewardedAd? .isReady == true {
            #if DEBUG
            NSLog ("reward Ad is ready")
            #endif
            return true
        } else {
            #if DEBUG
            NSLog ("reward Ad is not ready")
            #endif
            return false
        }
    }
}
extension AdMobRewardManager {
    /// Tells the delegate that the user earned a reward.
    public func rewardedAd (_ rewardedAd: GADRewardedAd, userDidEarn reward: GADAdReward) {
        print ("Reward received with currency: \ (reward.type), amount \ (reward.amount).")
        (self.parent as! AdMobManagerRewarder) .gotReward (amount: reward.amount)
        createAndLoadRewardedAd ()
    }
    /// Tells the delegate that the rewarded ad was presented.
    func rewardedAdDidPresent (_ rewardedAd: GADRewardedAd) {
        createAndLoadRewardedAd ()
      print ("AdMobRewardManager: Rewarded ad presented.")
    }
    /// Tells the delegate that the rewarded ad was dismissed.
    func rewardedAdDidDismiss (_ rewardedAd: GADRewardedAd) {
      createAndLoadRewardedAd ()
      print ("AdMobRewardManager: Rewarded ad dismissed.")
    }
    /// Tells the delegate that the rewarded ad failed to present.
    func rewardedAd (_ rewardedAd: GADRewardedAd, didFailToPresentWithError error: Error) {
        createAndLoadRewardedAd ()
      print ("AdMobRewardManager: Rewarded ad failed to present.")
    }
}
  • Answer # 1

    It has been resolved.

    The problem this time was that the delegate method of rewardedAdDidPresent, rewardedAdDidDismiss, rewardedAd (_ rewardedAd: GADRewardedAd, didFailToPresentWithError error: Error) was not called.
    This point has come to be called by making the 3 methods public.

    public func rewardedAdDidDismiss (_ rewardedAd: GADRewardedAd) {
          createAndLoadRewardedAd ()
          print ("AdMobRewardManager: Rewarded ad dismissed.")
        }


    Next, as pointed out by terotail, the call to createAndLoadRewardedAdmob () in rewardedAdDidPresent has been deleted.

    With the above work, rewardedAdDidDismiss is now called, and createAndLoadRewardedAdmob is no longer called inside rewardedAdDidDismiss, so even if you stop watching rewarded ads in the middle, rewarded ads will be reloaded.

  • Answer # 2

    func rewardedAdDidPresent (_ rewardedAd: GADRewardedAd)
    This is because I am calling createAndLoadRewardedAd () in.
    RewardedAdDidDismiss will not be handled properly as the ad will be overwritten.