So I set up Applovin SDK in my app and Applovin ads only come up sparingly. All of my other apps with Applovin installed have the ads coming up accordingly. Anyone heard of this kind of error?
Here is what I have in the Appdelegate:
[ALSdk initializeSdk];
Chartboost *cb = [Chartboost sharedChartboost];
cb.appId = #"TAKEN OUT";
cb.appSignature = #"TAKEN OUT";
// Required for use of delegate methods. See "Advanced Topics" section below.
cb.delegate = self;
[cb startSession];
[cb cacheMoreApps];
[cb showInterstitial];
//AppLovin Interstitial Ad
if (self.theTimer == nil)
{
self.theTimer = [NSTimer scheduledTimerWithTimeInterval:1000 target:self selector:#selector(countdownTracker) userInfo:nil repeats:YES];//Repeat to yes
}
}
-(void)didCloseInterstitial:(NSString *)location
{
[ALInterstitialAd showOver:self.window];
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:#"preferenceName"];
if ([savedValue isEqualToString:#"yes"]) {
}
NSString *valueToSave = #"yes";
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:#"preferenceName"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)stopTimer
{
if (self.theTimer != nil)
{
[self.theTimer invalidate];
self.theTimer = nil;
}
}
Related
I have successfully removed ads from the app with an in app purchase.
The problem is that if I close the app and reopen. The ads start up again.
I have 2 main scenes. The GameOverScene and the GameScene. The In App Purchase happens in the GameOverScene.
GameOverScene.m :
- (void)OnRemoveADS {
[self showPurchaseAlert: IAP_Q_RemoveADS :0];
g_bRemoveADS = [[NSUserDefaults standardUserDefaults] boolForKey: #"REMOVEADS"];
// For HZInterstitialAd, HZVideoAd, and HZIncentivizedAd, just check the BOOL to see if an ad should be shown
if (!g_bRemoveADS) {
[HZInterstitialAd show];
[self removeBannerAds];
[self disableAds];
NSLog(#"Disable ads is called");
}
}
- (void)removeBannerAds {
HZBannerAdOptions *options = [[HZBannerAdOptions alloc] init];
[HZBannerAd placeBannerInView:self.view
position:HZBannerPositionBottom
options:options
success:^(HZBannerAd *banner) {
if (g_bRemoveADS) { // case (2)
// Just discard the banner
[banner setHidden: YES];
[banner removeFromSuperview];
banner = nil;
//_currentBannerAd = banner;
NSLog(#"Banner ad removed!GameOverScene");
} else {
// Keep a reference to the current banner ad, so we can remove it from screen later if we want to disable ads.
_currentBannerAd = banner;
}
NSLog(#"Ad Shown! GameOverScene");
}
failure:^(NSError *error) {
NSLog(#"Error = %#",error);
}];
}
- (void)disableAds {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"REMOVEADS"];
[_currentBannerAd removeFromSuperview]; // case (3)
}
GameScene.m :
-(id) init {
if (self = [super init]) {
if (!g_bRemoveADS) {
g_bRemoveADS=FALSE;
[[NSUserDefaults standardUserDefaults] setBool:g_bRemoveADS forKey:#"REMOVEADS"];
[[NSUserDefaults standardUserDefaults] synchronize];
} else {
g_bRemoveADS=TRUE;
[[NSUserDefaults standardUserDefaults] setBool:g_bRemoveADS forKey:#"REMOVEADS"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
}
The way I'm trying to solve it is by using the same code from the GameOverScene.m in the AppDelegate.m that way when the app starts up it will remove the ads.
AppDelegate.m :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
g_bRemoveADS = [[NSUserDefaults standardUserDefaults] boolForKey: #"REMOVEADS"];
if (!g_bRemoveADS) {
[HZInterstitialAd show];
[self disableAds];
NSLog(#"Disable ads is called");
}
}
Out of my perspective you have one negation to much.
if (!g_bRemoveADS) { should be replaced with if (g_bRemoveADS) { in GameOverScene.m.
if (g_bRemoveADS) {
[HZInterstitialAd show];
[self removeBannerAds];
[self disableAds];
NSLog(#"Disable ads is called");
}
g_bRemoveADS evaluates to TRUE when the respective user-default is set. When it is set, then you call the removeBannerAds stuff etc. which seems to be the deactivation action.
You have to synchronise your NSUserDefaults after changing changing a value in your disableAds method with:
[[NSUserDefaults standardUserDefaults]synchronize];
I implemented the AdMob Interstitial ad in my project and it works well. Now I want the AdMob Interstitial ad to only appear for every fifth game and not after every single game. Can someone help me?
Here is my code for the Admob in my GameViewController:
- (void)viewDidLoad {
[super viewDidLoad];
//addInterstitial
self.interstitial = [[GADInterstitial alloc] initWithAdUnitID:#"ca-app-pub-XXXXXXXXXX/XXXXXXXXXX"];
GADRequest *request = [GADRequest request];
request.testDevices = #[#"XXXXXXXXXXXXXXXXXXXXXXXXXX"];
[self.interstitial loadRequest:request];
[[NSNotificationCenter defaultCenter]addObserver:self
selector:#selector(handleNotification:) name:#"showAd" object:nil]; }
- (void)handleNotification:(NSNotification *)notification
{
if ([notification.name isEqualToString:#"showAd"]) {
if ([self.interstitial isReady]) {
[self.interstitial presentFromRootViewController:self]; }
UPDATE:
I have this code in the GameViewController:
- (void)viewDidLoad {
[super viewDidLoad];
//addInterstitial
if ([[NSUserDefaults standardUserDefaults] objectForKey:GAME_AMOUNT_KEY] == nil){
NSNumber *number = [NSNumber numberWithInt:0];
[[NSUserDefaults standardUserDefaults] setObject: number forKey: GAME_AMOUNT_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
}
if ([[[NSUserDefaults standardUserDefaults] objectForKey:GAME_AMOUNT_KEY] intValue] >= 5){
[self callAd];
self.interstitial = [self createAndLoadInterstitial];
NSNumber *number = [NSNumber numberWithInt:0];
[[NSUserDefaults standardUserDefaults] setObject: number forKey: GAME_AMOUNT_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)handleNotification:(NSNotification *)notification {
if ([notification.name isEqualToString:#"showAd"]) {
if ([self.interstitial isReady]) {
[self.interstitial presentFromRootViewController:self];
}
}
}
- (void) callAd{
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(handleNotification:) name:#"showAd" object:nil];
}
- (GADInterstitial *)createAndLoadInterstitial {
self.interstitial = [[GADInterstitial alloc] initWithAdUnitID:MyAdUnitID2];
self.interstitial.delegate = self;
GADRequest *request2 = [GADRequest request];
request2.testDevices = #[#"XXXXXXXXXXXXXXXXXXXXXX"];
[self.interstitial loadRequest:request2];
return self.interstitial;
}
- (void)interstitialDidDismissScreen:(GADInterstitial *)interstitial {
self.interstitial = [self createAndLoadInterstitial];
}
And in the GameScene.m this code:
- (void)showGameOver{
//addInterstitial
int score = [[[NSUserDefaults standardUserDefaults] objectForKey:GAME_AMOUNT_KEY] intValue]+1;
NSNumber *newNumber = [NSNumber numberWithInt:score];
[[NSUserDefaults standardUserDefaults] setObject:newNumber forKey:GAME_AMOUNT_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName:#"showAd" object:nil];
Use NSUserDefaults:
- (void) callAd
{
// Code to call your ad here
}
- (void) viewDidLoad
{
// If you haven't played yet, sets to 0
if ([[NSUserdefaults standardUserDefaults] objectForKey:GAME_AMOUNT_KEY] == nil){
NSNumber *num = [NSNumber numberWithInt:0];
[[NSUserDefaults standardUserDefaults] setObject: num forKey: GAME_AMOUNT_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
}
// If you have played
if ([[[NSUserdefaults standardUserDefaults] objectForKey:GAME_AMOUNT_KEY] intValue] >= 5){
[self callAd]; // ad is called
NSNumber *num = [NSNumber numberWithInt:0];
[[NSUserDefaults standardUserDefaults] setObject: num forKey: GAME_AMOUNT_KEY];
[[NSUserDefaults standardUserDefaults] synchronize]; // resets to zero
}
}
And whenever a game is over:
int score = [[[NSUserdefaults standardUserDefaults] objectForKey:GAME_AMOUNT_KEY] intValue]
+ 1;
NSNumber *newNumber = [NSNumber numberWithInt:score];
[[NSUserDefaults standardUserDefaults] setObject:newNumber forKey: GAME_AMOUNT_KEY];
[[NSUserDefaults standardUserDefaults] synchronize]; // Sets to new value
The key can be anything really. At the top of your .m file put:
#define GAME_AMOUNT_KEY #"Game Amount Key"
UPDATE
Change:
- (void)handleNotification:(NSNotification *)notification
{
if ([notification.name isEqualToString:#"showAd"]) {
if ([self.interstitial isReady]) {
[self.interstitial presentFromRootViewController:self];
}
To:
- (void)handleNotification:(NSNotification *)notification
{
if ([notification.name isEqualToString:#"showAd"]) {
if ([self.interstitial isReady]) {
if ([[[NSUserDefaults standardUserDefaults] objectForKey:GAME_AMOUNT_KEY] intValue] >= 5){
[self.interstitial presentFromRootViewController:self];
NSNumber *number = [NSNumber numberWithInt:0];
[[NSUserDefaults standardUserDefaults] setObject: number forKey: GAME_AMOUNT_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
And change (in ViewDidLoad):
if ([[[NSUserDefaults standardUserDefaults] objectForKey:GAME_AMOUNT_KEY] intValue] >= 5){
[self callAd];
self.interstitial = [self createAndLoadInterstitial];
NSNumber *number = [NSNumber numberWithInt:0];
[[NSUserDefaults standardUserDefaults] setObject: number forKey: GAME_AMOUNT_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
}
To
[self callAd];
self.interstitial = [self createAndLoadInterstitial];
I wish to make an app that, when the user opens it for the first time he selects his country from a picker in order to make his flag appear on the main screen. If the user closes the app and opens it again I want the app to start the menu screen with his flag on it directly.
I am using the following code now but it doesn't work at all. Every time the app is opened it takes him to the picker VIew (TappViewController)
- (void)viewDidLoad
{
[super viewDidLoad];
if (![[NSUserDefaults standardUserDefaults] boolForKey:#"FirstLaunch"]) {
secViewController *menu = [[secViewController alloc] init];
[self presentViewController:menu animated:YES completion:^{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"FirstLaunch"];
[[NSUserDefaults standardUserDefaults] synchronize];}];
}
else{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"FirstLaunch"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Change your code like this:
- (void)viewDidLoad
{
[super viewDidLoad];
if (![[NSUserDefaults standardUserDefaults] boolForKey:#"isPickerOpened"]) {
secViewController *menu = [[secViewController alloc] init];
[self presentViewController:menu animated:YES completion:^{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"isPickerOpened"];
[[NSUserDefaults standardUserDefaults] synchronize];
}];
}
}
I have a two buttons. One that shows when the sound is playing and one when the sound isn't playing. However, when I switch it off and switch view controllers. And i come back to the main menu view controller the sound is back on. I want to keep the sound on or off based on the user setting.
(IBAction)pauseSound
{
BOOL shouldPlaySound = YES;
[[NSUserDefaults standardUserDefaults] setBool:shouldPlaySound forKey:#"shouldPlaySound"];
if (![sound isPlaying]) {
[sound play];
[soundButton setBackgroundImage:[UIImage imageNamed:#"SoundOn.png"] forState:UIControlStateNormal];
}else {
[sound pause];
[soundButton setBackgroundImage:[UIImage imageNamed:#"SoundOff.png"] forState:UIControlStateNormal];
}
[[NSUserDefaults standardUserDefaults] synchronize];
}
A good way to do this is saving wether or not to play the Sound in the NSUserDefaults, so the setting is remembered by your app. Set it i.e. via
BOOL shouldMuteSound = ...//set it corresponding to your button presses/visibility
[[NSUserDefaults standardUserDefaults] setBool:shouldMuteSound forKey:#"shouldMuteSound"];
//call this to immediatly update the userDefaults
[[NSUserDefaults standardUserDefaults] synchronize];
And load it via
BOOL shouldMuteSound = [[NSUserDefaults standardUserDefaults] boolForKey:#"shouldMuteSound"];
I didn't get it at first that the buttons are inside the same viewController that plays the sound. That code should help you:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
BOOL shouldMuteSound = [[NSUserDefaults standardUserDefaults] boolForKey:#"shouldMuteSound"];
if(!shouldMuteSound){
[self playSound];
}else{
[self stopSound];
}
}
- (void)playSound{
if(!sound){
NSString *path = [[NSBundle mainBundle] pathForResource:#"Main Menu" ofType:#"mp3"];
sound = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
sound.numberOfLoops = -1;
}
if (![sound isPlaying]){
[sound play];
}
[soundButton setBackgroundImage:[UIImage imageNamed:#"SoundOn.png"] forState:UIControlStateNormal];
}
- (void)stopSound{
[sound pause];
[soundButton setBackgroundImage:[UIImage imageNamed:#"SoundOff.png"] forState:UIControlStateNormal];
}
- (IBAction)soundButtonTapped{
BOOL shouldMuteSound = [[NSUserDefaults standardUserDefaults] boolForKey:#"shouldMuteSound"];
shouldMuteSound = !shouldMuteSound;
[[NSUserDefaults standardUserDefaults] setBool:shouldMuteSound forKey:#"shouldMuteSound"];
[[NSUserDefaults standardUserDefaults] synchronize];
if(shouldMuteSound){
[self stopSound];
}else{
[self playSound];
}
}
I have at timeout feature where if the app is idle (in background) for a period of time, I timeout my app and send the user to the login screen. I set the "timedOut" key in user defaults to YES in my application delegate, then reference that key in each view controller, where if it is YES, I segue to the login screen. On the login screen I have a label that displays "Session has timed out" if the "timedOut" is YES. My issue is that if I login, then logout very quickly, the label is displayed, even though I explicitly set that key to NO right after I show the label and then synchronize the user defaults. If I wait a second or two and logout, the label is hidden like it should be. I have solved the "problem", but would like to understand the behavior.
Code from view did load in my login view controller. You would think this changes the isTimedOut to NO, but when I do a quick logout viewdidload is called again, but isTimedOut is YES.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
sessionLabel.hidden = YES;
isTimedOut = [defaults boolForKey:#"isTimedOut"];
if (isTimedOut == YES)
{
sessionLabel.hidden = NO;
defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:NO forKey:#"isTimedOut"];
isTimedOut = NO;
NSLog(#"Timed Out has been reset to %s",[defaults boolForKey:#"isTimedOut"] ? "YES" : "NO");
[defaults synchronize];
}
UPDATE
I replaced the code above using a property in my app delegate instead of NSUserDefaults and the "strange" behavior went away.
eONavAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
isTimedOut = appDelegate.isTimedOut;
sessionLabel.hidden = YES;
//isTimedOut = [defaults boolForKey:#"isTimedOut"];
NSLog(#"Timed Out has been reset to %s",appDelegate.isTimedOut ? "YES" : "NO");
if (isTimedOut == YES)
{
appDelegate.isTimedOut = NO;
sessionLabel.hidden = NO;
}
MORE CODE
To logout, I have UIButtonBarItem calling a segue programmatically. The doLogout property tells the login view controller to run a logout API.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"logoutSegue"])
{
// Get reference to the destination view controller
eoLoginViewController *vc = [segue destinationViewController];
vc.doLogout = YES;
}
}
isTimedOut is set in one location in the app delegate.
-(void)timeoutWithDate:(NSDate *)currentDate
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDate *previousDate = [defaults objectForKey:#"enteredBackground"];
NSTimeInterval distanceBetweenDates = [currentDate timeIntervalSinceDate:previousDate];//TimeInterval is in seconds
NSLog(#"Time between dates in seconds %f",distanceBetweenDates);
double minutesInAnHour = 60;
double minutesBetweenDates = distanceBetweenDates / minutesInAnHour;
NSLog(#"minutesBetweenDates %f",minutesBetweenDates);
if(minutesBetweenDates > 60)
{
isTimedOut = YES;
}
else
{
isTimedOut = NO;
}
}
Use this:
To save a Bool:
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"isTimedOut"];
To Load a Bool:
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"isTimedOut"] == YES) {
//it equals yes
}
else {
//it equals no
}
why don't you try something like this? I didn't see your full project but it should work like a charm.
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
then...
- (void)applicationWillResignActive:(UIApplication *)application
{
[[NSUserDefaults standardUserDefaults] setValue:[NSDate date] forKey:#"sleepTime"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
and...
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSInteger _timeoutInSeconds = 300;
NSDate *_sleepTime = [[NSUserDefaults standardUserDefaults] valueForKey:#"sleepTime"];
if (_sleepTime) {
NSCalendar *_calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *_dateComponents = [_calendar components:NSSecondCalendarUnit fromDate:_sleepTime toDate:[NSDate date] options:0];
if (_dateComponents.second > _timeoutInSeconds) {
// expired session
} else {
// valid session
}
}
}