Swift SpriteKit iAd - ios

I'm developing a game in Swift and I have a little problem that I couldn't solve. I'm working only with scenes, I have no UIViews. The main scene is where the game runs and when the players dies a new scene will be loaded. I want in that scene, where the player dies, to display a menu (which I did) and to display iAd banners. I tried also with UIViewControllers but I couldn't manage it. I want to make it only in SpriteKit and I don't know how. Could anybody help me please?

If you simply want to display an iAd banner then you'll need to do several things. First, import the iAd framework and import iAd the the top of your code. Then, use this function to display the banner. (oh, and adBannerView should be declared as a global variables within your skscene).
func loadAds()->ADBannerView{
adBannerView = ADBannerView(frame: CGRect.zeroRect)
adBannerView.center = CGPoint(x: adBannerView.center.x, y: view!.frame.size.height - adBannerView.frame.size.height / 2)
adBannerView.delegate = self
self.view?.addSubview(adBannerView)
return adBannerView
}
You may also want to include these functions. This one right here runs when the banner cannot load (this will most likely occur due to a network problem).
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
println("Ad cannot load")
self.adBannerView.hidden = true
}
This runs when the banner successfully loads.
func bannerViewDidLoadAd(banner: ADBannerView!) {
println("ad did load.")
self.adBannerView.hidden = false
}

Related

How to free scene until Interstitial is dismissed?

So I have a an app that uses interstitial ads. Specifically it is a a SpriteKit game written with Swift.
I have code setup that when the user presses the replay button from the game over scene an ad appears and then it changes back to the game scene to replay the game. Now where I am running into problems the scene changes while the interstitial ad is being displayed, sometimes this doesn't happen fast enough and user can tap the restart button again, causing the game to crash.
Is there a way to freeze the screen and ignore any taps while the ad is being called? And also to only have the scene change after the ad is dismissed?
The code when the restart button is pressed;
if restartButton.contains(pointOfTouch) {
score = 0
ballMovementSpeed = 2
displayAd()
delay(2.0) {
self.restartScene()
}
I am a bit confused as to where the interstitialDelegate is placed. I am trying to implement func interstitialDidDismissScreen(ad: GADInterstitial!) {} to trigger a change back to my game scene and nothing happens when I dismiss the ad.
I have tried placing it in override func didMove(to view: SKScene){} as well as when the restart button is pressed and still won't work. This is how i have the ad being called
fun loadAndShow() {
myAd = GADInterstitial()
let requestI = GADRequest()
myAd.setAdUnitID("adID")
requestI.testDevices = [kGADSimulatorID, "test device"]
myAd.delegate = self
myAd.load(requestI)
}
func interstitialDidReceiveAd(_ ad: GADInterstitial) {
if (self.myAd.isReady) {
myAd.present(fromRootViewController: self)
}
}
you can use delegate methods of admob so when interstitial is going to be shown you can remove the restart button or put a condition so that it would not work when ad is shown. Also to pause the game is also important if it is running using isPaused bool.
https://developers.google.com/admob/ios/ad-events

GameCenter Multiplayer Stuck on "Starting Game..."

I am currently working on my game and I have decided to enable multiplayer via GameCenter in the Game to allow users to play their friend. I have followed a tutorial by RayWinderLinch, but ran into a problem.
My problem is that when I load up the GKMatchMakingViewController and hit the big Play Now button on both devices it will find each other (which is meant to happen) and under the set game center user name it will say Ready.
This means that GameCenter has found each player and is ready to start the match which it should, but in my case the match never begins. It is stuck on a loop that says Starting Game... and nothing happens. It appears that the
func matchmakerViewController(viewController: GKMatchmakerViewController!, didFindMatch theMatch: GKMatch!)
and the
func match(theMatch: GKMatch!, player playerID: String!, didChangeState state: GKPlayerConnectionState)
method's are never ran. I am completely lost on what is going on. I have tried this many times over and over to fix the problem but nothing worked. I will attach an image that show's the screen of the application where my problem persists and I will also attach the code I am using.
I am using a framework based of of the GameKitHelper.h In the
mentioned tutorial above. It is written in swift and is called
GCHelper
Code
The code for GCHelper can be found using the GitHub link mention earlier
I have cut out code that is unnecessary for this problem
class GameScene : SKScene, GameKitHelper, MultiplayerNetworkingProtocol {
override func didMoveToView () {
GCHelper().authenticateLocalUser() //Authenticate GameCenter User
println("\n \n \n Authenticating local user \n \n \n")
}
func startMultiplayer () {
var vc = self.view?.window?.rootViewController
GameKitHelper().findMatchWithMinPlayers(2, maxPlayers: 2, viewController: vc!, delegate: self); //Find match and load GKMatchMakerViewController
}
func matchStarted() {
//Delegate method
println("match started")
}
func matchEnded() {
//Delegate method
println("match ended")
}
func match(match: GKMatch, didReceiveData: NSData, fromPlayer: String){
//Delegate Method
println("Did receive data")
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch in (touches as! Set<UITouch>) {
let location = touch.locationInNode(self)
if self.nodeAtPoint(location) == multiplayer //SKSpriteNode {
//User clicked on multiplayer button, launch multiplayer now!
println("Loading multiplayer")
startMultiplayer()
}
}
Image
UPDATE
I have noticed that when I test using my iPhone and the simulator, on the iPhone the status will go from Ready to Disconnected but on the simulator the status is still Ready and then I will get the following message in the console for the iPhone
Warning matchmakerViewController:didFindMatch: delegate method not implemented`
Even though it is implemented in the GCHelper.swift file. This does not happen when I test on my iPhone and iPad Mini it just keeps on saying Starting Game...
Any help will be appreciated.
Prerequisites
Both players must be in the same environment (Sandbox for testing)
The authenticationChanged in GCHelper.swift must not be private. You may have to remove that keyword.
There are a few delegates involved, and in your example, there are a few competing protocols. My recommendation is to create a new App using minimalistic code to track down the startMultiplayer issue.
Gamekit Multi Player Step by Step Tutorial using GCHelper
Create a new project (Xcode > File > New > Project... > Single View Application > ... > Create) using the very same Product Name & Organization Name as your game, so that it matches both App Bundle Identifier and iTunes Game Center parameters. This will allow you to run tests without overhead.
Use this Podfile:
platform :ios, '8.0'
use_frameworks!
target 'SO-31699439' do
pod 'GCHelper'
end
Use a GCHelperDelegate
Create a UIViewController with just the bare minimum (a Start Multiplayer button), and connect it to this action:
#IBAction func startMultiplayerAction(_ sender: AnyObject) {
GCHelper.sharedInstance.findMatchWithMinPlayers(
2,
maxPlayers: 2,
viewController: self,
delegate: self);
}
Here is the crux: the delegate you pass must adopt GCHelperDelegate. It does not have to be the same class, but in your example above it is, and the present rule was not respected. For this example, ViewController adopts GCHelperDelegate:
import UIKit
import GCHelper
import GameKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
GCHelper.sharedInstance.authenticateLocalUser()
}
}
Implement required GCHelperDelegate methods in an extension
Since ViewController adopts GCHelperDelegate, the three methods below must be in that same class, and will be invoked:
extension ViewController: GCHelperDelegate {
func matchStarted() {
print("matchStarted")
}
func match(_ match: GKMatch, didReceiveData: Data, fromPlayer: String) {
print("match:\(match) didReceiveData: fromPlayer:\(fromPlayer)")
}
func matchEnded() {
print("matchEnded")
}
}
Execution
Tested: built, linked, ran, successful match.
Launch app, tap Start Multiplayer button, tap Play Now on both devices (or iPhone Simulator + real device).
Log:
Authenticating local user...
Authentication changed: player not authenticated
Ready to start match!
Found player: SandboxPlayer
matchStarted
► Find this solution on GitHub and additional details on Swift Recipes.

iAd Banner swift , after i added iAd the game started crash

i developed this game , and it works fine like i want it to do , but after i added the iAd banner , when i start the game it would run normally for like 10 sec. and the it zoom in and make every thing very large and then it would give me this error :
Shapes#2[75422:7643415] [AppDeveloper] ADBannerView: Unhandled error (no delegate or delegate does not implement didFailToReceiveAdWithError:): Error Domain=ADErrorDomain Code=1 "Service session terminated." UserInfo=0x7fdb09f5b1e0 {ADInternalErrorCode=1002, NSLocalizedDescription=Service session terminated.}
You're missing your didFailToReceiveAdWithError function. You can copy and paste this code in, just make sure you iAd banner matches what is in your project:
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
println("Error failed to load. Probably due to network connection.")
self.adBannerView.hidden = true//hide the banner
}
The problem is probably the iAd banner cannot load and you don't have the didFailToReceiveAdWithError function which runs when the banner can't load. If the banner doesn't load, and there's no function to handle this, the compiler will complain.
P.S. You may want to insert this function too. This one is the opposite of didFailToReceiveAdWithError, it runs when the banner can load.
func bannerViewDidLoadAd(banner: ADBannerView!) {
println("Banner did load.")
self.adBannerView.hidden = false//show banner
}
You can find more info about iAd here.

How do you preload banner iAds in Swift?

I just integrated iAds into my app and they work perfectly. The only problem is that there is a delay on the page before the ad shows up. I'd like to preload the ads as soon as the app is launched. I have one medium rectangle ad and one regular banner ad (on different views in the app).
Medium rectangle is loaded on viewDidLoad() of ReadingVC.swift like this:
var rectangleAdView = ADBannerView(adType: ADAdType.MediumRectangle)
// Show banner ad
rectangleAdView?.delegate = self
With the following functions:
func bannerViewDidLoadAd(banner: ADBannerView!) {
println("bannerViewDidLoadAd - Ad shown on app")
self.view.addSubview(banner)
self.view.layoutIfNeeded()
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError
error: NSError!) {
banner.removeFromSuperview()
self.view.layoutIfNeeded()
}
The regular banner is loaded on viewDidLoad() of LibraryVC.swift in the same fashion, just with ADAdType.Banner instead of ADAdType.MediumRectangle
How can this be done?
There will always be a bit of a delay because the application has to grab the ads from the iAd CDN. Now, if you have a view that shows before either ReadingVC and LibraryVC, you can always try to load the ads there beforehand. To do this, you'd probably need to create a separate singleton class to hold all of your iAd code, and then access that class from all of the places you need to display or try to preload an iAd.

ios iAd loading before displaying

I'm working on a iOS game in swift.
I'm trying to add an interstitial ad.
What I would like to do is when the game is over, displaying an Ad.
After closing it, the user can launch another game.
When the game is over I call this method:
func showFullScreenAd() {
if requestingAd == false {
interstitial = ADInterstitialAd()
interstitial!.delegate = self
requestingAd = true
}
}
func interstitialAdDidLoad(interstitialAd: ADInterstitialAd!) {
if interstitial?.loaded==true{
....}
}
The ad will be displayed when interstitialAdDidLoad is called.
So, between showFullScreenAd() and interstitialAdDidLoad some times we may have several seconds (the time for the ad to load) so the user can click on 'new game' and starts the game.
So, the game will begin and then the ad will be displayed (I'm handling the pause mode also) but it's weird to start the game and to have the ad showing up.
I'm thinking about the following case:
doing
interstitial = ADInterstitialAd()
when loading the game
and when the game is over just show the ad (if available), and doing it again after that.
What do you think about this ?
Thanks.
C.C.
You have to add the ad onto the view as a subview right? So load it and add it to the view when you are ready to. I'm assuming that you're doing it before interstitialAdDidLoad at the moment?

Resources