iPhone suspend/resume

Previous topic - Next topic

bigtunacan

My game works fine on the iPhone the first time it is opened, but then if you close and reopen the app will crash every time.

The first line in my game is

Code (glbasic) Select

AUTOPAUSE TRUE
 

I then have my GLB_ON_RESUME sub set a game state.
Code (glbasic) Select

SUB GLB_ON_RESUME:
STATE=ST_RESUME
ENDSUB


If this were getting called then my game should go back to the main menu on resume, but instead it just immediately quits.

Wampus

Hmm. I've been seeing a problem on iOS where running my apps sometimes causes immediate crashes too. I set AUTOPAUSE TRUE and GLB_ON_RESUME in my code.

The crash doesn't always happen but it does happen enough to be annoying. If the app is then re-opened it will work as normal.

I've seen the same behaviour on an iPod Touch 3rd gen with iOS 5 and several iPhone 4 devices. I haven't found a way that it will crash every time but if I go into iOS settings, look at the General page, then go back to my app, it will usually crash.

The same code version never causes this particular problem for PC or Android.

bigtunacan

That sounds the same as what is happening to me.

It seems like the GLB_ON_RESUME is not getting called.

bigtunacan

So I plugged in a STDOUT on my GLB_ON_PAUSE and GLB_ON_RESUME subs to see if they were being reached.  The output from XCode is below.  They are being entered, but for some reason the app crashes on resume. So my app is crashing EVERYTIME it resumes; this is consistent.  When the app is fresh started it never crashes; EVERY TIME it resumes it crashes.

Code (glbasic) Select

-applicationWillResignActive   -> pause
PAUSE
-applicationDidEnterBackground -> pause
quit
Shut down GLB
-applicationWillEnterForeground-> do nothing
-applicationDidBecomeActive    -> unpause
resume
glb is shut down
exit
Program ended with exit code: 0

bigtunacan

I am extremely concerned about this.  I added in a bunch of STDOUT statements to try and track where this was failing; thought maybe it was an issue with my app, but it isn't even crashing at the same point every time. 

My on resume sub looks like follows.

Code (glbasic) Select

SUB GLB_ON_RESUME:
STDOUT "resume \n"
STATE=ST_FOCAL_RESUME
STDOUT "resume state set\n"
ENDSUB


STATE is a GLOBAL variable I use to route what type of action is happening.  Sometimes the app will crash before it even sets this STATE variable.  Other times it will run through the subsequent 2 or 3 subs/functions before it fails, sometimes it will only run another 2 lines before it fails.  What the heck?  Then I search the forums here and I see that people seem to be having the same type of issue with this for over a year now; but no clear solution has yet been posted.

bigtunacan

There are about a DOZEN questions on this forum related to this; none of them clearly answer what is going on.  Some of the topics you can't even tell if there is a solution.  I was able to get this working now, but I really think for the sake of others this should be added to the GLBasic manual in an iPhone section so that people can find this info more easily; it is a hugely frustrating problem.

For anyone that is searching and comes on this thread; I've included some code snippets of what I ended up with...

At the beginning of my app I set AUTOPAUSE TRUE and ALLOWESCAPE FALSE.
I'm not sure if AUTOPAUSE TRUE is needed, because I'm unsure of it's default value; but it certainly won't hurt.
By default ALLOWESCAPE is set to TRUE, so this is definitely needed, without that line your app will crash for sure. 
Additionally; Apple does not allow for you to draw to buffers when your app is in the background; if you do it's possible you'll get through the approval process anyway... e.g. you may not get caught... but then again you may be rejected...

I have my main loop use a SELECT statement to act as a state machine; I have a bunch of constants defined and I only do the showscreen operation for states where my app has focus.
My resume, pause, quit SUBs only set state; which will cause another sub to get called that will either save off game data or reload data in if needed.  Pause and quit should both write everything needed to restore out to files; this is because in multitasking if your app is switched out it will cause the pause sub, but then later iOS may pkill your app and this will NOT call your quit sub. 

I hope this helps someone else...

Code (glbasic) Select

AUTOPAUSE TRUE
ALLOWESCAPE FALSE

SUB GLB_ON_RESUME:
STATE=ST_FOCAL_RESUME
ENDSUB

SUB GLB_ON_PAUSE:
STATE=ST_FOCAL_PAUSE
ENDSUB

SUB GLB_ON_QUIT:
STATE=ST_FOCAL_QUIT
ENDSUB

WHILE RUNNING
SELECT STATE
CASE ST_MENU_MAIN
GOSUB update_menu_main
CASE ST_PLAY
GOSUB update_play
CASE ST_FOCAL_RESUME
GOSUB focal_resume_game
CASE ST_FOCAL_PAUSE
GOSUB focal_pause_game
CASE ST_FOCAL_QUIT
GOSUB focal_quit_game
ENDSELECT
IF STATE<ST_FOCAL_PAUSE THEN SHOWSCREEN
WEND


spacefractal

#6
On windows, they does nothing at all, which They should when minimize window. I think getting message is the way using inline, but still not sure yet.

There was some crash and/or missing graphics issues here too on iOS, but got managed to fix them, so it's does work.

I use auto pause on and allow escape off (because I want to control escape by manual).

I do still use showscreen, but do not draw anything. I think I did that to prevent hanging (meant seen that on android, not sure) and then crash.
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

BigAnd

I have no problem with this on my iPhone but when my app loses focus all the main loop does is call the HIBERNATE function. Not sure you should be doing anything more than this.

I use the same as spacefractal and bigtunacan as in:
ALLOWESCAPE FALSE
AUTOPAUSE TRUE

spacefractal

I do more guess it have been hanging, due no response from ios due missing showscreen (which also response to os using it, even it's might not show graphics)?
Genius.Greedy Mouse - Karma Miwa - Spot Race - CatchOut - PowerUp Elevation - The beagle Jam - Cave Heroes 2023 - https://spacefractal.itch.io/

Wampus

bigtunacan, I think I get what you are saying about pause and resume. Thankyou for looking into this. Its very important to get right. There is one query I have though. I don't think STATE=ST_FOCAL_QUIT is needed in your source code. This is a summary of what I think I understand:-

Assuming ALLOWESCAPE FALSE and AUTOPAUSE TRUE are set

* GLB_ON_QUIT is called when the home button is pressed on iOS versions without multitasking or on apps that have multitasking disabled. As far as I know, no code can be executed outside GLB_ON_QUIT if the home button is pressed. Because of that a change a setting like STATE=ST_FOCAL_QUIT will never reach outside of the GLB_ON_QUIT subroutine. Game settings/progress should be saved within the GLB_ON_QUIT routine.

* GLB_ON_PAUSE is called for multitasking apps on iOS when the home button is pressed. You can set a state here like ST_FOCAL_PAUSE and afterwards the app will run in the background. During the time that, in your example, STATE is set to ST_FOCAL_PAUSE you should not draw to the back buffer or call showscreen. Game settings/progress can be saved within the GLB_ON_PAUSE subroutine or outside of it by detecting ST_FOCAL_PAUSE. Probably best to save with the GLB_ON_PAUSE subroutine though.

* GLB_ON_RESUME is called for multitasking on iOS when the app is re-opened or brought back from the background. However, if your app was previously paused it may not necessarily resume because iOS may kill it if memory is running low.

bigtunacan

Wampus,

You make a good point there with STATE=ST_FOCAL_QUIT; that is probably completely unneeded and would never hit my focal_quit_game subroutine.  I hadn't given that much thought; in my current state of my app I'm not bothering to write & read my game state; I'm just setting my game back to a new game initialization state.  That is not ideal since the player can't resume where they left off, but it was way better than having my app crashing all the time :)  I plan to update it to actually read & write state so the player can pick up where they left off, but that's pretty far down on my list of priorities right now.