I need to monitor ~400 regions worldwide (some places in capitals with 1-3 km radius). However, there's a limit of monitored regions per app, so I cannot register them all at start. There's no concrete max number of regions in Apple docs, but some say that the safe max number of regions is 10 regions (here).
Apple docs state "To work around these limits, you should consider registering only those regions in the user’s immediate vicinity. As the user’s location changes, you can remove regions that are now farther way and add regions coming up on the user’s path". So, the questions is how and when to manage those regions?
The main callbacks are didEnterRegion and didExitRegion when using region monitoring. So at start, I though that everytime a user would enter some region, I would receive a notification where I could remove old regions, find relevant closest 10 regions and register them. But the problem will occur in cases when a user will not enter the closest region but will move more far away from them (for example fly with airplane from some place to the opposite place of the planet), and I will never get a change to update the list of monitored regions because didEnterRegion will never be called.
To work around this problem I'm thinking to add monitoring of significant changes because I should get callbacks (notifications) everytime one of the triangular cell towers change. So I could use those notifications to update a list of monitored regions quite frequently. That's it, what are your opinions on that?
The first thought that comes to mind is that if you have ten regions to work with, what you really want to do is set notifications on the 9 closest regions of interest and then one region that's not an actual region, but a meta-region around the current location. That way, you're more likely to receive a didExitRegion callback when the user moves away from the current location. At that point you deregister all 10 regions and repeat the process. (i.e. re-register 9 + meta region based on the new current location.)
As you propose, it also probably makes sense to get as many cracks at updating your ten regions as possible, so sure, adding a significant changes notification seems like a decent approach.
Another option, although probably frowned-upon, would be to tell the OS that your app is a VOIP application. This allows you to register for periodic wakeups. You could use these to update your regions. I don't know to what degree Apple audits the use of this facility, but it's something to try.
Related
I would say that the following are valid use cases for Early Media when used for IVRs:
Filtering
Disconnect incoming calls based on certain criteria (such as callers from a specific area code, or to play a message before hanging up on after hour callers).
Rate limiting
For example to limit the number of simultaneous callers, where the excess calls are either disconnected, or placed in a queue. (I'm not sure if the queue example is possible though without answering the call.)
Are there more?
Some links that were helpful:
https://www.dialogic.com/webhelp/csp1010/8.4.1_ipn3/sip_software_chap_-_early_media.htm
https://wiki.asterisk.org/wiki/display/AST/Early+Media+and+the+Progress+Application
https://freeswitch.org/confluence/display/FREESWITCH/Early+Media
3) Legal: in some countries it is illegal for a call center using payed line (caller pay per minute) to accept a call without sending it straight to an agent. So you can't accept the call, give the user some waiting music for 15 minutes (and make them pay for the privilege of waiting as well).
Result: you don't accept the call. However, this creates a new problem: if the caller only hears the ring back tone for those 15 minutes, he/she will assume no one will answer and hangs up.
Using early media, you can give them the traditional "your call is very important to us, please hold on"-type of experience without accepting the call and without starting to charge money. Of course this also depends somewhat on how much the provider is willing to tolerate, as this can also affects their income (depending on their own business model).
4) Comfort: you may not be aware of this, but the sound you hear as caller when the other side is ringing (ring-back tone), is not universally the same throughout the world. A company with a global number may wish to use early media to provide a ring-back tone more familiar to you, depending on where you are calling from. It was always a bit niche of a concept but some target audiences are statistically more likely to hangup if they hear an unfamiliar sound. 15-20 year ago this might have been a concern to some, but in the era of smartphones and internet calls, I doubt anyone really worries about it anymore.
Problem is discussed bellow :
1: User can register multiple events using my app with trigger distance and address.
how can i fire multiple events on the basis of location , when user near by , or leave or cross the registered event place .
where i have to manage the events and alert him.
i am using CLLocationManger delegate method didUpdateLocation for trace the location distance
please help me
iOS native support for Location is expansively explained in Location Awareness Programming Guide. As you go through it, you will see that your didUpdateLocation is nothing but a step in tracking user's location.
That said, there are number of other steps involved:
[locationManager startUpdatingLocation] - Triggers Location Manager to start monitoring for location updates.
didUpdateLocations - Delegate to be notified about location updates. Note that your method didUpdateLocation is valid for versions < iOS 6.
[locationManager startMonitoringSignificantLocationChanges] - fires location update events so that accurate monitoring is available with good power savings.
Region monitoring - this is what you want for geofence requirement.
regionMonitoringAvailable decides if hardware supports monitoring shape based regions.
startMonitoringForRegion method starts monitoring a specific region.
Similarly, stopMonitoringForRegion stops monitoring for a region.
Finally, didEnterRegion and didExitRegion gives you the geofence triggering you want.
That said, there are number of third party iOS sdk providers who provide high level support for region monitoring inside your iOS app. Geoloqi and Parse are two of them. You can visit their api pages to know more about how simplistic or complex their monitoring is, and choose based on pricing,complexity etc.
Nirav gave you a good overview whats included in the API, i concentrate here more on the things you will not find in apple docu:
To detect enter and leave of a geographical area, you can use
Circles, Rectangles and closed Polygons.
You store them with the latitude, longitude coordinates of that geo area.
To detect enter event:
if current location state changes from outside to inside area.
To detect leave event:
if current location state changes from inside to outside area.
calculate inside:
Inside Polygon: search here on Stackoverflow for point in polygon algorithm
Inside Rectangle: use API
Inside Circle: use API: distance from location to circle center < radius
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.
In my testing, I have found that the results of my tesing regionMonitoring on iPhone4S has been a little under par.
That being said, here's what's happening in my testing:
I try to test by setting an alert for the same location when I drive. Sometimes, the alert goes off right on the dime, but most of the time it does not. I have been wondering about the accuracy of this feature. The feature saves power, which is great, but what good is it if timely updates are not received by the device. It defeats the purpose. In this case the users are going to give bad reviews to the app - because they'll have to switch to startUpdatingLocation which is power hungry
Since I drive around for testing, and because the updates are not received - in time, I believe, the alert does not go off. Is my 50.0m radius too small? I can increase it - but the user will be alerted a little too soon!
The feature relies on user's device being passed by one cell-tower to the next. Therefore, is the user out of luck (for using this feature) if he/she happens to be in area where there are not enough cell towers?
Thoughts? Suggestions?
Regards....
50 meters is pretty aggressive even for GPS on a handheld. Try throwing up a wider net first, then switch to more aggressive location monitoring when you were say, within 500-1000m of the target location.
If I set my CLLocationManager's desired accuracy to be kCLLocationAccuracyKilometer (accurate within a kilometer) will the iPhone deliver a better position eventually, when it gets it ? Or will it stop at my desired accuracy. I can't find this in the documentation.
The idea is that I need a fast fix for the location, but then I would like to go more accurate. Will I have to code this myself, or is it done for me automatically ?
I don't know if the following is 100% correct, but I am pretty sure it works like this: the accuracy filters are primarily designed to save energy. So if you specify that kCLLocationAccuracyKilometer is enough for you and the OS is pretty certain that it can locate you accurately within 1 km using triangulation only, it won't even power up the battery-draining GPS unit. So regarding your first question, the location manager will stop as soon as it reaches your desired accuracy.
Regarding the second question: I don't think the accuracy filter has any influence on the time you receive your first location update. The OS often caches your last known location and will deliver that one almost instantly even if you have specified a very high accuracy. Subsequent location updates will get more and more precise.
You should be able to easily test for yourself if this is indeed the real behavior.
Set the best accuracy you need (but not more, because location services consume too much power). LocationManager will call didUpdateToLocation of your CLLocationManagerDelegate every time accuracy is improved. Stop updating location as soon as you can to prevent battery exhausting.
No, it will stop at the specified accuracy. If you request only kCLLocationAccuracyKilometer then the GPS receiver won't be powered on and it will get no better than WiFi or Cell tower triangulation. [The only exception would be if another app in the background (like TomTom nav) already has the GPS on for high accuracy fixes, then you might get the high (<300m) accuracy fixes too).
If you want better you have to request it and you might as well request it immediately, you'll get the fast fix (1000m accuracy) fix right away and in a minute or two you'll get the high accuracy GPS fix (well, it can take 30 seconds up to 10 min depending on several things). No special coding is required, just specify the accuracy you eventually want.