I have a CLLocationManager contained in a singleton and I have added around a dozen regions to monitor. I am successfully notified of boundary crossings when the app is in the foreground/background. However, when I force quit the app, the location icon disappears and I am not getting any callbacks.
As far as I can see, this is intended functionality as of iOS7. Here is a reply I found to a similar question, in this case involving significant location change: https://devforums.apple.com/message/882691#882691:
If a user swipes up in the app switcher then the OS will not launch the app unless explicitly told to do so by the user. So no, SLC will not be launching the app, nor will silent notifications. The only thing that will launch the app at that point is the user tapping the icon. The intention here is that the user has expressed their choice of not having that app running any more for any reason, so we honor that.
In this situation, there's really nothing that you can do. The next time the user launches the app you can let them know that some of the data may be missing, although you really cannot tell whether there's missing data or not (i.e. you might have been killed by the OS in the background and the user may not have moved thereby not triggering any SLC notifications). My suggestion would be to gather the data you can within the policies of the OS and if the user has manually killed the app then respect that wish and don't do anything.
By all means, feel free to file a bug report if this change in behavior winds up causing problems for you or (especially) confusion for your users.
Related
My application uses the core location also after the application terminates with the method startMonitoringSignificantLocationChanges in CLLocationManager class.
My application launches with a location key in iOS 5 and 6 in the method:
- (BOOL) application:application didFinishLaunchingWithOptions:launchOptions;
in AppDelegate class and everything works well.
But in iOS-7 betas the application doesn't launch with a location key after a significant location change.
Has anybody encountered this problem?
I tried it on a simulator and in the device.
Thanks for the help.
I have the same problem in my app, when the app was terminated by user from app switcher.
But it does launch with location key if it was terminated by OS for low memory or other reason.
It is the expected result from iOS7 unfortunately. An official apple response I got from one of their evangelists:
If a user swipes up in the app switcher then the OS will not launch
the app unless explicitly told to do so by the user. So no, SLC will
not be launching the app, nor will silent notifications. The only
thing that will launch the app at that point is the user tapping the
icon. The intention here is that the user has expressed their choice
of not having that app running any more for any reason, so we honor
that. In this situation, there's really nothing that you can do. The
next time the user launches the app you can let them know that some of
the data may be missing, although you really cannot tell whether
there's missing data or not (i.e. you might have been killed by the OS
in the background and the user may not have moved thereby not
triggering any SLC notifications). My suggestion would be to gather
the data you can within the policies of the OS and if the user has
manually killed the app then respect that wish and don't do anything.
By all means, feel free to file a bug report if this change in
behavior winds up causing problems for you or (especially) confusion
for your users.
Attach link to Apple DEV forums:
https://devforums.apple.com/message/882691#882691
I have to develop a kind of GPS navigation application that needs to constantly keep track of the position of the user, which is moving by car.
In the specific, I don't have to display the current location on a map but just to record its position with the best possible precision in order to calculate the total distance traveled.
Of course the application needs to continue its work in background if the user switch to another app, a phone call come in or something like that…
From the tests I have made and from what I have learned from this useful post (and from the documentation), it seems to me that the best choice in this case is the Standard location service, with the application configured with the UIBackgroundModes = location in the .plist file.
In this way it will continue to receive the location updates even if in background and it will never be suspended by the OS (this is actually true only if [locationManager startUpdatingLocation] has been called). This is also confirmed by this guys.
I have personally verified that is true simply by running the app with Instruments and the Memory monitor module where you can see the various flags about the app states, putting the app in background first with UIBackgroundModes set to location and startUpdatingLocation active, and after without it.
1) I'm now wondering what to do when the app is terminated when it is tracking the position. I don't want to loose any location updates so I need to wake up it again whenever a new update is available.
The documentation say:
Important: The applicationWillTerminate: method is not called if your
app is currently suspended.
But because in my case it will be never suspended (it will stay in background but not suspended), my logical conclusion is that applicationWillTerminate will be always called and so I could register for a Significant location update or Region monitoring inside of this method in order to be waked up and then restart the Standard location service.
Is applicationWillTerminate the right place to put this code?
2) An application working in background but not suspended could be terminated by the OS for no other reasons than a very low memory condition or for my app don't properly respond to a memory warning? (the user could also manually close it). I was concerned if applicationWillTerminate wouldn't be called in some way.
3) Could Apple not approve an app which constantly use the standard location services in background because of its quick battery drain?
Have you ever had approve problems for similar apps?
since you are asking many questions which you shoukd not do here, i cam give you only aswrs to a part of it.
if the app is terminated, then you cannot restart it anymore.
This is usually the case when the user terminates the app.
Dont worry Apple ( ios) will not terminate your app. your app will not use much memory, games with huge bitmap graphics are more likely to be termin.
evry gps app will drain the bat. that is not a reason for not aproving.
suspended means that app is not in background mode, it is sleeping. you will not receive Gps, so there is no need to call you on terminate. you have to save data before, see the apple docu on background modes and app life cycle.
When I restart the device my app is on it won't preserve the state it had once I open up the app again, it will be as if it's the first time I open, losing the session and having to re-login, how can I make my app preserve its state even through a device reboot? Like Twitter does, for example.
I'll try a bit more formal answer based on the comments you added above. I'll start by saying that the link Tim posted is something you should familiarize yourself with.
When your app is running, it's in the Foreground state. When you "exit" an app with the Home button, you're not really quitting it; you're just pushing it to the Background state. after a few seconds in background state, the OS automatically moves the app to the Suspended state. If you come back within a few minutes, your app is still in memory, so the OS just puts it back on the screen the way it was.
However, if you leave the app alone for a while and use other apps, the OS can--at any time and without warning--purge your app from memory. This is known as the "Not Running" state. Now, when the open the app again, it has to start from scratch. Obviously, the same thing happens when the device restarts--all apps are purged from memory.
The trick, then, is to save essential information about the app state whenever it enters the background state. You can use the app delegate's didEnterBackground method, or register for the UIApplicationDidEnterBackgroundNotification and invoke a method in your active view controller (or any other class, for that matter). Either way, you should save whatever state information you can.
How do you save this information? There are several strategies. For a simple app, perhaps you can register a few setting as NSUserDefaults. Or maybe you can write out a file containing whatever data the user was working on. It's really up to you.
Then, whenever the app launches, check for the presence of that saved data (however you chose to write it out), and set up the UI accordingly. To the user, it will appear as though the app never quit, which is exactly what Apple wants them to think.
What is the proper way of ending an application on the iPhone when you are finished with it?
thanks,
anton
Jaanus is referring to this paragraph in the Apple iPhone Human Interface Guidelines
Stopping
People quit an iPhone application by opening a different application. In particular, note that people don’t tap an application close button or choose Quit from a menu. In iOS 4.0 and later, and on certain devices, the quitting application moves to a suspended state in the background. All iPhone applications should:
Be prepared to quit at any time. Therefore, save user data as soon as possible and as often as reasonable.
Save the current state when stopping, at the finest level of detail possible. For example, if your application displays scrolling data, save the current scroll position.
iPhone applications should never quit programmatically because doing so looks like a crash to the user. There may be times, however, when external circumstances prevent your application from functioning as intended. The best way to handle this is to display an attractive screen that describes the problem and suggests how users can correct it. This helps users in two ways:
It provides feedback that reassures users that there’s nothing wrong with your application
It puts users in control, letting them decide whether they want to take corrective action and continue using your application or press the Home button and open a different application
If certain circumstances prevent only some of your application's features from working, you can display either a screen or an alert when users activate the feature. Although an alert doesn't allow much flexibility in design, it can be a good choice if you can:
Describe the situation very succinctly
Supply a button that performs a corrective action
Display the alert only when users try to access the feature that isn’t functioning
As with all alerts, the less users see them, the more effective they are. For more information about creating alerts, see “Using Alerts.”
There is no way for an iPhone application to quit/terminate itself. Apple actively advises against it in their Human Interface and/or programming guides (can't remember which exactly) because it would look like a crash to the user.
An app should not terminate by itself.
Also, avoid showing an "exit screen" that prompts the user to quit the app manually as in iOS4, the app might stay open in the background and your user would be stuck in that exit state.
I am trying to determine feasibility of certain features required in a (potential) project. I am not (yet) looking for a how-to, just a can-do. I apologize for any vagueness and ignorance: the former due to an NDA that makes Apple's NDA look like GPL, and the latter due to the fact that I have no iPhone or MAC experience.
I do have a solid understanding of objective-c and interface builder (going back to NextStep) and some PDA development experience, so I'll probably understand the answers, even if my questions are naive. I have done a bit of browsing, so I know some buzzwords.
I can't go into detail about the actual project, but I have come up with a lame analogy.
a large number of users in the same room are asked to complete task(s) in the app (say a puzzle)
they are under supervision, but the monitor cannot watch them all closely
they are not allowed to leave the application until done.
they cannot send/receive phone calls or messages during the task.
the monitor receives notification of various steps during the task
the monitor is notified when the task is completed, or the app is exited
the app sends a heartbeat, so the monitor also knows if signal is lost
Jailbreak is not an option.
The app should also work on iPod Touch.
So the things I need to do that seem dicey to me are
can I turn off (or require the user to turn off) phone and sms but still be able send http to my server
can I prevent an app from being switched out (even if, say an alarm app triggers or the phone rings).
failing prevention, can I at least detect any of these events and notify my server.
failing notification, can I record the event for the monitor to check later.
The user will be aware (and in fact welcome) these restrictions. It's a trust issue - the user must not seek help or use a helper app to solve the puzzle, and wants the monitor (and other contestants) to know that he did not. It's feasible for the user to click on an "OK, I understand and approve" screen at the beginning, but not for each communication to the server.
The app would only communicate with a central server (run by my company) - the monitor would not be able to buy the server software, and the url's of the server would not be user (or monitor) modifiable.
Hey! This looks like an app for taking exams. Not what I am doing, but that would be cool too!
EDIT --
I changed the title and am adding a few more parts to the question, based in part on mmc's answer. The App may run in an offline mode that would have to do the following:
So using the exam analogy, the user off line experience would be something like this
Launch App
App download test questions, registers start time, etc.
Turn off phone (if app can't do it by itself)
Disable any app that might interrupt my App (can app do this?)
Resume and Take Test
Indicate test done (or finish last problem).
Turn on phone (if app can't) and restart App (if needed).
App uploads test results and log of any interruptions.
So the question becomes
Am I sure that I at least get to log any interruption I can't prevent
can I know the cause of the interruption (phone answered, alarm launch, user initiated)?
can the user be prevented from modifying the log
can I know what other Apps are running when I start? (to guard against a daemon that occasionally displays a hint or something.
I would still like to run with real time uploads, so a few other ideas come to mind.
If I can reliably detect and record that the phone or another app was used, that might be almost as good as preventing it.
Can the user prevent the phone from ringing even if it's on (eg. call forward + ringer off)
Can my app know if the ringer is off
Same question for sms messaging
If I can't block it, can the user just ignore (silent) call or message and not leave my App. Would my app know that?
Sounds like you might be better off doing away with the phone, and making it exclusive to the iPod Touch.
You've nailed your trouble spots.
There is no way to disable phone functionality, and at the same time maintain network functionality of any type (3G, WiFi, or bluetooth) If you disable the phone operations with Airplane mode, all of them are disabled.
There is no way to prevent the Home button from returning you to Springboard
You can notify a server of a premature app interruption (there is an applicationWillTerminate: method on your app delegate) but is not reliable. If the operation takes too long, your app will be forcibly terminated.
You could write to the local file system that a premature interruption happened, and this would be far more reliable, as this operation would be much faster.