I have replicated the iAdSuite with Storyboards in swift and the iAd works all fine across all view controllers, except that when the delegate method bannerViewDidLoadAd(banner: ADBannerView!)
is called the banner view does not appear instantly. I have to either rotate the simulator or go to another tab so that it appears.
I think this is the part of Apple sample code in Objective-C that I could not "translate" to swift? which may well be causing the iAd not show asynchronously once loaded...
+ (BannerViewManager *)sharedInstance
{
static BannerViewManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[BannerViewManager alloc] init];
});
return sharedInstance;
}
This is my BannerViewManager
class with the ADBannerViewDelegate
methods.
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)
}
}
EDIT
I have managed to convert the objective-C code above to swift using this post on SO but I still have the same problem. The iAd doesn't appear once its loaded. There's got to be some sort of change to the view so that it does, either rotating device or tapping another tab, etc...
So now my sharedInstance
looks like this:
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!
}
I think I figured out what the problem is. It has nothing to do with the way I initialise the shared instance of the BannerViewManager
class. In the matter of fact it turned out to give exactly the same behaviour whether using dispatch_once
or the new swift 2.0 way.
The thing that caused the iAd not to show instantaneously when bannerViewDidLoadAd
was invoked is that viewDidLayoutSubviews
was actually never called!
I had to add some print statements here and there. Both in my code and Apple sample code to reach this conclusion.
So setNeedsLayout
instead of layoutIfNeeded
forced trigger the viewDidLayoutSubviews
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With