googlemobileads google ios swift null admob interstitial

ios - googlemobileads



Swift Admob Interstitial Error (2)

Apuesto a que este es tu problema:

if (interstital.isReady) { print("there is an inter ready") interstital.presentFromRootViewController(self) interstital = CreateAd()

Estás presentando tu intersticial y luego sobrescribiendo inmediatamente tu interstitial . Debería implementar los métodos de delegado de GADInterstitial y llamar a su func CreateAd() -> GADInterstitial una vez que se func CreateAd() -> GADInterstitial func interstitialDidDismissScreen(ad: GADInterstitial!) .

Esto es bastante largo, pero probablemente sea una solución realmente fácil. La mayor parte de esto es código, solo pasa al final y habrá un tl; dr

Oye, así que seguí unos 10 tutoriales para conseguir que los intersticiales de Admob funcionen en mi juego Swift Spritekit. Excepto que todos los tutoriales que he visto usan un IBAction con un botón. Actualmente me gustaría que los anuncios aparezcan de vez en cuando en el menú. (solo para empezar, podría cambiarlo más tarde). Todo esto funciona perfectamente, pero una vez que presiono el botón de reproducción (yendo a una escena diferente) y luego regreso a la escena del menú. (GameScene) La función intersticial ya no sucede. No hay ningún error, simplemente no lo hace más hasta que la aplicación se cierra por completo y se vuelve a abrir.

Aquí está el código.

En mi clase GameViewController tengo:

var interstital: GADInterstitial!

Y en el GameViewController cargué tengo:

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)

También en la clase GameViewController tengo estas funciones:

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 }

En la clase de GameScene (El menú) tengo:

var viewController: GameViewController!

Y en la clase de GameScene tengo esta función para mostrar un anuncio intersticial.

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") }

Entonces, llamo a la función ShowAd (que se encuentra en gameviewcontroller) en mi GameScene cada 20 segundos, ( lo he confirmado al menos cree que está llamando a la función ) . Funciona perfectamente cuando la aplicación se abre para empezar. Pero cuando cambio de escena y luego regreso a la escena del menú (GameScene), la función Prints en mi GameScene sigue sucediendo, y mi código cree que está llamando a la función ShowAd, pero parece que no está pasando nada, no aparecen los intersticiales, ni siquiera las impresiones que se encuentran en la función ShowAd en GameViewController.

Entonces parece que después de cambiar las escenas y regresar, mi juego olvida lo que es el GameViewController. Si me refiero al GameViewController sin un ''?'' se bloqueará mi juego con el error "inesperadamente encontrado nil al desenvolver una opción". Entonces, después de cambiar escenas, ¿tal vez GameViewController se vuelve nulo? Cómo puedo arreglar esto.

¡¡¡Por favor, ayúdame!!! (Soy nuevo en la programación en caso de que no pueda decirlo. Sé que debe ser tentador hacer un comentario sarcástico sobre mi código, es realmente escueto y no tan bueno en este momento).

Muchas gracias si me pueden ayudar, y wow ... gracias por leer todo esto ...;)


Lo más probable es que, una vez que realice la transición a una nueva escena, la propiedad viewController esté establecida en cero, y por lo tanto, se bloqueará si usa!

En general, no es la mejor práctica para hacer referencia a viewController en su SKScenes, debe usar Delegation o NSNotification Center.

1) Centro de notificaciones (forma más fácil)

En su ViewController, donde tiene la función de mostrar anuncios, agregue un observador NSNotificationCenter en ViewDidLoad

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(showAd), name: "ShowInterAdKey", object: nil)

(El selector es la función para llamar y el nombre es la clave para hacer referencia a este observador)

En sus SKScenes, cuando desea mostrar el anuncio simplemente publica la notificación

NSNotificationCenter.defaultCenter().postNotificationName("ShowInterAdKey", object: nil)

2) Para ejemplos de delegación, revisa estos artículos.

http://stephenradford.me/creating-a-delegate-in-swift/

https://www.natashatherobot.com/ios-weak-delegates-swift/

3) También noté que no está precargando los anuncios antes de mostrarlos, lo cual no es muy eficiente y puede causar demoras en la publicación de anuncios.

Deberías llamar

interstital = CreateAd()

en viewDidLoad, entonces cargará el primer anuncio lo antes posible. De lo que deberías usar el método delegado adMob

func interstitialDidDismissScreen(ad: GADInterstitial!) { // load next ad interstital = CreateAd()

para cargar inmediatamente el siguiente anuncio una vez que se cierra el actual.

Para usar los delegados, puede crear una extensión en 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) } }

Para asegurarse de que estos se llamen vaya a su función createAd y agregue esta línea antes de devolver el anuncio

let interstitial = ... interstitial.delegate = self

Finalmente, su método showAd debería verse así

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) También puede consultar mi ayudante en gitHub si está buscando una solución más reutilizable.

https://github.com/crashoverride777/Swift-AdMob-AppLovinTVOS-CustomAds-Helpers

Como consejo general, también debe seguir las convenciones de nomenclatura rápida, su función y las propiedades deben comenzar con letras pequeñas. Solo las clases, estructuras, enumeraciones y protocolos deben comenzar con letras mayúsculas. Hace que tu código sea más difícil de leer por ti mismo y en porque está marcado en azul, pero no debería ser así. A veces lo haces y otras no.

Espero que esto ayude