import iAd
#IBOutlet weak var Banner: ADBannerView!
override func viewDidLoad() {
super.viewDidLoad()
Banner.hidden = true
Banner.delegate = self
self.canDisplayBannerAds = true
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
return true
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
self.Banner.hidden = false
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
NSLog("Error")
}
func bannerViewWillLoadAd(banner: ADBannerView!) {
}
Hello,
I am currently developing an iOS app with Xcode 7.2, Swift 2.0, and iOS 9.2. I have implemented iAds, and it works perfectly. However in my region the fill rate is not high, and I would like to use Google's AdMob to advertise on my app, as a backup. I would like for the AdMob banner ad to show up when iAd does not receive an ad. Note that I am new to Swift, and have no knowledge of Objective-C. Thanks.
You can load the AdMob ad (and view) in the didFailToReceiveAdWithError. supposing that this callback will be called when no iAd is available (I think so).
You idea is, you are going to support two add platforms.
In this case, suppose you are trying to load adMob first.
If adMob will fails, simply load iAD.
Similarly if iAD will fail, load adMob.
So in didFail delegate method of adMob, write code to load iAD.
In didFail delegate method of iAD, write code to load adMob.
this way you can get your required result.
Related
I have an iOS app in swift language. I have included Google AdMob ads in my app. I have implemented banner ads and interstitial ads but I am not able to generate the Ad ID for Native Ads. I have found an Ad Sense custom search native ads but I don't know for what purpose these ads are used. Can I use AdSense native ads in my mobile app. Please suggest me what to do and how to progress?
Below are the steps that I always follow whenever it comes to adding Google Admob Ads. Do take note that the example below will implement Google Admob in a table view.
Install Google Admob Ads via pod pod 'Google-Mobile-Ads-SDK'
In AppDelegate > didFinishLaunchingWithOptions, setup/configure Google Admob GADMobileAds.configure(withApplicationID: Constant.googleAdmobAppID)
Next, create a class for Google Admob Banner.
import Foundation
import GoogleMobileAds
class GoogleAdMobBanner: NSObject, GADBannerViewDelegate {
unowned var sourceTableViewController: UITableViewController
var adBannerView: GADBannerView
init(sourceTableViewController: UITableViewController) {
self.sourceTableViewController = sourceTableViewController
adBannerView = GADBannerView(adSize: kGADAdSizeSmartBannerPortrait)
super.init()
adBannerView.adUnitID = Constant.googleAdmobBannerID
adBannerView.delegate = self
adBannerView.rootViewController = sourceTableViewController
}
// MARK:- Google Admob
func adViewDidReceiveAd(_ bannerView: GADBannerView) {
print("Banner loaded successfully")
// Reposition the banner ad to create a slide up effect
let translateTransform = CGAffineTransform(translationX: 0, y: -bannerView.bounds.size.height)
bannerView.transform = translateTransform
UIView.animate(withDuration: 0.5) {
bannerView.transform = CGAffineTransform.identity
self.sourceTableViewController.tableView.tableHeaderView = bannerView
}
}
func adView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: GADRequestError) {
print("Fail to receive ads")
print(error)
}
func loadAdMob() {
let request = GADRequest()
request.testDevices = [kGADSimulatorID]
adBannerView.load(request)
}
}
Declare a lazy loaded admob banner in the desired class.
class MyController: UITableViewController {
lazy var googleAdMobBanner: GoogleAdMobBanner = {
return GoogleAdMobBanner(sourceTableViewController: self)
}()
}
Lastly, load the Google Admob in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
googleAdMobBanner.loadAdMob()
}
This is pretty long but it's probably a really easy fix.
Most of this is code, just skip to the bottom and there'll be a tl;dr
Hey, so I've followed about 10 tutorials on getting Admob interstitials to work in my Swift Spritekit game. Except all the tutorials I've seen use an IBAction with a button.
Currently I would like the ads to pop up every once in a while on the menu. (just to begin with, I might change it later).
This all works perfectly, but once I hit the play button (going to a different scene) and then return to the menu scene. (GameScene) The interstitial function no longer happens. There is no error, it just doesn't do it any more until the app is completely closed and re-opened.
Here's the code.
In my GameViewController class I have:
var interstital: GADInterstitial!
And in the GameViewController did load I have:
if let scene = GameScene(fileNamed:"GameScene") {
let skView = self.view as? SKView
skView!.ignoresSiblingOrder = false
scene.scaleMode = .AspectFill
scene.viewController = self
skView!.presentScene(scene)
interstital = GADInterstitial(adUnitID: "ca-app-pub-9776687746813194/9687097060")
let request = GADRequest()
interstital.loadRequest(request)
Also in the GameViewController class I have these functions:
func ShowAd() {
print("doing the showadfunc now")
if (interstital.isReady) {
print("there is an inter ready")
interstital.presentFromRootViewController(self)
interstital = CreateAd()
}
else{
print("The interstitial wasn't ready.")
}
}
func CreateAd() -> GADInterstitial {
let interstital = GADInterstitial(adUnitID: "ca-app-pub-9776687748683194/9687247060")
interstital.loadRequest(GADRequest())
return interstital
}
In my GameScene's (The menu) class I have:
var viewController: GameViewController!
And in my GameScene's class I have this function for displaying an interstitial ad.
func adThing(){
//viewController?.ShowAd()
print("starting the ad function")
let waitForInterstitial = SKAction.waitForDuration(15.0)
let waitForInterstitialShort = SKAction.waitForDuration(3.0)
let showInterstitialAd = SKAction.runBlock({self.viewController?.ShowAd(); print("the function has been called..")})
let waitThenShowInterstitial = SKAction.sequence([showInterstitialAd,waitForInterstitial])
let waitThenShowInterStitialForever = SKAction.repeatActionForever(waitThenShowInterstitial)
//self.runAction(waitThenShowInterStitialForever)
self.runAction(waitForInterstitialShort, completion: {
print("its waited 3 seconds and will now start the ad thingo")
self.runAction(waitThenShowInterStitialForever)
})
print("done")
}
So, I call the ShowAd function (which is located in gameviewcontroller) in my GameScene every 20 seconds, (I have confirmed it at least thinks it is calling the function.) It works perfectly when the app is opened to begin with. But when I change scene and then return to the menu scene (GameScene), the Prints in my GameScene function keep happening, and my code thinks that it is calling the ShowAd function, but it seems that nothing is happening, no interstitials pop up, not even the prints that are in the ShowAd function in the GameViewController.
So it seems like after I change scenes and return, my game forgets what the GameViewController is. If I refer to the GameViewController without a '?' it will crash my game with the error "unexpectedly found nil while unwrapping an optional." So after changing scenes, maybe GameViewController becomes nil? How can I fix this.
Please help me!!! (I'm new to programming in case you can't tell. I know it must be tempting to make a snide comment about my code, it is really bare bones and not that good at the moment.)
Thank you so much if you can help me, and wow.. thanks for reading all this.. ;)
You problem most likely is that once you transition to a new scene the viewController property is set to nil hence a crash if you use !.
In general its not the best practice to reference the viewController in your SKScenes, you should use Delegation or NSNotification Center.
1) Notification Center (easiest way)
In your ViewController where you have the function to show ads add a NSNotificationCenter observer in ViewDidLoad
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(showAd), name: "ShowInterAdKey", object: nil)
(Selector is the function to call and name is the key to reference this observer)
Than in your SKScenes when you want to show the ad you simply post the notification
NSNotificationCenter.defaultCenter().postNotificationName("ShowInterAdKey", object: nil)
2) For delegation examples check out these articles.
http://stephenradford.me/creating-a-delegate-in-swift/
https://www.natashatherobot.com/ios-weak-delegates-swift/
3) I also noticed that you are not preloading the ads before you show them, which is not very efficient and can cause delays showing ads.
You should call
interstital = CreateAd()
in viewDidLoad so it will load the first ad ASAP. Than you should use the adMob delegate method
func interstitialDidDismissScreen(ad: GADInterstitial!) {
// load next ad
interstital = CreateAd()
to immediately load the next ad once the current one is closed.
To use the delegates you can create an extension in ViewController
extension MyViewController: GADInterstitialDelegate {
func interstitialDidReceiveAd(ad: GADInterstitial!) {
print("AdMob interstitial did receive ad from: \(ad.adNetworkClassName)")
}
func interstitialWillPresentScreen(ad: GADInterstitial!) {
print("AdMob interstitial will present")
// pause game/app
}
func interstitialWillDismissScreen(ad: GADInterstitial!) {
print("AdMob interstitial about to be closed")
}
func interstitialDidDismissScreen(ad: GADInterstitial!) {
print("AdMob interstitial closed, reloading...")
interstitial = createAd()
}
func interstitialWillLeaveApplication(ad: GADInterstitial!) {
print("AdMob interstitial will leave application")
// pause game/app
}
func interstitialDidFailToPresentScreen(ad: GADInterstitial!) {
print("AdMob interstitial did fail to present")
}
func interstitial(ad: GADInterstitial!, didFailToReceiveAdWithError error: GADRequestError!) {
print(error.localizedDescription)
}
}
To make sure these get called go to your createAd function and add this line before returning the ad
let interstitial = ...
interstitial.delegate = self
Finally your showAd method should look like this
func showAd() {
print("doing the showadfunc now")
if (interstital.isReady) {
print("there is an inter ready")
interstital.presentFromRootViewController(self)
} else{
print("The interstitial wasn't ready, reloading again.")
interstital = CreateAd()
}
}
4) You can also check out my helper on gitHub if you are looking for a more reusable solution.
https://github.com/crashoverride777/Swift-AdMob-AppLovinTVOS-CustomAds-Helpers
As a general tip you should also follow the swift naming conventions, your func and properties should start with small letters. Only classes, structs, enums and protocols should start with capital letters.
It makes your code harder to read for yourself and on stackoverflow because it is marked blue but shouldn't. You are sometimes doing and sometimes not.
Hope this helps
I'd bet this is your issue:
if (interstital.isReady) {
print("there is an inter ready")
interstital.presentFromRootViewController(self)
interstital = CreateAd()
You're presenting your interstitial and then immediately overwriting your interstitial. You should be implementing the GADInterstitial's delegate methods and calling your func CreateAd() -> GADInterstitial once func interstitialDidDismissScreen(ad: GADInterstitial!) is called.
if your device keeps crashing because of:
interstitial.delegate = self
then put it in your CreatAndLoadInterstitial(), not your viewDidLoad()
I've run into a very strange issue with AdMob. On my main project I receive error that there is no ad to load (when trying to fetch GADInterstitial).
However when I created a new project, copied the AdMob related sources, launched the project it loaded the ad without any problem (it looks like it always loads the test ad; I gave it few tries just to be sure).
On both projects I'm using the same Google pods:
pod 'Google-Mobile-Ads-SDK'
pod 'Google/Analytics'
I've been trying various solutions, generating different ad unit id's, tested the new project without analytics, then attached analytics to it. It worked like a charm during every step.
On my main project I got the ad once, strangely it was for ad unit id (banner view). Sadly since then I cannot get neither banner or interstitial ad (I couldn't retrieve the interstitial ad before).
My target platform is iOS 8+.
Sources, the AdMobManager
import GoogleMobileAds
class AdMobManager {
static let sharedInstance = AdMobManager()
private(set) var interstitial: GADInterstitial!
func loadInterstitialAd(delegate: GADInterstitialDelegate) -> GADInterstitial {
interstitial = GADInterstitial(adUnitID: "same-ad-unit-id-for-both-projects")
interstitial.delegate = delegate
let request = GADRequest()
request.testDevices = [ "same-test-id-for-both-projects" ]
interstitial.loadRequest(request)
return interstitial
}
}
And the ViewController
import UIKit
import GoogleMobileAds
class ViewController: UIViewController {
private var interstitial: GADInterstitial!
override func viewDidLoad() {
interstitial = AdMobManager.sharedInstance.loadInterstitialAd(self)
}
}
extension ViewController: GADInterstitialDelegate {
func interstitialDidReceiveAd(ad: GADInterstitial!) {
if interstitial.isReady {
interstitial.presentFromRootViewController(self)
} else {
NSLog("Not ready")
}
}
func interstitial(ad: GADInterstitial!, didFailToReceiveAdWithError error: GADRequestError!) {
NSLog("Error: \(error.debugDescription)")
}
}
Cause of my problem was custom User-Agent.
Hope that save somebody hours of debugging since AdMob documentation doesn't cover that.
I wrote this piece of code with Swift so that when I push a button an Admob ad shows up, and now my app is showing a test Admob ad. My question is how I can transition from showing a test ad to a real world ad? I'm using the simulator on Xcode by the way since I don't have an iPhone!
import UIKit
import Parse
import GoogleMobileAds
class NewsPageViewController: UIViewController {
var interstitial:GADInterstitial!
override func viewDidLoad() {
super.viewDidLoad()
self.interstitial = self.createAndLoadAd()
}
func createAndLoadAd() -> GADInterstitial {
interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
var request = GADRequest()
request.testDevices = ["2077ef9a63d2b398840261c8221a0c9b"]
interstitial.loadRequest(request)
return interstitial
}
#IBAction func buttonTapped(sender: AnyObject) {
if (self.interstitial.isReady) {
self.interstitial.presentFromRootViewController(self)
self.interstitial = self.createAndLoadAd()
}
}
Do this:
1-remove "request.testDevices = ["2077ef9a63d2b398840261c8221a0c9b"]
2- Create an Admob account on google's website, then create an app in your account,then, replace the default adUnitID given in the google's tutorial with the one in the created app.
3- Then, instead of test ad, you might get a full black screen ad. This one is because it takes a few hours before google starts to send real ads. Hope that helps.
iAd interstitials aren't showing up at all on the iPhone simulator, and they don't show up consistently on my iPhone. I've gone to the Developer settings, changed the fill rate to 100%, and turned on Unlimited Ad Presentation. No difference... an interstitial will generally show the first time it's supposed to, and then won't show again for anywhere from a few minutes to fifteen minutes. No idea what is causing the difference in time.
Also, there doesn't seem to be a way to track if the interstitial is going to show or not / if it actually showed or didn't. I realize there's an interstitial delegate, but it seems that isn't used anymore. The way I am calling my interstitial is using viewController.interstitialPresentationPolicy = ADInterstitialPresentationPolicy.Automatic
Thanks!
So it seems that using requestInterstitialAdPresentation is intended to only be used when your ADInterstitialPresentationPolicy is set to Automatic. When implementing your interstitials using a Manual ADInterstitialPresentationPolicy you must use presentInView to present the ad at your own intervals. When presenting your interstitial in this manner it does not load with its own close button to dismiss itself. So, what I've done is created a UIView to present the interstitial in and used the interstitials delegate methods to dismiss the UIView. The inconsistency with receiving an ad from the iAd network still arises when testing. Sometimes you receive an ad, sometimes it fails to load which allows us to request a new ad, and sometimes nothing happens at all. This just seems to be the nature of iAd's interstitials.
import UIKit
import iAd // Import iAd
class ViewController: UIViewController, ADInterstitialAdDelegate { // Include the delegate
var iAdInterstitial = ADInterstitialAd() // Our ad
var iAdInterstitialView = UIView() // View to present our ad in
var adLoaded = false // Bool to keep track if an ad is loaded or not
override func viewDidLoad() {
super.viewDidLoad()
setupAd()
}
func setupAd() {
// Set presentation to manual so we can choose when to present the interstitial
// Setting this will also fetch an interstitial ad for us
self.interstitialPresentationPolicy = ADInterstitialPresentationPolicy.Manual
iAdInterstitial.delegate = self // Set the delegate
// Make our view the same size as the view we will be presenting in
iAdInterstitialView.frame = self.view.bounds
}
func requestNewAd() {
// This will fetch an ad for us
ViewController.prepareInterstitialAds()
println("Requesting new ad")
}
#IBAction func presentAdButton(sender: AnyObject) {
if (adLoaded) {
// We have an ad that is loaded so lets present it
self.view.addSubview(iAdInterstitialView)
iAdInterstitial.presentInView(iAdInterstitialView)
}
else {
// No ad has been loaded
println("Ad not loaded")
}
}
func interstitialAdDidUnload(interstitialAd: ADInterstitialAd!) {
// Kinda works as expected
// Sometimes is called prematurely
// Sometimes takes minutes after ad is dismissed to be called
println("interstitialAdDidUnload")
// Get new ad
adLoaded = false
iAdInterstitialView.removeFromSuperview()
requestNewAd()
}
func interstitialAd(interstitialAd: ADInterstitialAd!, didFailWithError error: NSError!) {
// Failed to load ad so lets try again
println("didFailWithError: \(error)")
requestNewAd()
}
func interstitialAdWillLoad(interstitialAd: ADInterstitialAd!) {
// There is an ad and it has begun to download
println("interstitialAdWillLoad")
}
func interstitialAdDidLoad(interstitialAd: ADInterstitialAd!) {
// We got an ad
println("interstitialAdDidLoad")
adLoaded = true
}
func interstitialAdActionShouldBegin(interstitialAd: ADInterstitialAd!, willLeaveApplication willLeave: Bool) -> Bool {
println("interstitialAdActionShouldBegin")
return true;
}
func interstitialAdActionDidFinish(interstitialAd: ADInterstitialAd!) {
// Done with this ad. Lets get a new one
println("interstitialAdActionDidFinish")
iAdInterstitialView.removeFromSuperview()
adLoaded = false
requestNewAd()
}