So I have this code.
override func viewDidLoad() {
super.viewDidLoad()
self.canDisplayBannerAds = true
adBanner.delegate = self
adBanner.hidden = true
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
NSLog("adBanner Error")
}
func bannerViewWillLoadAd(banner: ADBannerView!) {
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
return true
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
adBanner.hidden = false
}
It works fine but when I transition to one of my other view controllers, then go back, the adBanner is visible but empty for x amount of time (say maybe 15 seconds) before loading a new ad. How can I tell the adBanner to become hidden again until the new ad is loaded?
Related
My app was approved just a couple of days ago and had an iAd banner on the bottom of the screen. I know that there it can take up to a week for ads to start appearing, but while I'm waiting.. can someone make sure that I don't have any errors in my code?
import UIKit
import SpriteKit
import iAd
import GameKit
class GameViewController: UIViewController, ADBannerViewDelegate, GKLocalPlayerListener {
var adBanner: ADBannerView!
override func viewDidLoad() {
super.viewDidLoad()
authenticateLocalPlayer()
if let scene = GameScene(fileNamed:"GameScene") {
// Configure the view.
let skView = self.view as! SKView
skView.ignoresSiblingOrder = true
scene.scaleMode = .AspectFill
skView.presentScene(scene)
}
}
func loadBanner() {
adBanner = ADBannerView(frame: CGRect.zero)
adBanner.center = CGPoint(x: adBanner.center.x, y: view.bounds.size.height - adBanner.frame.size.height / 2)
adBanner.delegate = self
adBanner.hidden = true
view.addSubview(adBanner)
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
adBanner.hidden = false
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
adBanner.hidden = true
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
return true
}
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
return .AllButUpsideDown
} else {
return .All
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override func prefersStatusBarHidden() -> Bool {
return true
}
func authenticateLocalPlayer() {
let localPlayer = GKLocalPlayer.localPlayer()
localPlayer.authenticateHandler = {(viewController, error) -> Void in
if (viewController != nil) {
self.presentViewController(viewController!, animated: true, completion: nil)
}
else {
print((GKLocalPlayer.localPlayer().authenticated))
}
}
}
}
Right now it just displays a white rectangle. Is there anything wrong with my code, or do I just need to keep waiting for my app to start receiving ads?
iAd is officially discontinued as of tomorrow (June 30th, 2016). I am unsure of the "sign up" process now, but I believe Apple stopped registering apps to receive ads from their network some months ago
Who calls the loadBanner()?
You might consider overriding viewDidAppear() and shifting the code there.
Reading through Apple's documentation on iAD I got the impression, that if I'll add the ADBannerView to my controller's view tree - other views will be scaled to fit the add. But apparently that's not the case as you can see here :
That's the code I'm using :
import UIKit
import SpriteKit
import iAd
class GameViewController: UIViewController, ADBannerViewDelegate {
var mainView: SKView!
let adBanner = ADBannerView(adType: .Banner)
override func viewDidLoad() {
super.viewDidLoad()
mainView = self.view as? SKView
mainView.showsDrawCount = true
mainView.showsNodeCount = true
mainView.showsFPS = true
adBanner.delegate = self
adBanner.center = CGPoint(x: adBanner.center.x, y: mainView.bounds.size.height - adBanner.frame.size.height / 2)
adBanner.hidden = true
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
return true
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
NSLog("error: \(error)")
}
func bannerViewWillLoadAd(banner: ADBannerView!) {
print("WILL LOAD BANNER")
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
print("Loaded Ad \(banner)")
adBanner.hidden = false
}
override func viewWillAppear(animated: Bool) {
let helloScene = HelloScene(size: mainView.frame.size)
mainView.presentScene(helloScene)
mainView.addSubview(adBanner)
}
override func shouldAutorotate() -> Bool {
return false
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
return UIInterfaceOrientationMask.AllButUpsideDown
} else {
return UIInterfaceOrientationMask.All
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func prefersStatusBarHidden() -> Bool {
return true
}
}
Am I missing something ? If I'll set controller's self.canDisplayBannerAds = true then banner is displayed properly at the bottom with the rest scaled as I would expect.
Is it because I'm using presentScene, which adds SKScene and not a view ?
UPDATE
I've tried adding constraints, but I guess there's a lot of reading ahead of me cause I couldn't yet figure that out :) I googled for a while and came up with this, but that didn't change anything so probably I'm doing it wrong (added that to viewDidLoad :
mainView.addSubview(adBanner)
let viewsDictionary = ["adBanner": adBanner]
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[adBanner]|", options: NSLayoutFormatOptions.AlignAllBaseline, metrics: nil, views: viewsDictionary))
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[adBanner]|", options: NSLayoutFormatOptions.AlignAllBaseline, metrics: nil, views: viewsDictionary))
You can replace your complete code with
self.canDisplayBannerAds = true
Here is a short tutorial.
I am using Xcode 7, Swift 2.0. This problem happens both in the simulator, and in my actual app which is available on the App Store. Many times (not always), when I perform a segue in my app the adBanner goes plain white for a bit before loading a new ad. I'm confused because an ad is available, even when it's white!
Here is my code:
I initialize the ADBannerView:
var adBanner = ADBannerView(adType: ADAdType.Banner)
In my viewDidLoad:
self.canDisplayBannerAds = true
self.adBanner.delegate = self
self.adBanner.hidden = true
self.adBanner.alpha = 0
self.adBanner.frame.origin.y = self.view.frame.height-self.adBanner.frame.height
self.view.addSubview(self.adBanner)
My viewDidDisappear:
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(true)
adBanner.removeFromSuperview()
if( deviceType.isEqualToString("iPhone") )
{
adBanner.delegate = nil
}
}
In my class:
func bannerViewDidLoadAd(banner: ADBannerView!)
{
self.adBanner.hidden = false
UIView.animateWithDuration(0.5, animations: {self.adBanner.alpha = 1})
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!)
{
self.adBanner.hidden = true
UIView.animateWithDuration(0.5, animations: {self.adBanner.alpha = 0})
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool
{
return willLeave
}
func bannerViewWillLoadAd(banner: ADBannerView!) {
}
When running the app with Xcode, I occasionally get this message despite the fact that I have implemented the delegate method:
ADBannerView: Unhandled error (no delegate or delegate does not implement didFailToReceiveAdWithError:): Error Domain=ADErrorDomain Code=5 "The operation couldn’t be completed. Banner view is visible but does not have content" UserInfo=0x9632d30 {ADInternalErrorCode=5, NSLocalizedFailureReason=Banner view is visible but does not have content}
Edit: The problem is using canDisplayBannerAds results in delegate methods not being called. More info here: Hiding iAd ADBannerView in Swift when ad fails to load - no delegate or delegate does not implement didFailToReceiveAdWithError
Here is some working code for you that just worked for me. This does not need self.candisplaybannerads = true as I had some issues with that. The ad automatically changes the size according to the screen size and is located at the bottom of the screen. In my spritekit game it did not have any problems with becoming white when transitioning.
import iAd
class viewController: UIViewController, ADBannerViewDelegate {
var AdBanner = ADBannerView()
override func viewDidLoad() {
super.viewDidLoad()
/* Ad Banner Settings */
AdBanner = ADBannerView()
AdBanner.frame = CGRectZero
AdBanner.delegate = self
self.AdBanner.frame = CGRectMake(0, self.view.frame.size.height-self.AdBanner.frame.size.height, self.AdBanner.frame.size.width, self.AdBanner.frame.size.height)
AdBanner.backgroundColor = UIColor.clearColor()
self.view.addSubview(AdBanner)
}
/* All iAd Functions */
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
/* whatever you need */
return true
}
func bannerViewActionDidFinish(banner: ADBannerView!) {
/* whatever you need */
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
AdBanner.hidden = false
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
NSLog("Error Loading Ad")
/* whatever you need */
AdBanner.hidden = true
}
func bannerViewWillLoadAd(banner: ADBannerView!) {
/* whatever you need */
}
I have an iAd banner in my application however, sometimes (usually when the iAd has an error) it will shift my other views up. Is it possible to just have the banner view overlap my other views instead of interfere with them?
override func viewDidLoad() {
Banner.hidden = true
Banner.delegate = self
self.canDisplayBannerAds = true
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
return true
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
NSLog("Error")
Banner.hidden = true
}
func bannerViewWillLoadAd(banner: ADBannerView!) {
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
Banner.hidden = false
}
Not clear if you are manually adding the iAD banner from a singleton or just using the built in shortcut self.canDisplayBannerAds = true.
If you mix the two together you might have strange results.
Try removing self.canDisplayBannerAds = true and manually add the banner view to your view hierarchy.
this small example might help.
When you opt for the shortcut solution self.canDisplayBannerAds = true, your view hierarchy will be embedded in a bigger view containing the banner and automatically animating as you described. In this case you do not need to conform and implement the delegate methods.
I implemented iAd into my swift sprite kit application, but want to make it so that iAd displays a new ad every minute for example. I supplied my code for how I implemented iAd below.
self.canDisplayBannerAds = true
self.adBannerView?.delegate = self
self.adBannerView?.hidden = true
}
func bannerViewWillLoadAd(banner: ADBannerView!) {
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
self.adBannerView?.hidden = false
}
func bannerViewActionDidFinish(banner: ADBannerView!) {
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
return true
}
func bannerView(banner: ADBannerView!, didFailToReceiveWithError error:NSError!) {
}
You can use NSTimer for that. Keep in mind that if your app goes into background mode, it may cause some inaccuracies. However since it's only for showing ads, it's shouldn't be a big issue.