Reputation: 161
I've been trying to add an Admob banner advertisement to my spritekit game, and although I've been successful in getting the advertisement to show up initially in the first scene of the game (MenuScene), when I leave that scene (to go to GameScene, SettingsScene, etc.) and then return to the menu scene, I get the error: unexpectedly found nil while unwrapping an Optional value
Basically, whenever I leave MenuScene, the banner ad variable becomes nil, and when I return to it the game bugs out because it's trying to call on a nil value.
I have tried initializing the banner ad in the GameViewController, MenuScene, and SettingsScene (with the methods remaining in GameViewController and just being called in the MenuScene or SettingsScene in the two latter options) - the banner ad always became when leaving the menu scene, and was nil upon arrival in the settings scene.
I suspect that my problem may have something to do with the fact that the GameViewController is only directly related to the MenuScene, and that when the player transitions away from MenuScene (and consequently away also from GameViewController) to another scene, all the variables in GameViewController become nil. However, I have no idea what to do, and would appreciate some help in this regard. Here is my initialization code:
In GameViewController:
var bannerAd: GADBannerView!
func initializeBanner() {
bannerAd = GADBannerView(adSize: kGADAdSizeSmartBannerLandscape, origin: CGPoint(x: 0, y: self.view.frame.size.height-32))
bannerAd.isHidden = true
bannerAd.adUnitID = "ca-app-pub-3940256099942544/2934735716"
bannerAd.rootViewController = self
view.addSubview(bannerAd)
}
func requestBanner() {
let request = GADRequest()
request.testDevices = ["31340db3ea728bd5faf2789325b27620"]
bannerAd.load(request)
}
In MenuScene:
var gameVC: GameViewController!
override func didMove(to view: SKView) {
gameVC.initializeBanner()
gameVC.requestBanner()
gameVC.bannerAd.isHidden = false
}
When transitioning to (for example) SettingsScene:
gameVC.bannerAd.isHidden = true
Upvotes: 1
Views: 298
Reputation: 10674
As you mentioned you will loose the reference to your GameViewController when you change scenes. In general its not the best practice to reference the GameViewController in your SKScenes.
A better approach to call the GameViewController method would be using Notification Center or delegation.
Create a key for your notification to avoid typos. You can put this anywhere you like in your project (outside any class or a new .swift file)
extension Notification.Name {
static let showBannerAd = Notification.Name(rawValue: "ShowBanner")
}
Than in your GameViewController add the observer in ViewDidLoad to call the requestBanner method
NotificationCenter.default.addObserver(self, selector: #selector(requestBanner), name: .showBannerAd, object: nil) // selector is the method to call
and than in your SKScene(s) you can post the notification like so when you need to show the banner.
NotificationCenter.default.postNotificationName(.showBannerAd, object: nil)
How to present ads during certain scenes in sprite-kit?
Also to avoid such crashes you should not force unwrap your properties (!) unless you know 100% that it will not be nil. By writing
var bannerAd: GADBannerView!
you tell xCode that this banner property will always be there and will never be nil. Thats not the case tho and thus makes your code less solid. So instead you should make it an optional property like this
var bannerAd: GADBannerView?
and than your setup method like this
func initializeBanner() {
bannerAd = GADBannerView(adSize: kGADAdSizeSmartBannerLandscape, origin: CGPoint(x: 0, y: self.view.frame.size.height-32))
bannerAd?.isHidden = true
bannerAd?.adUnitID = "ca-app-pub-3940256099942544/2934735716"
bannerAd?.rootViewController = self
view.addSubview(bannerAd!)
}
Now when the banner property is nil you will not crash when for example saying this
bannerAd?.isHidden = true
Alternatively I have a helper on Github which will make this much easier and cleaner.
https://github.com/crashoverride777/SwiftyAds
Hope this helps
Upvotes: 3