Why does the applicationWillResignActive method not work? - ios

In my GameScene.m I have a method called wentToBackGround. This method is called by applicationWillResignActive in AppDelegate:
GameScene *gameScene = [[GameScene alloc]init];
[gameScene wentToBackground];
In wentToBackGround I move my player sprite (just to test if it works) like so:
-(void)wentToBackground {
NSLog(#"BG");
self.player.position = CGPointMake(CGRectGetMidX(self.frame), 1000);
}
The NSLog works, however the players position remains the same. Is this due to the fact that SpriteKit automatically pauses everything once it enters the BG. How do I work around this. I eventually want there to be a pause menu that opens as soon as the user leaves the app. How do I do this properly?
I think it also might not work, because I made a new instance of the GameScene. How do I use the old instance? (the old instance was created in another scene, the TitleScene)

I think it also might not work, because I made a new instance of the GameScene
Correct, you got it! Well done. Keep in mind (and I think you are now grasping this) that a class is just a template. The objects in your app are instances, and you can make many instances of one class. So when you say
[[GameScene alloc]init]
you are making a new instance. That's legal but pointless; sending it the wentToBackground message does nothing of any use, because it isn't in your interface. The GameScene instance you want to talk to, the one in your interface, is elsewhere.
Getting a reference to a particular existing instance can be tricky. You sometimes have to arrange things in advance to make it possible. However, I think you can avoid the whole problem here. UIApplication has not only an app delegate method but also a notification for letting you know that you will resign active. So just have the GameScene register for that notification, and now you don't have to involve the app delegate at all.
Here's the documentation on that notification:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/#//apple_ref/c/data/UIApplicationWillResignActiveNotification
Any object can register for a notification, so this is a way to establish that your GameScene wants to be informed of deactivation.

Related

Handling cancel in GKMatchmakerviewcontroller

I am making a multiplayer feature to a game I made.
Everything is working, except when I am in matchmaking and both players are connected, if one person hits the "Cancel" button the other device gets no notice of the canceling.
On the other device it the words change to say "Disconnected" however none of the delegate methods are called.
How can I handle this?
You should implement the GKMatchmakerViewControllerDelegate protocol.
Unfortunately, there is not a method (that I know of, or could find with almost 3 months of looking into it) that is called when one person disconnects in matchmaking after they have begun to connect.
Therefore, the way I got around this is once the GameViewController is presented it waits one second and then calls a method to check to see if it is connected to someone else.
To do this I have it so once the game begins each player sends the other player a random number (used to determine non-related settings later on - such as who gets to go first). When it calls the method to check to see if it is connected it just checks to see if the random number has been assigned. If so, then it begins the game as normal, if not, it ends the game and pops back to the menu.

iOs game - lives refill

I'm working on match 3 game in there I need to add lives. If user didn't solve puzzle he loses 1 life. I made it but how I can make lives refill every 20 minutes? I'm stuck. Another on problem is if game moves to background, how to check after user open game again?
My game is Sprite Kit project on objective-c
First part of your question:
You are looking for some timer. You could use NSTimer to call a method every 20m or SKAction with waitForDuration method init.
Second part of your question:
In your AppDelegate find or add method applicationWillEnterForeground:(UIApplication *)application
. This method is called everytime your app should become active. Or addObserver for applicationWillEnterForeground notification where you need it.

iOS Sprite Kit Sprite Nodes don't work unless in initWithSize method

I am making an iOS game using SpriteKit and have found that, for some reason, the sprites only respond to actions sent if the actions are sent within the initWithSize method. This is quite infuriating because I am doing the same things outside of the initWithSize method that I am inside, so it should work. For example, I use [self addChild:playerSprite] within the initWithSize method and it works perfectly. If I use it anywhere else, it does nothing. Same code and everything. I have worked on this issue for hours and cannot find any reason for this. Thanks in advance for any help.

Is there any scenario that can cause ViewDidLoad to be called before didBecomeActive?

I know it's sounds silly but just to clear a point.
Is there any chance that view did load will be called before didBecomeActive ?
Is it totally impossible ?
EDIT
We have a crash that happens when user is coming back to the app from the background and we start to use openGL. The crash error points that we try to use openGL in the background.
It is important to say that our app lives in the background as a VOIP app.
We try to figure out if there is a chance that somehow we are triggering something in the background thats causes the app restart openGl in the background.
In the stack we see:
[VideoCallViewController viewDidLoad] (VideoCallViewController.m:283)
And few lines after that:
[GPUImageContext createContext]
And finally:
gpus_ReturnNotPermittedKillClient + 10
We are trying to figure out if there is a way that [VideoCallViewController viewDidLoad] was called in the background or that we must assume that we are in the foreground, and somehow moving to the background right after the viewDidLoad ?
Second option
The second option is that we are indeed moving to the background right after the viewDidLoad. The point here is that we are listening to AppWillResignActive and we pause the GPUIMage. So we can not understand why do we get the crash ?
Thanks
Thanks
When / Where do you instantiate the various GPUImage objects that you are using? Is it within viewDidLoad or possibly within init:?
It's just pure rampant speculation here since you didn't really post any code...
but if you are disposing of objects when the app heads to the background that are not then re-created when it comes back to the foreground (perhaps because the viewController was retained by a parent, and therefore init: was not called again but viewDidLoad was...) Then you may be trying to send OpenGL messages to objects that don't actually exist anymore.
On the (probably unlikely) chance that my speculation is right, you could easily fix it with the common "getter" pattern of:
- (GPUImageObjectOfInterest*)instanceOfObject {
if (!_classVariableOfThisType) {
_classVariableOfThisType = [[GPUImageObjectOfInterest alloc] init];
// custom configuration, etc...
}
return _classVariableOfThisType;
}
and then use [self instanceOfObject]; wherever you used to use _classVariableOfThisType
It's a low overhead, but reasonably foolproof way of making sure a key object exists under a wide range of app interruption / background & foreground & low memory conditions.
Don't be shy to post too much code though, we can read through an entire class if needed. Some of us like reading code! (and it will really help the quality of response you get...)

how to get hold of object from other classes in appDelegate when app enters background

I got a class which runs a bunch of timers, and when the app enters background I want to stop them. I know of course this is done in the appDelegate but when I got the timer class initialized as an instance variable in another class.. What´s the common ways of getting hold of the instance object in the appDelegate?
Do I delegate the didEnterBackground to the class with the timer i want to stop?
Do I make the timer a singelton?
Use the notification center?
or, hopefully there are better ways than this!
Probably the easiest thing to do here is post a notification when your app delegate gets the "didEnterBackground:" call. And have your timer class (or class that has a bunch of timers) listening for that notification.
You'd need an matching app-delegate-does-a-post method if you want to restart the timers when the app comes back to the fireground.
You're right - the only method you will need is didEnterBackground method in your appDelegate.
Using notification center may cause you a lot of problem (you 100% positive that every time app enter backgound you will have timers fire in your class?). Notification Center in this case can easily cause crash.
Here is what i will do:
Set up my timers in one class (let's call it TimerManager)
Make my class a Singleton class.
In TimerManager i will create array/set with timers.
Call singleton class right after my first ViewControllers will load (or in AppDelegate). Basically right after my app will start.
Add Timers to my Set/Array when i need it.
Create a method stopAllTimers
\
-(void)stopAllTimers {
for(NSTimer *timer in self.allTimers) {
[timer invalidate];
}
}
Call this method in my didEnterBacground : [[TimerManager sharedInstance] stopAllTimers]
That's it and this is perfectly safe.

Resources