iAd не отображается асинхронно после вызова его метода делегата

Я воспроизвел iAdSuite с раскадровками в быстром и iAd отлично работает на всех контроллерах представления, за исключением того, что когда вызывается метод делегата bannerViewDidLoadAd(banner: ADBannerView!), представление баннера не появляется мгновенно. Я должен либо повернуть симулятор, либо перейти на другую вкладку, чтобы он появился.

Я думаю, что это часть примера кода Apple в Objective-C, которую я не смог «перевести» на Swift? что вполне может быть причиной того, что iAd не отображается асинхронно после загрузки...

+ (BannerViewManager *)sharedInstance
{
    static BannerViewManager *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[BannerViewManager alloc] init];
    });
    return sharedInstance;
}

Это мой класс BannerViewManager с методами ADBannerViewDelegate.

class BannerViewManager: NSObject, ADBannerViewDelegate {

    // MARK: - Shared instance
    static let sharedInstance = BannerViewManager()

    var bannerView: ADBannerView!
    var bannerViewControllers: NSMutableSet!

    override init() {
        super.init()

        bannerView = ADBannerView(adType: .Banner)
        bannerViewControllers = NSMutableSet()
        bannerView.delegate = self
    }

    func addBannerViewController(controller: BannerViewController) {
        bannerViewControllers.addObject(controller)
    }

    func removeBannerViewController(controller: BannerViewController) {
        bannerViewControllers.removeObject(controller)
    }

    // MARK: - Ad banner view delegate methods

    func bannerViewDidLoadAd(banner: ADBannerView!) {
        NSLog("bannerViewDidLoadAd")

        for bannerViewController in bannerViewControllers {
            (bannerViewController as! BannerViewController).updateLayout()
        }
    }

    func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
        NSLog("didFailToReceiveAdWithError %@", error);

        for bannerViewController in bannerViewControllers {
            (bannerViewController as! BannerViewController).updateLayout()
        }
    }

    func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
        NSNotificationCenter.defaultCenter().postNotificationName(BannerViewActionWillBegin, object: self)
        return true
    }

    func bannerViewActionDidFinish(banner: ADBannerView!) {
        NSNotificationCenter.defaultCenter().postNotificationName(BannerViewActionDidFinish, object: self)
    }
}

ИЗМЕНИТЬ

Мне удалось преобразовать приведенный выше код Objective-C в быстрый, используя этот пост на SO но у меня все та же проблема. iAd не появляется после загрузки. Должно быть какое-то изменение в представлении, чтобы оно работало, либо вращая устройство, либо касаясь другой вкладки и т. Д.

Итак, теперь мой sharedInstance выглядит так:

    static var sharedInstance: BannerViewManager {
        struct Static {
            static var onceToken: dispatch_once_t = 0
            static var instance: BannerViewManager? = nil
        }
        dispatch_once(&Static.onceToken) {
            Static.instance = BannerViewManager()
        }
        return Static.instance!
    }

person Ahmed Khedr    schedule 21.12.2015    source источник
comment
Я предполагаю, что у вас есть некоторый код iAd в каждом контроллере представления viewDidLoad? Если это так, переместите код iAd в viewWillAppear каждого контроллера представления.   -  person Daniel Storm    schedule 21.12.2015
comment
Я сделал это полностью, как пример кода. Таким образом, ни в одном контроллере представления нет кода iAd. В качестве альтернативы есть BannerViewController в представлении контейнера, и у меня есть эта строка view.addSubview(BannerViewManager.sharedInstance.bannerView) в ее viewWillAppear   -  person Ahmed Khedr    schedule 21.12.2015
comment
@DanielStorm – Ознакомьтесь с примером кода для tabbedBanner здесь   -  person Ahmed Khedr    schedule 21.12.2015


Ответы (2)


Кажется, я понял, в чем проблема. Это не имеет никакого отношения к тому, как я инициализирую общий экземпляр класса BannerViewManager. На самом деле оказалось, что это дает точно такое же поведение, независимо от того, используется ли dispatch_once или новый способ swift 2.0.

Дело в том, что iAd не отображался мгновенно при вызове bannerViewDidLoadAd, так это то, что viewDidLayoutSubviews на самом деле никогда не вызывался!

Мне пришлось добавить некоторые операторы печати здесь и там. Как в моем коде, так и в примере кода Apple, чтобы прийти к такому выводу.

Итак, setNeedsLayout вместо layoutIfNeeded принудительно запускает viewDidLayoutSubviews

person Ahmed Khedr    schedule 25.12.2015

  1. В общем, прикрепите точки останова в bannerViewDidLoadAd и аналогичную функцию обратного вызова.
  2. Убедитесь, что у вас есть делегат, как в Swift, как класс YourClassViewController: UIViewController, ADBannerViewDelegate.
  3. Проверьте свой сценарий, вы сказали: «Мне нужно либо повернуть симулятор, либо перейти на другую вкладку, чтобы он появился», так что какой метод может быть за это ответственен. Я знаю, вы догадались.
  4. ПРОЧИТАЙТЕ документы, анализируйте.
person Kumar Utsav    schedule 30.12.2015