Foursquare always tracks geolocation (even when it's turned off) - ios

Foursquare always tracks geolocation (even when it's turned off).
On the image you can see that it tracks geolocation right now, but I turned it off, so when I double press home button I don't see Foursquare app.
Is it but of iOS7, is it bug of my iPhone?
Or may be Apple provided Foursquare with these abilities?

You can find out information on using location in the background in the Apple Location and Maps programming guide. Although your application doesn't appear in the app switcher it can still receive notifications - just as an app that isn't "running" can display notifications on the lock screen or update its icon badge.
From the Core allocation documentation on Signficant Region Change Notification -
If you start this service and your application is subsequently terminated, the system automatically relaunches the application into the background if a new event arrives. In such a case, the options dictionary passed to the locationManager:didUpdateLocations: method of your application delegate contains the key UIApplicationLaunchOptionsLocationKey to indicate that your application was launched because of a location event. Upon relaunch, you must still configure a location manager object and call this method to continue receiving location events. When you restart location services, the current event is delivered to your delegate immediately. In addition, the location property of your location manager object is populated with the most recent location object even before you start location services.
So, just because you have terminated the app and it doesn't appear in the app switcher doesn't mean that iOS can't relaunch it to process the notification and then shut it down again

Related

iOS: Location Update in Application Suspended State

Is it possible to update location when application is in suspended/terminate state.
i want to update location every 500 meters when app is in suspended/terminate state.
thanks in advance.
When terminated the only real way to get updates is to use Region Monitoring but you will only get major updates so I doubt it will work for 500 meters.
From the documentation:
If your app is terminated either by a user or by the system, the
system doesn't automatically restart your app when new location
updates arrive. A user must explicitly relaunch your app before the
delivery of location updates resumes. The only way to have your app
relaunched automatically is to use region monitoring or
significant-change location service. However, when a user disables the
Background App Refresh setting either globally or specifically for
your app, the system doesn't relaunch your app for any location
events, including significant change or region monitoring events.
Further, while Background App Refresh is off your app won't receive
significant change or region monitoring events even when it's in the
foreground.
There are good reasons for this. Firstly people don't want apps that 'snoop' on them all the time and even if there is a good reason imagine having 10 apps doing this constantly. It's going to start causing you performance and battery life issues.
EDIT
There appears to be some confusion by a lot of people over this issue so I will attempt to clear things up a bit.
Your app is NOT supposed to be continually tracking location while terminated (or suspended really). You are just not allowed to do this both for privacy reasons and so that you don't drain the battery excessively.
While your app is in the foreground you can use location services via startUpdatingLocation to monitor the device location. Assuming the app has been granted permission this will use all available hardware (GPS, WiFi, Cellular).
Now from the documentation itself:
If you start this service and your app is suspended, the system stops
the delivery of events until your app starts running again (either in
the foreground or background). If your app is terminated, the delivery
of new location events stops altogether. Therefore, if your app needs
to receive location events while in the background, it must include
the UIBackgroundModes key (with the location value) in its Info.plist
file.
So once suspended and terminated your options are really to monitor regions and to monitor for significant location changes. Neither of these are particularly accurate or frequent. One reason for this is that they only use low power methods to get the position (WiFi and Cellular) they don't use the GPS.
So no accurate and/or frequent location tracking while an app is suspended or terminated. This just has to be accepted and you need to design your apps accordingly.
let locationManager = CLLocationManager()
locationManager.startMonitoringSignificantLocationChanges()
After returning a current location fix, the receiver generates update events only when a significant change in the user’s location is detected. It does not rely on the value in the distanceFilter property to generate events
If you start this service and your app is subsequently terminated, the system automatically relaunches the app into the background if a new event arrives. In such a case, the options dictionary passed to the application(:willFinishLaunchingWithOptions:) and application(:didFinishLaunchingWithOptions:) methods of your app delegate contains the key location to indicate that your app was launched because of a location event. Upon relaunch, you must still configure a location manager object and call this method to continue receiving location events. When you restart location services, the current event is delivered to your delegate immediately. In addition, the location property of your location manager object is populated with the most recent location object even before you start location services.
Apps can expect a notification as soon as the device moves 500 meters or more from its previous notification. It should not expect notifications more frequently than once every five minutes. If the device is able to retrieve data from the network, the location manager is much more likely to deliver notifications in a timely manner.
Hope It helps

IOS Getting location updates when app terminated without using significantChange

I apologise for the redundancy of this topic, but in spite all the given answers, I can't identify the possibility of getting accuracyBest location updates when the app is terminated.
I don't want to use monitoringSignificantChange, I want the best possible accuracy; I won't submit the app on the AppStore, so Apple restrictions are not a problem either.
I have gone through these:
-Location update even when app is killed/terminated
-iOS update location even when app is terminated
-Working with location updates when app is terminated
-http://mobileoop.com/getting-location-updates-for-ios-7-and-8-when-the-app-is-killedterminatedsuspended
and many more, but it is not clear whereas it's possible or not. I currently have my project, everything works great with significantChange but I now need better accuracy.
Could somebody tell me straight forward if getting best accuracy location update when app is killed is possible please ?
Thank you infinitely,
Looking at the below content from the Apple doc, you clearly have 2 alternatives against using significant location changes to wake a app from the background. I have marked in bold the services you can use to relaunch the app if it has been terminated.
Using Location Services in the Background Most location services are
meant to be used while your app is in the foreground but some can also
run in the background. In some cases, location events can even cause
your app to be relaunched to process an event. To run most location
services in the background, you need to enable the location updates
background mode in the Capabilities tab of your Xcode project. For
services that launch your app, you need to request (and be granted)
“Always” authorization from the user.
The standard location service delivers events normally while an app is
running in the foreground. When your app is in the background, this
service delivers events only when the location-updates background mode
is enabled for the app. This service does not relaunch iOS apps that
have been terminated.
The significant location change service delivers events normally
while an app is running in the foreground or background. For a
terminated iOS app, this service relaunches the app to deliver
events. Use of this service requires “Always” authorization from the
user.
The region monitoring service delivers events normally while an
app is running in the foreground or background. (You can use this
service for both geographic and beacon regions.) For a terminated
iOS app, this service relaunches the app to deliver events. Use of
this service requires “Always” authorization from the user.
Beacon ranging delivers events normally while an app is running in the
foreground. When your app is in the background, this service delivers
events only when the location-updates background mode is enabled for
the app and the standard location service is running. (If the beacon
region’s notifyEntryStateOnDisplay property is YES, waking the device
causes the app to range for beacons for a few seconds in the
background.) This service does not relaunch iOS apps that have been
terminated; however, you can be relaunched by monitoring beacon
regions using the region monitoring service.
The heading service delivers events normally while an iOS app is
running in the foreground. When your app is in the background, this
service delivers events only when the location-updates background mode
is enabled for the app and the standard location service is running.
This service does not relaunch iOS apps that have been terminated.
The visit service delivers events normally while an iOS app is
running in the foreground. When your app is in the background, this
service delivers events only when the location-updates background mode
is enabled for the app and the standard location service is running.
For a terminated iOS app, this service relaunches the app to deliver events. Use of this service requires “Always” authorization from the
user.
Enabling the location-updates background mode ensures that an app
continues to receive location events while in the background. When the
app moves to the background, the system adds the location-services
indicator to the status bar to let the user know that an app is using
location services. The system may still terminate the app at any time
to reclaim its memory or other resources.
Also from the doc,
Getting the Visited Locations
In iOS, the visits service provides an alternative to the significant location change service for apps that need location
information about interesting places that the user visited. For
example, if the user is in one location for an extended period of
time, the service might generate an event when the user arrives at
that location and another when the user leaves that location. The
service is intended for apps that might already be using the
significant location change service and want an even lower power way
to do so. You would not use this service to create navigation apps or
apps that rely on regular location updates.
Document Link:
https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/index.html#//apple_ref/doc/uid/TP40007125-CH3-SW73
Continuous location updates stop when your app is terminated.
Geo-fence notices will re-launch your app even if it's not running. I think a significant location change will also relaunch you're app but I'm not as sure about that.
Once you're relaunched you can start location updates again with the accuracy set to best like you want, but I think you're going to need to use one of those two APIs to get relaunched again after you've been terminated.

how to get user's current location when application has been terminated

I have gone through many tutorials but not able to find the right solution. I am working on location base application where I need to fetch user's current location, it doesn't matter even if the application is running in foreground or in background. So when i kill or terminate the application is it possible to fetch user's current location?
Yes it is possible. You will have to use method startMonitoringSignificantLocationChanges. According to CLLocationManager documentation
If you start this service and your application is subsequently
terminated, the system automatically relaunches the application into
the background if a new event arrives. In such a case, the options
dictionary passed to the application:didFinishLaunchingWithOptions:
method of your application delegate contains the key
UIApplicationLaunchOptionsLocationKey to indicate that your
application was launched because of a location event. Upon relaunch,
you must still configure a location manager object and call this
method to continue receiving location events. When you restart
location services, the current event is delivered to your delegate
immediately. In addition, the location property of your location
manager object is populated with the most recent location object even
before you start location services.

Does location update remain running after force close app

I am sending user location at n time on server for tracking. Working fine in foreground and background mode. But my question is bit more theoretical.. Does my location update service remain running after i force close the app on the device?
I know i can check it on server, But sorry i don't have server access permission. So i have to be sure in which scenario my location service will stop running.
Yep it will continue to be updated when the application is sent into the background. For some official docs check here under the "Getting Location Events in the Background (iOS Only)" section.
Also, under special circumstances you can register your application to have a true background process running like Android allows. So when the user kills the background application, your app doesn't really die. The background process continues to work. Apple will only allow apps that have a necessary reason for this though. Such as a turn by turn navigation app (example from the docs).
Yes, if the application is removed from background then location update will be stopped.
iOS will only restart an app after a force close if its uses region monitoring or the significant-change location service. From the iOS Location and Maps Programming Guide section on Getting the User’s Location:
If your app is terminated either by a user or by the system, the system doesn’t automatically restart your app when new location updates arrive. A user must explicitly relaunch your app before the delivery of location updates resumes. The only way to have your app relaunched automatically is to use region monitoring or the significant-change location service.
iOS only restarts the app if it has Background App Refresh enabled:
when a user disables the Background App Refresh setting either globally or specifically for your app, the system doesn’t relaunch your app for any location events, including significant-change or region monitoring events.

Recording events with Flurry after app was launched due to a monitored region being entered

The scenario is as follows. I have an iOS app that uses the CLLocationManager's region monitoring feature to notify the app when a predefined geographic region is entered. The way region monitoring works, the app can be notified of a user entering a region, even if the app was previously terminated. Basically, the operating system will launch the app (without bringing it to the foreground), when the region is entered, and gives the app a chance to respond to the region being entered.
What I am trying to do is log an event using Flurry when the region is entered. Currently, it does not seem to be working, as the events are not showing up in Flurry, even after several days. I should note that I have tested both i) that Flurry event logging is otherwise working OK when the app is launched as normal by the user and ii) that my app is indeed receiving the region entered and exited events (I use local notifications each time the region is entered or exited).
My suspicion is that it has something to do with the application delegate lifecycle differing when the app is launched as a result of entering a region versus when the app is launched as a result of the user starting it. My first suspicion was that application:didFinishLaunchingWithOptions: was not called when the app was launched in the background. Because my call to [Flurry startSession:#"my_key"] is in the application:didFinishLaunchingWithOptions: method, this would have explained things. However, the Apple documentation for startMonitoringForRegion:desiredAccuracy: suggests that application:didFinishLaunchingWithOptions: is in fact called:
If you begin monitoring a region and your application is subsequently
terminated, the system automatically relaunches it into the background
if the region boundary is crossed. In such a case, the options
dictionary passed to the application:didFinishLaunchingWithOptions:
method of your application delegate contains the key
UIApplicationLaunchOptionsLocationKey to indicate that your
application was launched because of a location-related event.
Although I'm using startMonitoringForRegion: and not startMonitoringForRegion:desiredAccuracy: (deprecated), I'm assuming that both call application:didFinishLaunchingWithOptions:. I then read a note in the Flurry documentation about startSession: (emphasis mine):
This method serves as the entry point to Flurry Analytics collection.
It must be called in the scope of applicationDidFinishLaunching. The
session will continue for the period the app is in the foreground
until your app is backgrounded for the time specified in
setSessionContinueSeconds:. If the app is resumed in that period the
session will continue, otherwise a new session will begin.
Note:
If testing on a simulator, please be sure to send App to background via home button. Flurry depends on the iOS lifecycle to be complete for full reporting.
So, my suspicion is that even though I am testing on a real device, the app never gets "sent to the background" because when it launches it never enters the foreground to begin with. Can anyone clarify whether this is the reason for my logged events never showing up, or whether there is perhaps some other reason? And, is there a workaround for this?
So I contacted Flurry support and this is what I heard back:
So, at present its not possible to record / log events while the app is in the background.
Our engineering team is working on a solution to this and this should be available in one of the future versions of our SDK, in probably a months time.
So I guess we'll wait and see.

Resources