I am having a problem with my code. I am trying to programmatically add an iAd to my view in Xcode. There are a few times when it randomly works, and I run it again without changing any code, and it doesn't work any more. During those few times it randomly works, when I switch to a different view and then back to the one the iAd is in, the iAd is just an empty iAd frame, not showing the animation it should be. It is simply not loading the iAd. Please Help! Code:
import UIKit
import Foundation
import iAd
class ViewController: UIViewController, ADBannerViewDelegate {
//variables*******************************************
var adBannerView = ADBannerView(frame: CGRect.zeroRect)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.canDisplayBannerAds = true
loadAds()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//iAd**************************************************
func loadAds()
{
adBannerView = ADBannerView(frame: CGRect.zeroRect)
adBannerView.center = CGPoint(x: adBannerView.center.x, y: view.bounds.size.height - adBannerView.frame.size.height / 2 - 50)
adBannerView.delegate = self
adBannerView.hidden = true
view.addSubview(adBannerView)
}
func bannerViewWillLoadAd(banner: ADBannerView!)
{
println("sort of working1")
}
func bannerViewDidLoadAd(banner: ADBannerView!)
{
adBannerView.hidden = false
println("sort of working2")
}
func bannerViewActionDidFinish(banner: ADBannerView!)
{
println("sort of working3")
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool
{
println("sort of working4")
return true
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!)
{
adBannerView.hidden = true
println("error1")
}
}
UPDATE 1/28/15:
Somehow, the iAds work now without changing the code, but I am experiencing another problem. After I leave the view that the iAd is in, it turns into a blank white frame with the small iAd logo in the bottom corner of the frame. Also, another large problem is that it darkens the tab bar for the view with the iAd.
Not even the println's are working? the iAds are not always displayed, depends of the connectivity to the iAd servers, that's the reason why you should implement the didFailToReceiveAdWithError and hide the banner, in case of no information is comming from the server due to some problem.
If you use the automatic iAd presentation you don't need to do anything else after self.canDisplayBannerAds = true. Your view controller will automatically shrink and auto layout will be triggered when an iAd is available. The iAd will be presented at the bottom.
Thus your sample code can just be:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.canDisplayBannerAds = true
}
If you need a different behaviour here is a simple iAd example. It uses a singleton ADBannerView and can present it at the top of the view.
Anyway consider that the proper way to manually instantiate an ADBannerView is: ADBannerView(adType: ADAdType.Banner)
Related
I have been wanting to properly fix an iAd to the top of my screen and I tried several solutions but to no avail. I need to fix the issue where you get a white rectangle in place of the iAd banner when disconnected and also it sometimes appears on the top and sometimes on the bottom. How can I make it always appear in the top centre, instead of going from top to bottom and bottom to top randomly?
My code:
class ViewController: UIViewController, ADBannerViewDelegate, UITextFieldDelegate {
#IBOutlet var adBannerView: ADBannerView!
var bannerIsVisible : Bool = false
override func viewDidLoad() {
super.viewDidLoad()
self.canDisplayBannerAds = true
self.adBannerView?.delegate = self
self.adBannerView?.hidden = true
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
self.adBannerView?.hidden = true
}
func bannerViewActionDidFinish(banner: ADBannerView!) {
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
return true
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
self.adBannerView?.hidden = false
}
func bannerViewWillLoadAd(banner: ADBannerView!) {
}
The ADBannerView displaying on the bottom of your devices screen is created by self.canDisplayBannerAds = true. self.canDisplayBannerAds = true can be used for a no hassle way of implementing iAd banners in your application. This will create an ADBannerView for you and show or hide the ADBannerView depending on whether it receives an ad or not from the iAd network.
You need to remove self.canDisplayBannerAds = true from your viewDidLoad.
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've created an iAd banner in the storyboard by dragging into the UITableViewController
In my UITableViewController, I have these codes
#IBOutlet var adBannerView: ADBannerView!
In ViewDidLoad
self.canDisplayBannerAds = true
self.adBannerView.delegate = self
self.adBannerView.hidden = true
And these delegates method
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
return true
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
self.adBannerView.hidden = false
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
println("didFailToReceiveAdWithError")
self.adBannerView.hidden = true
}
Sometimes when the UITableViewLoads, it would look like this
http://i.stack.imgur.com/P4p1J.png
The iAd will be at the bottom of the TableView and it moves with it
However sometimes it would just load at the bottom of the View with a fixed position which is what i want.
How do i get the iAd to be fixed at the bottom and doesn't moves with the tableview?
Your issue is that you are actually creating two ADBannerView's here. Once in Interface Builder and another in your viewDidLoad with self.canDisplayBannerAds = true. Remove self.canDisplayBannerAds = true from your viewDidLoad to correct this.
To pin your ADBannerView you created in Interface Builder to the bottom of your applications view you need to set its constraints. Pin your ADBannerView to the bottom of the view with Bottom Space to: Bottom Layout Guide and align it to Align Center X to: Superview in Interface Builder.
This will keep the ADBannerView on the bottom of your applications view and resize it appropriately when on devices with different screen dimensions.
I was unable to add any constraints in the storyboard. I removed the iAd banner from storyboard and just use:
self.canDisplayBannerAds = true
Now it works fine
I had a similar problem so I just coded my manually. Nothing worked when my code was in ViewDidLoad but instead ViewWillAppear all I needed was
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.canDisplayBannerAds = true
self.banner.delegate = self
}
And of course add the ADBannerViewDelegate at the top of the class then its methods:
let banner = ADBannerView(adType: .Banner)
func bannerViewDidLoadAd(banner: ADBannerView!) {
self.view.addSubview(banner)
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
banner.removeFromSuperview()
}
when I run the game a white box appears at the top of the game which I'm guessing the ads are suppose to appear in there, but no ads ever appear!
Am I doing something wrong, missing a certain piece of code somewhere, or blind? haha.
I'm quite new to this iAd and everything!
Here is an image of it
Here is the ViewController Code!
import UIKit
import SpriteKit
import iAd
class GameViewController: UIViewController, ADBannerViewDelegate{
#IBOutlet var Banner: ADBannerView!
override func viewDidLoad() {
super.viewDidLoad()
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
// Configure the view.
let skView = self.view as SKView
skView.ignoresSiblingOrder = true
/* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
skView.presentScene(scene)
loadAds()
}
}
func loadAds() {
self.canDisplayBannerAds = true
Banner = ADBannerView(frame: CGRect.zeroRect)
Banner.center = CGPointMake(Banner.center.x, view.bounds.size.height - Banner.frame.size.height / 2)
Banner.delegate = self
Banner.hidden = true
view.addSubview(Banner)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
self.Banner.hidden = true
}
func bannerViewWillLoadAd(banner: ADBannerView!) {
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
return willLeave
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
self.Banner.hidden = false
}
Your issue is that you are using self.canDisplayBannerAds = true in addition to creating an ADBannerView programmatically. Remove self.canDisplayBannerAds = true from your loadAds function.
It seems to be working all of the sudden! Was getting error message, but it has gone away and the Ad has actually loaded! :)
Don't know what was going on!
So I am trying to set up a simple iAd banner in my application but I am getting these two warnings in the output:
WARNING: More than 10 instances of ADBannerView or ADInterstitialView
currently exist. This is a misuse of the iAd API, and ad performance will
suffer as a result. This message is printed only once.
and
<Error>: CGAffineTransformInvert: singular matrix.
This is what I am using to implement my ADBannerView:
var adBannerView = ADBannerView()
func loadAds() {
adBannerView = ADBannerView(frame: CGRect.zeroRect)
adBannerView.center = CGPoint(x: adBannerView.center.x, y: view.bounds.size.height - adBannerView.frame.size.height / 2)
adBannerView.delegate = self
adBannerView.hidden = true
view.addSubview(adBannerView)
}
//BannerView did load ad
func bannerViewDidLoadAd(banner: ADBannerView!) {
adBannerView.hidden = false
}
//BannerView failed to load
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
adBannerView.hidden = true
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
loadAds()
//(rest of the code is from here onwards)
I tried adding this to stop the first error: (hasn't worked)
//BannerView will disappear
override func viewWillDisappear(animated: Bool) {
adBannerView.removeFromSuperview()
adBannerView.delegate = nil
}
The issue is every time you load your view you are creating a new instance of ADBannerView. What we need to do is create a ADBannerView once in our AppDelegate.swift and then present this ADBannerView on which ever views we would like to have an iAd banner. This is also called a Shared iAd Banner. In this example, I've created an ADBannerView in my AppDelegate.swift and then added it to my ViewController.swift's view.
AppDelegate.swift
import UIKit
import iAd // Import iAd
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, ADBannerViewDelegate { // Include the delegate for our banner
var window: UIWindow?
var adBannerView = ADBannerView() // Create our one ADBannerView
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Set delegate and hide banner initially
adBannerView.delegate = self
adBannerView.hidden = true
return true
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
print("bannerViewDidLoadAd")
adBannerView.hidden = false
}
func bannerViewActionDidFinish(banner: ADBannerView!) {
print("bannerViewActionDidFinish")
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
print("didFailToReceiveAdWithError: \(error)")
adBannerView.hidden = true
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate // Create reference to our app delegate
override func viewWillAppear(animated: Bool) {
// Position
appDelegate.adBannerView.center = CGPoint(x: view.frame.midX,
y: view.frame.height - appDelegate.adBannerView.frame.height / 2)
// Add to view
view.addSubview(appDelegate.adBannerView)
}
Don't forget to remove the code from your viewWillDisappear(animated: Bool) function that you added previously. If you click on the banner and then dismiss it this function will be called and removing our banner from our view and setting our banners delegate equal to nil too soon will cause issues.
If you don't want to care about the size, position, error handling and the delegate methods of your banner ad you can also use:
self.canDisplayBannerAds = true
This solved the error in my App, because Apple takes also care about the number of instances
I've written a short tutorial about this:
link
If you want the banner to persist between the tabs and not disappear when rapidly switching tabs, you've got to do the iAd Suite approach: http://developer.apple.com/library/ios/#samplecode/iAdSuite/Introduction/Intro.html (Check out BannerViewController.m file - not in Swift, but it's not hard to convert it)
This approach also doesn't require you to modify any go the view controllers within your tabs. You simply have to have a relationship segue from your tab bar controller to a View Controller that has container view embedded into it. Do that in your storyboard. Also, you need to set Custom Class to BannerViewController for each tab, and embed your content into the embedded view. Take a look at this post for details on how to do it it the Storyboard: https://stackoverflow.com/a/16205420/5007500
If you are not using Storyboard - you need to set BannerViewController as parent view controller for each of your tabs.