First some background; for the tl;dr version skip to "the problem" below.
Background
This is really more of a user interface question than a technical one, but I think it fits better here than on the UI site anyway.
Since iOS (iPhone OS) 4.0 apps can run in the background, and actually always does so instead of quitting. Quitting an application requires pressing the home button, pressing it again, holding your finger on the application icon until it starts shaking, touching the "close" indicator, pressing the home button again. Not really intuitive.
The reason for this is of course that usually the user shouldn't care if the app is quit or just suspended, because it doesn't matter. But for some apps it does.
The problem
I have an app that logs location changes; think "RunKeeper" if that's familiar. The user starts the app, chooses to start recording (to a file), or just uses it to view distance, speed, etc. When the user is done (or wants to do something else), they hit the home button. The app disappears. Now one of several things happen:
The app quits, closing any ongoing recording (iPhoneOS 3.1.3 and below).
The app continues running in the background, using the GPS and draining the battery (iOS 4). This is appropriate if the user for example wanted to switch to the iPod app to change their soundtrack.
The app continues running in the background, using the GPS and draining the battery (iOS 4). This is completely inappropriate if the user was done and wanted to quit the app.
There is of course no way for the app to see the difference between cases three and four. A quick look around RunKeeper forums indicates that many users have no clue what is happening and get seriously confused by this.
Ideas
So what's the best way to solve this from a user interface point of view?
When the home button is pressed, go into background as is the default action. It's the user's problem to actually kill the app if they are done. It's the platforms fault that this is non-obvious and slightly tedious.
When the home button is pressed and a recording is in progress, continue in background. If we are not recording, quit the application.
Present a toggle widget somewhere in the application that allows the user to choose what happens when the home button is pressed. (This might run afoul of the HIG; I'm not sure)
...?
What do you think?
I though to the third option without reading at it ^^ (I don't think it would be against HIG)
So a "big" button when recording to change the "mode" ? Or a switch ;-) (Like "Continue Recording when in "background" ?")
And maybe asking the user about it when he start registering ? (with a default value available in prefs page ?)
And as you can change songs without quitting the app, maybe setting the default value as stopping record when the app is going to background.
But I haven't any other solution for you :-/
Related
I'm developing an iPhone/iPad application through Phonegap, is there a way to implement a sort of "click here to quit app"? I mean quit for real, not "put it in the background and go to home screen".
Thanks in advance.
you can use following code to quite your app on click,
device.exitApp()
OR
navigator.app.exitApp()
Hope this may help you.
is there a way to implement a sort of "click here to quit app"?'
Yes, there is a way for really exiting the app and killing its process.
But never do that. Not only because Apple rejects your app if you do this. The problem with this is bad user experience. iOS is not a desktop operating system. You have a Home button for leaving apps (and again, there's a reason apps don't exit completely).
The window size is, conceptually, not spacious enough for maintaining an extraneous 44x44 pixel frame (44 pixel is the minimal size that can comfortably be touched, according to Apple's Human Interface Guidelines) dedicated only for exiting.
However, if you still want to exit after this lecture, there are several ways:
exit(0);
pthread_kill(pthread_self()); // on the main thread
[[UIApplication sharedApplication] terminateWithSuccess];
etc. Some of them may have a binding in PhoneGap (if not, it's easy enough to write one yourself).
You should not do that as this may considered as violation of iOS Human Interface Guidelines, lead rejection of your app.
Always Be Prepared to Stop
**Save the current state when stopping at the finest level of detail possible so that people don’t
lose their context when they start the app again.** For example, if your app displays scrolling data,
save the current scroll position. To learn more about efficient ways to preserve and restore your
app’s state, see “State Preservation and Restoration”.
Apple guidlines link :
http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/mobilehig/UEBestPractices/UEBestPractices.html
in the application's plist put
UIApplicationExitsOnSuspend = TRUE
and when the user hits the home button, the application will quit. No need for a button, no need for exit().
http://developer.apple.com/library/ios/#documentation/general/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW23
Sorry, I am new to iPhone development and my google searches have failed me, so I have had to resort to posting a potentially idiotic question on SO.
I would like to write an app that, when suspended, performs an action when the user presses the home or power button (presumably to unlock the phone). I read the section in the iOS App Programming Guide's App States and Multitasking and the "Processing Queued Notifications at Wakeup Time" discusses handling queued events upon waking up. However, this isn't what I'm after.
I'd like to know if it is possible to:
From the phone sleeping state (I couldn't find a document for phone states, so I am talking about the case where the user presses the power button to turn off the screen), I would like my app to be ready to respond to the event where the user presses the power or home button (to unlock the phone)
I would like my app to respond to the event that occurs when the user unlocks the phone. I found an answer here that's close.
I don't want any funkiness when calls come in, get ignored, etc. :)
From what I can tell, it's a very gray area in the API around locking and unlocking, and I'd like to verify whether or not I'm wasting my time trying to do this.
It looks like I can use the accelerometer to detect when the phone is locked, but I also assume that I won't be able to count on this behavior in all future versions of iOS.
EDIT - I think I can handle the locking and unlocking requirements by assuming that the application has to be running at the time the phone is locked and unlocked, but I still cannot figure out if it is possible to determine #1 above, which is that the power button has been pressed and the unlock screen is displayed. Likewise, I'd like to know if the power button has been pressed again and is no longer displayed (i.e. screen is off).
All of the behaviors for your app being suspended/backgrounded are in the document you referenced. The AppDelegate will receive these messages and pass them on to whatever view you want to listen for them.
-applicationWillTerminate
-applicationWillEnterBackground
-applicationDidBecomeActive
-applicationWillResignActive
You can set up a notification observer in your view if you would like the view to be notified of any of these events. Then just override them or set up a custom method to do any work that needs to be done.
While the Apple docs might be a little foggy at first, all the information is in there to let you know which state your app will go to and how it will be handled. It is up to you to figure out what your app needs to do for each of these events. Hope this helps.
Consider an app that was in the multitask bar, and was closed, clicking on the minus sign.
What is supposed to be the behavior of this app at restart?
Does the app restart from scratch with the splash screen and without old data?
Or does the app load saved data and restart without splash screen and with previous data reloaded?
Thank you.
The application should restore its previous state in as many cases as possible. Prior to multitasking, all the applications tried to do this, to give the users the impression of multitasking. With multitasking in iOS 4, this doesn't change. You still need to do this to:
Support older devices.
Keep the user experience the same even if the user opens tons of apps and the device frees memory automatically.
If its closed then it will start from "scratch" unless you use the app delegate methods which are fired to store data and create the functionality to reload somewhere specific in your app yourself.
The splash screen will show if there is loading time needed, just like when you start an app the first time.
I think a user who clicks the minus is probably doing it, either just to clean up, or because he/she would like the app to return to it's beginning setup, just as if the device was reset.
I handle the minus, just like that, and start fresh with the splash screen. (not sure what the apple guide recommends)
This operation (tapping on minus icon) is intended for freeing memory.
When Apple has introduced multitasking in iOS, usage of memory has increased a lot!
So, why you have to tap on minus to kill application? When do you have to do this?
When your device responsiveness is too bad.
After killing (closing) application, when you restart the app, it start from scratch or resume last operation depending on how the application has developed!
For example, look at FacebookApp. If you are logged-in and quit app, at next restart it's reopen your account and last page seen!
For something like a game, I would suggest you restore the user's state ONLY IF they were in the middle of a game, else just start from scratch. However, for anything else, always start from scratch.
If you do nothing, your app will probably start from scratch at the moment.
I want to use my iPhone to very easily create a timestamp whenever a certain event occurs (e.g. every time I cough). The goal is to build up a log file that can be analyzed later for trends.
My iPhone is passcode locked because of my Exchange policy, so the steps to do this if I were to create a conventional app are as follows:
Press home buttom
Slide to unlock
Enter passcode
(If applicable) Close whatever app is already open
Navigate to my app in the home screen & launch it. When the app is launched, it records a timestamp.
This turns a very simple write-only action into a somewhat annoying task I will probably abandon, given that it may occur dozens of times a day. Is there a way around these steps?
Here's a hack I've come up with:
Press the home button
Press the home button and sleep/wake button simultaneously, taking a screenshot
Each time I do this, an image is created in my photo library. After a couple of weeks, I transfer the (hundreds of) pictures to my PC, and run a script to extract the timestamps from the screenshots' metadata and build the log.
Any other ways of doing this, possibly using Voice Commands, hardware buttons, log files, or something else I might not be aware of?
Edit: iPhone 3GS, iOS 4.
iOS4.0? Here's one idea requiring a media player app running in the background. Make an app like Pandora, or a simpler audio player app that continually plays silence (keeps filling audio queue buffers with zeros, etc.), and that will continue to play this "music" in the background. Have it register for volume change notifications. Record a timestamp when you press one of the volume buttons (have to be careful to alternate so you don't hit the max or zero volume).
Is it possible to override the default behavior (close app) of the Home Button? And if how do you do that?
well, there's a reasonable alt to the need to detect if the Home button was tapped. i'm currently working on just such a scenario.
my app allows user input (into UITextViews). a customer has asked for an "autosave" feature where, should they (accidentally) tap the Home button during data entry, could i still capture the data entered and save it.
my testing of the sequence of viewWillDisappear in the view that is collecting the data and applicationWillTerminate show viewWillDisappear getting called before applicationWillTerminate. now i fully appreciate that this is the architected sequence Apple intended, BUT this sequence also precludes setting a simple Boolean in applicationWillTerminate to let the particular viewWillDisappear know that it is disappearing specifically due to applicationWillTerminate.
so the issue still stands. how can a UIView detect that it is disappearing specifically as a result of the app terminating?
Even if it is possible, your app will probably not be approved by Apple.
Are you planning this feature for your own private App or do you want to distribute it later on?
The home button is probably the most critical button on the device on not a good idea to change