I am having issue regarding significant-change location service.
Apple documentation says "Whether you use the standard location service or the significant-change location service to get location events, the way you receive those events is the same."
but in case of "significant-change location service" I am not able to get any callbacks which
I get in case of "standard location service" Please let me know if anybody has any inputs?
startUpdatingLocation updates the location when it is called first time and then when the distance filter value exceeds.
But the startMonitoringSignificantLocationChanges when a significant change in position occurs.
Please check CLLocationManager for the details.
startUpdatingLocation
Starts the generation of updates that report the user’s current
location.
- (void)startUpdatingLocation Discussion
This method returns immediately. Calling this method causes the
location manager to obtain an initial location fix (which may take
several seconds) and notify your delegate by calling its
locationManager:didUpdateLocations: method. (In iOS 5 and earlier, the
location manager calls the
locationManager:didUpdateToLocation:fromLocation: method instead.)
After that, the receiver generates update events primarily when the
value in the distanceFilter property is exceeded. Updates may be
delivered in other situations though. For example, the receiver may
send another notification if the hardware gathers a more accurate
location reading.
Calling this method several times in succession does not automatically
result in new events being generated. Calling stopUpdatingLocation in
between, however, does cause a new initial event to be sent the next
time you call this method.
If you start this service and your application is suspended, the
system stops the delivery of events until your application starts
running again (either in the foreground or background). If your
application is terminated, the delivery of new location events stops
altogether. Therefore, if your application needs to receive location
events while in the background, it must include the UIBackgroundModes
key (with the location value) in its Info.plist file.
In addition to your delegate object implementing the
locationManager:didUpdateLocations: method, it should also implement
the locationManager:didFailWithError: method to respond to potential
errors.
startMonitoringSignificantLocationChanges
Starts the generation of updates based on significant location
changes.
- (void)startMonitoringSignificantLocationChanges Discussion
This method initiates the delivery of location events asynchronously,
returning shortly after you call it. Location events are delivered to
your delegate’s locationManager:didUpdateLocations: method. The first
event to be delivered is usually the most recently cached location
event (if any) but may be a newer event in some circumstances.
Obtaining a current location fix may take several additional seconds,
so be sure to check the timestamps on the location events in your
delegate method.
After returning a current location fix, the receiver generates update
events only when a significant change in the user’s location is
detected. For example, it might generate a new event when the device
becomes associated with a different cell tower. It does not rely on
the value in the distanceFilter property to generate events. Calling
this method several times in succession does not automatically result
in new events being generated. Calling
stopMonitoringSignificantLocationChanges in between, however, does
cause a new initial event to be sent the next time you call this
method.
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.
In addition to your delegate object implementing the
locationManager:didUpdateLocations: method, it should also implement
the locationManager:didFailWithError: method to respond to potential
errors.
Note: 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.
Related
I'm building my first CloudKit application, and am using CKFetchRecordZoneChangesOperation on startup to get any new records changed while the current device was offline.
I am also calling CKFetchRecordZoneChangesOperation when I receive a subscription notification of changes.
It is possible the subscription notification could come in before the startup call finishes. I am currently using a lock to prevent the 2nd call from starting until the recordZoneFetchCompletionBlock handler is called, signalling that the first one is done. This works, but it also smells a bit hacky.
If you for instance do
DataBase.database().refrence().observe(.valueChanged....
//code here
)
more then one time in the same spot, does this create a stack of observers? I want to make sure I only have 1 observer per spot. Does calling this method multiple times create more then one observer?
If you attach multiple observers to the same location in the database, the SDK is smart enough to internally only register with the server to receive updates to that location once. It doesn't duplicate the amount of data sent to the app. All your observers at that location will still receive the updates, so you will need to unregister each to stop receiving updates.
In the context of an application that has been registered to run in the background with the location services, what event(s) will result in backgroundTimeRemaining being reset to its maximum value and will that reset extend the duration allowed for the completion of ongoing tasks?
Based on the experiments I ran on the simulator and hardware, and for the context I defined in the question, backgroundTimeRemaining is reset whenever an internal call from the location library is made to didUpdateLocations (or didUpdateToLocation for IOS<6).
This is what all approaches used to running continuously in background leverage in one way or another.
What are you trying to do exactly? It looks like you want to run continuously in the background.
Or maybe you just want to run a little bit of code when the location updates? Then don't "cheat the system" and run that code when your app is notified of a location change (and run it using beginBackgroundTaskWithExpirationHandler:).
i'm implementing an app where i need to track user's location by the following:
track user's location while the app is in the background or closed
if the user's location is changed for about 2000 meters i should perform an API call.
my approach for this problem is the following:
the first time the user launches the app i start monitoring for a region using his current location
if the didExitRegion is triggered, i perform the API call and replace the current monitored region by a new region using the current location as the center of the new region.
this works fine when the app is in the foreground as the location that is returned from the location manager is accurate.
But if the app is in the background then the location manager will not return an accurate location since it's running for the first time and the first coordinates that are returned are not accurate.
the question is how can i get an accurate location of the user when the didExitRegion is triggered in the background?
thanks
I have not had a lot of luck with didExitRegion: firing reliably; it often fires much further away than the edge of my region.
I'd suggest you use CLLocationManager's -startMonitoringSignificantLocationChanges, if you just need an API call every 2km or so. If your accuracy/precision is important, just register location services as a necessary background state (UIBackgroundModes in your app plist; you may need to do this to use the significant change API from the background, too), and use the normal -startUpdatingLocation, with appropriate distanceFilter and desiredAccuracy field values on your CLLocationManager instance.
Several things happening here.
You mentioned that the region change trigger is a little variable. This is deliberate; to avoid high numbers of triggers being fired as you walk down the boundary between two regions, there is some stickiness to the triggering, in both time and position.
From the documentation (http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html#//apple_ref/doc/uid/TP40009497-CH2-SW1)
The system does not report boundary crossings until the boundary plus a designated cushion distance is exceeded. You specify the desired cushion distance for a region when you register it using the startMonitoringForRegion:desiredAccuracy: method. This cushion value prevents the system from generating numerous entered and exited events in quick succession while the user is traveling close the edge of the boundary.
Getting an accurate position is no different from normal. You start up the location manager and wait until you get a location update with the desired accuracy. Shut down the manager and use the position.
Because you're running in the background, you only have ten minutes to do this, and you have to tell the OS that you're doing background processing using UIApplication's startBackgroundTaskWithExceptionHandler. Plenty of documentation on that elsewhere.
Hope that helps.
Does google analytics SDK caches all data for sending them later if no Wifi is available? I guess everything is OK when iPhone/iPad is online (has internet available) then it sends all events data. But what about its functionality when the device has no internet connection? Do I have manually to check for internet connection (for example with apple reachability class) and maintain the data cache for later use myself?
Short answer: yes.
More details:
In case you use dispatch period greater than zero (let's say 15):
every 15 seconds GA tracker will try to dispatch events, AND
if no network connection is available, tracker will try to dispatch after another 15 seconds until success, AND
if it fails and you quit the app (it's not paused in the background), on next application session, tracker will try to dispatch your events again according to dispatch period.
In case you use dispatch period is equal to -1, which means you dispatch your events manually by calling [[GANTracker sharedTracker] dispatch]:
if you call dispatch but connection is not available, event will get cached, so next dispatch call will try to send cached events in a batch,
again, events are cached between application sessions.
The above also applies to a mix of above two cases: you use dispatch period > 0, but you decide to dispatch some events manually.
Note: I have no idea how much events/data can GA tracker cache before its' buffers get overwritten or go haywire.
Some other tips for using GA:
if you're unsure about something, set option dryRun to YES and test
your scenario. Also you can use some other account ID for testing
without dry run.
use GANTrackerDelegate methods to see if hits were dispatched.
This is a related question, basically you need to use batching. I think Flurry analytics makes this aspect more transparent (you just log events and it takes care of everything).