I keep getting an error within this section of code:
// Interstitial iAd
-(void)showFullScreenAd {
// Check if already requesting ad
if (requestingAd == NO) {
interstitial = [[ADInterstitialAd alloc] init];
interstitial.delegate = self;
self.interstitialPresentationPolicy = ADInterstitialPresentationPolicyManual;
[self requestInterstitialAdPresentation];
NSLog(#"interstitialAdREQUEST");
requestingAd = YES;
}
}
-(void)interstitialAd:(ADInterstitialAd *)interstitialAd didFailWithError:(NSError *)error {
interstitial = nil;
requestingAd = NO;
NSLog(#"interstitialAd didFailWithERROR");
NSLog(#"%#", error);
}
-(void)interstitialAdDidLoad:(ADInterstitialAd *)interstitialAd {
NSLog(#"interstitialAdDidLOAD");
if (interstitialAd != nil && interstitial != nil && requestingAd == YES) {
//[interstitial presentFromViewController:self];
//[interstitial presentInView:self.view] // I get an error on this line
NSLog(#"interstitialAdDidPRESENT");
if (interstitial.loaded) {
[self requestInterstitialAdPresentation]; //I also get an error on this line too
}
}
}
-(void)interstitialAdDidUnload:(ADInterstitialAd *)interstitialAd {
interstitial = nil;
requestingAd = NO;
NSLog(#"interstitialAdDidUNLOAD");
}
-(void)interstitialAdActionDidFinish:(ADInterstitialAd *)interstitialAd {
interstitial = nil;
requestingAd = NO;
NSLog(#"interstitialAdDidFINISH");
}
Its something to do with this particular line:
[self requestInterstitialAdPresentation];
This is the error I'm getting and I have no idea what this line needs changing to so that the error stops:
-[UIView setShowsFPS:]: unrecognized selector sent to instance 0x146e241a0
Ive gotten this error in the past when working with the same sort of code, it usually appears when I start trying to implement interstitial ads. I seem to be having a lot of trouble trying to implement interstitial ads and I have read a lot of tutorials. I have no idea what I'm doing wrong :( can someone please help?
Regards,
Ryan
setShowsFPS: is a method on SKView, but not on UIView.
Although I don't see the cause in the code you posted, the error means that a UIView instance is being passed to a method that expects an SKView. Set an exception breakpoint to try to figure out where. It's possible that it isn't your code that's triggering the call.
Related
I am trying to add admob interstitial ads to my app but when I run my app no ad shows up. I just get a message in the logs saying :
<Google> To get test ads on this device, call: request.testDevices = #[ #« deviceID » ];
I'm pretty sure it knows im trying to show an add because of a previous error but it just won't appear.
here is my code( I added a print statement to the first part but it doesn't seem to take it into considiration ):
if interstitialad != nil {
if interstitialad!.isReady {
interstitialad?.present(fromRootViewController: self)
}
}
here is the second part of the code ( note both are in ViewDidLoad )
if interstitialad != nil {
if interstitialad!.isReady {
interstitialad?.present(fromRootViewController: self)
}
}
func createAndLoadInterstitial() -> GADInterstitial {
let request = GADRequest()
let interstitial = GADInterstitial(adUnitID: "unit id")
//request.testDevices = ["iPhone test device ID"]
//request.testDevices = ["simulator ID"]
interstitial.delegate = self
interstitial.load(request)
return interstitial
}
interstitialad = createAndLoadInterstitial()
What is wrong with this?
Thanks !
Google Ad Interstitial Objective C Working code:
- (void)startAdInterstial
{
self.interstitial = [[GADInterstitial alloc] initWithAdUnitID:FIREBASE_ADMOBID];;
GADRequest *request = [GADRequest request];
request.testDevices = #[kGADSimulatorID,#"7b5e0f6aad46c15f1e9ef2e6d3d381b7"];
_interstitial.delegate = self;
[self.interstitial loadRequest:request];
}
#pragma mark - interstitial delegate
- (void)interstitialDidReceiveAd:(GADInterstitial *)ad
{
[_interstitial presentFromRootViewController:[APPDELEGATE window].rootViewController];
}
- (void)interstitial:(GADInterstitial *)ad didFailToReceiveAdWithError:(GADRequestError *)error
{
NSLog(#"error during full screen view %#",error);
}
- (void)interstitialDidDismissScreen:(GADInterstitial *)interstitial {
}
Hope this will help you out in some other way.
Here are some code which I used to initiate the AdMob in Objective-c:
AdMobHandler.m file:
//created 320x60 banner and displayed at the bottom of UIView.
//If your app in development stage then you need to add the device ID or simulator ID which will appear during AdMob Initiation.
To get test ads on this device, call: request.testDevices = #[ #"xxxxxxxxxxxxxxxxxxxxxxxxxx" ];
- (void)initiateAndLoadAdMob:(UIViewController *)sender
{
GADRequest *request = [GADRequest request];
GADBannerView *bannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];
request.testDevices = #[ #"xxxxxxxxxxxxxxxxxxxxxxxxxx <<Device ID>>",#"xxxxxxx<<Simulator ID>>" ];
bannerView.adUnitID = FIREBASE_ADMOBID;
bannerView.rootViewController = (id)self;
bannerView.delegate = (id<GADBannerViewDelegate>)self;
senderView = sender.view;
bannerView.frame = CGRectMake(0, senderView.frame.size.height - bannerHeight, senderView.frame.size.width, bannerHeight);
[senderView addSubview:bannerView];
}
If you able to understand and change code to Swift will gives you some idea and solve your above issue. Let me know if you have any queries for above code.
For more details check this below link:
https://firebase.google.com/docs/admob/ios/interstitial
You said you're trying to present your GADInterstitial in your viewDidLoad. This is not when you should be presenting your GADInterstitial. You need to give the GADInterstitial time to load the ad. Presenting an ad in your viewDidLoad is also against the AdMob TOS. You should be presenting the GADInterstitial during a transition/action in your application. You should also implement the GADInterstitial delegate methods so you know why the ad is failing to load, when it has actually loaded, and when the user has dismissed the ad so you can continue to transition them in your application.
Disallowed interstitial implementations
GADInterstitial Ad Events
I want to show an Interstitial Ad (from iAd framework) imediately after performing a segue between viewControllers in the storyboard.
I tried to launch [interstitial presentInView:view] (as stated in Apple Documentation) but the ad is not showing.
Any help?
Finally, I managed to solve my doubt.
- (void) showFullScreenAd {
if (requestingAd == NO) {
interstitial = [[ADInterstitialAd alloc] init];
interstitial.delegate = self;
self.interstitialPresentationPolicy = ADInterstitialPresentationPolicyManual;
[self requestInterstitialAdPresentation];
NSLog(#"interstitialAdREQUEST");
requestingAd = YES;
}
}
-(void) interstitialAdDidLoad:(ADInterstitialAd *)interstitialAd{
NSLog(#"interstitialAd DidLOAD");
if (interstitialAd != nil && interstitial != nil && requestingAd == YES) {
NSLog(#"interstitialDidPRESENT");
[interstitial presentFromViewController:self];
}
}
I'm preparing to launch my first app and want to have multiple leaderboards inside my game. Currently in sandbox mode I can track and log scores into Game Center successfully. Game Center saves my scores (only if it is higher) and seems to be fully functional.
I know through Itunes Connect we have the ability to set up multiple leaderboards and it seems pretty straight forward. I still want to be able to test multiple leaderboards before publishing my game though. Is there a way to do this in sandbox mode? Currently it seems like my scores are only automatically logged into a default leaderboard. Below is the relevant code I'm using to save/access scores. Thanks!
ABGameKitHelper.m
#pragma mark - Leaderboard
-(void) reportScore:(long long)aScore forLeaderboard:(NSString*)leaderboardId
{
GKScore *score = [[GKScore alloc] initWithCategory:leaderboardId];
score.value = aScore;
[score reportScoreWithCompletionHandler:^(NSError *error) {
if (!error)
{
if(![self hasConnectivity])
{
[self cacheScore:score];
}
if (ABGAMEKITHELPER_LOGGING) NSLog(#"ABGameKitHelper: Reported score (%lli) to %# successfully.", score.value, leaderboardId);
}
else
{
[self cacheScore:score];
if (ABGAMEKITHELPER_LOGGING) NSLog(#"ABGameKitHelper: ERROR -> Reporting score (%lli) to %# failed, caching...", score.value, leaderboardId);
}
}];
}
-(void) showLeaderboard:(NSString*)leaderboardId
{
GKLeaderboardViewController *viewController = [GKLeaderboardViewController new];
viewController.leaderboardDelegate = self;
if (leaderboardId)
{
viewController.category = leaderboardId;
CCLOG(#"Going to category already created");
}
[[self topViewController] presentViewController:viewController animated:YES completion:nil];
}
MainScene.m
- (void)gameCenter {
[[ABGameKitHelper sharedHelper] reportScore:1400 forLeaderboard:#"Score"];
[[ABGameKitHelper sharedHelper] showLeaderboard:#"Score"];
}
I'm not sure if I understand your question properly, but I'll try to answer! Game Center does support multiple leaderboards:
-If you want to send a score to specific leaderboard, you just have to call the function [[ABGameKitHelper sharedHelper] reportScore:X forLeaderboard:LEADERBOARD_ID];, where X represents the score you'd like to send, and LEADERBOARD_ID is the ID of the leaderboard you want to send the score to, as specified in iTunes Connect.
-When you have multiple leaderboards, if you don't want to show just one leaderboard, but a list of them all, you should use the GKGameCenterViewController class instead. However, be careful; this ViewController has been added in iOS 6 only, so you must check which version the device is running. I am also using the ABGameKitHelper, so I've made a function to show this kind of view. Here it goes :
ABGameKitHelper.m
- (void) showGameCenter{
if (![[ABGameKitHelper sharedHelper] hasConnectivity]) return;
//Check if device runs on iOS 5
if([[[UIDevice currentDevice]systemVersion]intValue]==5)
{
//If so, we must use the GKLeaderboardViewController
GKLeaderboardViewController *leaderboard = [[GKLeaderboardViewController alloc] init];
if (leaderboard != nil)
{
leaderboard.leaderboardDelegate = self;
[[self topViewController] presentViewController:leaderboard animated:YES completion:nil];
}
}else if ([[[UIDevice currentDevice]systemVersion]intValue]>=6)
{
//if it runs on iOS 6 or higher, we use GKGameCenterViewController
GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController alloc] init];
if (gameCenterController != nil)
{
gameCenterController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateDefault;
[[self topViewController] presentViewController:gameCenterController animated:YES completion:nil];
}
}
}
And don't forget to add :
- (void) gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController{
[gameCenterViewController dismissViewControllerAnimated:YES completion:nil];
}
Using this function will allow you to show a nice view containing all your leaderboards and achievements.
Hope this helps!
Here is my problem.
Also please not that I am aware of AdWhirl but choose not to use it because I prefer to have control over what is happening with my ads.
Basically I have iAds and AdMob. I start out always with iAds and if the ads have nothing to show I initialize AdMob and start showing it. Then when iAds finally gets something to show I hide Admob ads and destroy the view and display the iAds again.
This seems to work for 1 iteration meaning :
initialize iAds
iAds have no content to show
hide iAds
initialize Admob
Admob displays ads
iAds have received content so we should display it!
hide Admob
release the Admob view object
The problem is.. over time if I leave the app running and iAd fails to load ads a few times (meaning I do a bit of switching which results in creating Admob views) the released Admob view object is not being released and keeps receiving new ads even though it shouldn't.
Here is the code that I run whenever I receive a code 3 from iAds (meaning :The operation couldn’t be completed. Ad inventory unavailable)
-(void) smartInitialize:(UIViewController*) theVC
{
NSLog(#"AMOB :: smartInitialize");
if(!initialized)
{
NSLog(#"AMOB :: PRE initialization");
CGRect appFrame = [UIScreen mainScreen].applicationFrame;
UIView * theView = [[UIView alloc] initWithFrame:appFrame];
theView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
theViewController = theVC;
//[theViewController retain];
self.view = theView;
[theView release];
adMobAd = nil;
adMobAd = [self requestNewAdmobView];
if(adMobAd != nil)
{
NSLog(#"AMOB :: adding ADMOBVIEW TO VIEW CONTROLLER!");
[theVC.view addSubview:adMobAd];
[adMobAd release];
}
initialized = YES;
}
else
{
NSLog(#"AMOB :: POST initialization");
if(adMobAd!=nil)
{
NSLog(#"AMOB :: adMobView is present, doing nothing...");
}
else
{
NSLog(#"AMOB :: reinitializing..");
[self reinitializeAdmob];
}
}
}
Here is the [self requestNewAdmobView] function :
- (GADBannerView*) requestNewAdmobView
{
NSLog(#"AMOB :: requestNewAdmobView");
CGRect adFrame = CGRectZero;
NSString * appID = nil;
adMobAd = nil;
if(DEVICE_IPAD)
{
adFrame.size = GAD_SIZE_728x90;
appID = #"id1";
}
else
{
adFrame.size = GAD_SIZE_320x50;
appID = #"id2";
}
GADBannerView * tmp = nil;
tmp = [[GADBannerView alloc] initWithFrame:adFrame];
if(tmp != nil)
{
NSLog(#"AMOB :: adMobAD != nil , commencing with other stuff!");
tmp.adUnitID = appID;
tmp.rootViewController = gD.viewController;
tmp.delegate = self;
[tmp loadRequest:[GADRequest request]];
[tmp setHidden:NO];
}
else
{
NSLog(#"AMOB :: adMobAD == nil , THIS IS BAD..");
}
return tmp;
}
Here is the [self reinitializeAdmob] function :
-(void) reinitializeAdmob
{
NSLog(#"AMOB :: reinitializeAdmob");
if(theViewController != nil)
{
[self shutdownAdmob];
adMobAd = nil;
adMobAd = [self requestNewAdmobView];
if(adMobAd!=nil)
{
[theViewController.view addSubview:adMobAd];
}
}
}
And finally the [self shutdownAdmob]
-(void) shutdownAdmob
{
NSLog(#"AMOB :: shutdownAdmob");
if(adMobAd!=nil)
{
NSLog(#"AMOB :: adMobAd != nil, removing from superview and nilling...");
adMobAd.delegate = nil;
[adMobAd removeFromSuperview];
//[adMobAd release];
adMobAd = nil;
}
else
{
NSLog(#"AMOB :: adMobAd == nil");
}
}
Now from what I understand I am cleaning the GADBannerView called AdMobView correctly because :
at first it is == nil
then in [self requestNewAdmobView] i am allocing an instance so retain count = 1
I am returning it and then adding it to the viewControllers view and the view retains it so that makes the retain count go up to 2
I am then releasing the adMobView so I no longer own it and the retain drops down to 1
then when I want to get rid of the object completely in [self shutdownAdmob] i use the removeFromSupreview function which releases the view from the controller and thus it should dealloc it (I even tested this by subclassing the GADViewController and doing an NSLog upon deallocation and it does indeed dealloc).
Phew.. That's a lot of text sorry for that. So the question is :
why does the admobview remove itself correctly the 1st time but durring the 2nd time it does not.?
You must release the adMobAd in shutdownAdMob.
The removeFromSuperview decreases the reference count of the adMobAd, but
the count was incremented with addSubView, so you must release it.
I've had the same problem. I solved it by selecting this check
I'm trying to use game center : multi player
Till now, players are Authenticating to Game center, they can send/read scores, and acheivements.
For multiplayer features, I tried both methods :
- using Game center interface to find a match.
- Find a Match Programmatically.
For both ways I have the following issue: the match delegate’s match:player:didChangeState: method is not called.
In apple docs, it's stated that this delegate is called if one player is connected or disconnected.
In my case this delegate is never called. I think that I'm missing a step.
here after the implementation of my delegate (as specified in apple doc).
- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state
{
switch (state)
{
case GKPlayerStateConnected:
// handle a new player connection.
break;
case GKPlayerStateDisconnected:
// a player just disconnected.
break;
}
if (!self.matchStarted && match.expectedPlayerCount == 0)
{
self.matchStarted = YES;
// handle initial match negotiation.
}
}
and also the code to find a match.
-(void) findProgrammaticMatch
{
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
request.minPlayers = 2;
request.maxPlayers = 2;
[[GKMatchmaker sharedMatchmaker] findMatchForRequest:request
withCompletionHandler:^(GKMatch *FoundMatch, NSError *error)
{
if (error)
{
// Process the error.
StatusLabel.text = #"Match Not Found";
}
else if (FoundMatch != nil)
{
MultiPlayerMatch = FoundMatch; // Use a retaining property to retain the match.
StatusLabel.text = #"Match Found";
MultiPlayerMatch.delegate = self; // start!
// Start the match.
// Start the game using the match.
[self StartMatch];
}
}];
}
Thanks for your help.
It was working all along. The only difference is that... when you use invites the event "didChangeState" doesn't get called. You're connected without notice and you can start to receive data. I never tried to send/receive data because I was expecting the event first, but i did send something by mistake one time, and it worked.
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *) match {
//Dismiss window
[self dismissModalViewControllerAnimated:YES];
//Retain match
self.myMatch = match;
//Delegate
myMatch.delegate = self;
//Flag
matchStarted = TRUE;
//Other stuff
}
- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state {
//This code gets called only on auto-match
}
The above code works as expected.
I think didChangeState: GKPlayerStateConnected may only happen if a player was GKPlayerStateUnknown and then comes back, or if they are added/invited back to a match in progress.