Как сделать синглтон AdMob Interstitial в Swift? - PullRequest
0 голосов
/ 04 октября 2018

Я использую AdMob в своем приложении и пытаюсь упростить реализацию.
Я только что нашел его файлы-одиночки в Objective-C, но я не могу переделать их в Swift.

Как я могу переписать их в Swift?
И если мне не следует использовать синглтон для этой реализации по некоторым причинам, пожалуйста, дайте мне знать.

AdMob.h

#import <Foundation/Foundation.h>
#import "AdsID.h" 
@import GoogleMobileAds;

@interface AdMob : NSObject<GADBannerViewDelegate,GADInterstitialDelegate>

@property(nonatomic) GADBannerView *GADRecView; @property(nonatomic, strong) GADInterstitial *interstitial;

+ (AdMob *)sharedIncetance;
-(void)loadAdMobBanner:(UIViewController*)vc view:(UIView*)view x:(int)x y:(int)y;
-(void)loadAdMobInste:(UIViewController*)vc rate:(float)rate;

@end

AdMob.m

#import "AdMob.h"

@implementation AdMob

static AdMob *sharedData_ = nil;

+ (AdMob *)sharedInstance{
    @synchronized(self){
        if (!sharedData_) {
            sharedData_ = [[AdMob alloc]init];
        }
    }
    return sharedData_;
}

- (id)init {
    self = [super init];
    if (self) {
        self.interstitial = [self createAndLoadInterstitial];
    }
    return self;
}

- (GADInterstitial *)createAndLoadInterstitial {

    GADInterstitial *interstitial =
    [[GADInterstitial alloc] initWithAdUnitID:@"XXXXXX"]; 
    interstitial.delegate = self;
    [interstitial loadRequest:[GADRequest request]];

    return interstitial;

}

-(void)loadAdMobInste:(UIViewController*)vc{

    if ([self.interstitial isReady]) {
        [self.interstitial presentFromRootViewController:vc];
    }

}

- (void)adViewDidReceiveAd:(GADBannerView *)bannerView {
    NSLog(@"Banner adapter class name: %@", bannerView.adNetworkClassName);
}

@end

ViewController

[[AdMob sharedIncetance] loadAdMobInste:[self btk_parentViewController]];

ОБНОВЛЕНИЕ
Я мог бы реализовать это в Swift, но ошибка «чье представление не в иерархии окон!»вызвано, когда я сделал следующее, и объявление не показывалось:

  1. Загрузить вставку в ViewController
  2. Показать вставку в ViewController
  3. Загрузить вставку в SecondViewController
  4. Показать вставку в SecondViewController (объявление не показывалось, и появилась ошибка)

Если я использовал код в Objective-C, объявление показывалось, а ошибка не появлялась.

AdMob

import Foundation
import GoogleMobileAds

class AdMob : NSObject, GADBannerViewDelegate, GADInterstitialDelegate{

    static var sharedData_: AdMob? = nil

    var interstitial: GADInterstitial?

    class func sharedInstance() -> AdMob? {
        let lockQueue = DispatchQueue(label: "self")
        lockQueue.sync {
            if sharedData_ == nil {
                sharedData_ = AdMob()
            }
        }
        return sharedData_
    }

    override init() {
        super.init()

        interstitial = createAndLoadInterstitial()

    }

    func createAndLoadInterstitial() -> GADInterstitial? {

        let interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910") 
        interstitial.delegate = self
        interstitial.load(GADRequest())

        return interstitial

    }

    func loadInste(_ vc: UIViewController?) {

        if interstitial?.isReady == true {
            self.interstitial?.present(fromRootViewController: vc!)
        }else{
            print("Ad was not realy")
        }
    }

    func interstitialDidDismissScreen(_ ad: GADInterstitial) {
        interstitial = createAndLoadInterstitial()
    }

    func interstitialDidReceiveAd(_ ad: GADInterstitial) {
        print("interstitialDidReceiveAd")
    }

    func interstitial(_ ad: GADInterstitial, didFailToReceiveAdWithError error: GADRequestError) {
        print("interstitial:didFailToReceiveAdWithError: \(error.localizedDescription)")
    }

    func interstitialWillPresentScreen(_ ad: GADInterstitial) {
        print("interstitialWillPresentScreen")
    }

    func interstitialWillDismissScreen(_ ad: GADInterstitial) {
        print("interstitialWillDismissScreen")
    }

    func interstitialWillLeaveApplication(_ ad: GADInterstitial) {
        print("interstitialWillLeaveApplication")
    }

}

AppDelegate

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    var navigationController: UINavigationController?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        window = UIWindow(frame: UIScreen.main.bounds)

        if let window = window {
            let mainVC = ViewController()
            navigationController = UINavigationController.init()
            navigationController = UINavigationController(rootViewController: mainVC)
            navigationController?.navigationBar.isHidden = true
            window.rootViewController = navigationController
            window.makeKeyAndVisible()
        }

        return true
    }
}

ViewController

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        AdMob.sharedInstance()?.loadInste(self)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        let secondVC = SecondViewController()
        self.navigationController?.pushViewController(secondVC, animated: true)

        if AdMob.sharedInstance()?.interstitial?.isReady == true {
              AdMob.sharedInstance()?.interstitial?.present(fromRootViewController: self)
        } else {
            print("Ad wasn't ready")
        }
    }
}

SecondViewController

import GoogleMobileAds

class SecondViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = UIColor.white

        AdMob.sharedInstance()?.loadInste(self)

    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        self.navigationController?.popViewController(animated: true)

        if AdMob.sharedInstance()?.interstitial?.isReady == true {
            AdMob.sharedInstance()?.interstitial?.present(fromRootViewController: self)
        } else {
            print("Ad wasn't ready")
        }
    }
}

1 Ответ

0 голосов
/ 04 октября 2018

Здесь проблема заключается в том, что вы представляете AD после нажатия контроллера представления, чтобы self представление было удалено из иерархии окон, поэтому вы получаете эту ошибку ", представление которой отсутствует в иерархии окон!"

Примечание: Push, Present или Pop ViewController после представления AD

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    // Present ad First and then Push view controller
    if AdMob.sharedInstance()?.interstitial?.isReady == true {
          AdMob.sharedInstance()?.interstitial?.present(fromRootViewController: self)
    } else {
        print("Ad wasn't ready")
    }

    let secondVC = SecondViewController()
    self.navigationController?.pushViewController(secondVC, animated: true)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...