I have this game project and it has a coin system. I also have an option for users to watch a video ad to get 50 coins added to their total. Since the shop page is a SKScene, I run the ad through the view controller and when it is done presenting, the viewcontroller runs a function inside the scene that should update the amount of coins and the label that displays them.
Here is the code for my view controller:
class GameViewController: UIViewController , GADRewardBasedVideoAdDelegate {
var rewardBasedVideo: GADRewardBasedVideoAd!
var rewardvideoisinprogress = false
var interstitial: GADInterstitial!
var adcounter = 0
override func viewDidLoad() {
super.viewDidLoad()
adcounter = UserDefaults.standard.integer(forKey: "AdCounter")
print(adcounter)
createandloadvideoad()
interstitial = GADInterstitial(adUnitID: "ca-app-pub-3343126174384559/7308554354")
let request = GADRequest()
interstitial.load(request)
ThemeShop().updatecoins()
NotificationCenter.default.addObserver(self, selector: #selector(GameViewController.presentvideoad), name: NSNotification.Name("video"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(GameViewController.inter), name: NSNotification.Name("inter_"), object: nil)
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
if let scene = SKScene(fileNamed: "MainMenu") {
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Present the scene
view.presentScene(scene)
}
view.ignoresSiblingOrder = true
}
}
@objc func inter(){
adcounter = adcounter + 1
print(adcounter)
if adcounter == 2{
adcounter = 0
if interstitial.isReady {
interstitial.present(fromRootViewController: self)
interstitial = createad()
} else {
print("Ad wasn't ready")
}
}
UserDefaults.standard.set(adcounter, forKey: "AdCounter")
}
func createad() -> GADInterstitial {
let inter = GADInterstitial(adUnitID: "ca-app-pub-3343126174384559/7308554354`")
inter.load(GADRequest())
return inter
}
func createandloadvideoad(){
rewardBasedVideo = GADRewardBasedVideoAd.sharedInstance()
rewardBasedVideo?.delegate = self
if !rewardvideoisinprogress && rewardBasedVideo?.isReady == false{
//ca-app-pub-3343126174384559/3425197396
rewardBasedVideo?.load(GADRequest(), withAdUnitID: "ca-app-pub-3940256099942544/1712485313")
rewardvideoisinprogress = true
}
}
@objc func presentvideoad(){
if rewardBasedVideo?.isReady == true{
rewardBasedVideo?.present(fromRootViewController: self)
}else{
print("Was NOt Reardyadjfsjfsalfkj")
}
createandloadvideoad()
}
func rewardBasedVideoAd(_ rewardBasedVideoAd: GADRewardBasedVideoAd,
didFailToLoadWithError error: Error) {
print("Reward based video ad failed to load: \(error.localizedDescription)")
rewardvideoisinprogress = false
}
func rewardBasedVideoAdDidReceive(_ rewardBasedVideoAd: GADRewardBasedVideoAd) {
print("Reward based video ad is received.")
}
func rewardBasedVideoAdDidOpen(_ rewardBasedVideoAd: GADRewardBasedVideoAd) {
print("Opened reward based video ad.")
}
func rewardBasedVideoAdDidStartPlaying(_ rewardBasedVideoAd: GADRewardBasedVideoAd) {
print("Reward based video ad started playing.")
}
func rewardBasedVideoAdDidClose(_ rewardBasedVideoAd: GADRewardBasedVideoAd) {
rewardvideoisinprogress = false
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1500) , execute: {
print("Brikdsajfaslkd")
ThemeShop().updatecoins()
})
}
func rewardBasedVideoAd(_ rewardBasedVideoAd: GADRewardBasedVideoAd,
didRewardUserWith reward: GADAdReward) {
var coins = UserDefaults.standard.integer(forKey: "Coins")
coins = coins + 50
UserDefaults.standard.set(coins, forKey: "Coins")
}
}
This is the function inside the SKScene:
func updatecoins(){
print("Updating")
coins = UserDefaults.standard.integer(forKey: "Coins")
print("Coins: \(coins)")
self.coinlabel.text = String(self.coins)
print(self.coinlabel.text)
}
I know that the coins are being added to the balance behind the scenes because if I exit the scene and reenter, the coins show up like they should.
you're trying to call a function on a class variable of ThemeShop you need to be calling the func on an instance variable of the class.
you don't show your ViewController code so you may have to adapt this accordingly
have a scene variable at the top of your viewController
then in your viewDidLoad when you load the scene put it inside of the variable
then in your viewController when you need to access the scene