I'm trying to test region monitoring, for that I'm getting current location like this:
- (void)startLocationTracking
{
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
// Start location manager
if ([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
locationManager = [LocationTracker sharedLocationManager];
locationManager.delegate = self;
[locationManager startMonitoringSignificantLocationChanges];
}
}
And tracking first location with region monitoring like this:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:manager.location.coordinate radius:300 identifier:#"first location initializer"];
NSLog(#"0: %#", manager.location);
NSLog(#"1: %#", region);
[manager startMonitoringForRegion:region];
NSLog(#"[locationManager startMonitoringForRegion:%#];", region);
});
}
Then in every exit from current region I'm monitoring the new location like this:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(#"%s, %#", __PRETTY_FUNCTION__, region);
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(#"%s, %#", __PRETTY_FUNCTION__, region);
NSArray *allRegions = manager.monitoredRegions.allObjects;
if (allRegions.count > 0) {
for (CLRegion *reg in allRegions) {
[manager stopMonitoringForRegion:reg];
}
}
CLLocationCoordinate2D cord = CLLocationCoordinate2DMake(manager.location.coordinate.latitude, manager.location.coordinate.longitude);
CLRegion *regionNew = [[CLRegion alloc] initCircularRegionWithCenter:cord radius:300 identifier:#"new region"];
NSLog(#"region: %#", region);
NSLog(#"regionNew: %#", regionNew);
[manager startMonitoringForRegion:regionNew];
}
I'll explain what I expect to happen:
Register current location in region monitoring.
Notify user exit current region.
On exit log and register again the current location as region.
This doesn't happen.
Where I'm wrong?
I tried on simulator with 'Freeway Drive'.
UPDATE:
Tested and work, due to Apple bug in geofencing, app will support only 7.1+, pretty bad but I don't have an another idea.
I think the way you implement the region monitoring might cause some problems.
Here are the reasons:-
Inside the startLocationTracking method, your locationManager is a local object that does not extend over the life cycle of that method. It also means that every time you call startLocationTracking, there will be a new locationManagerobject that is allocated with a new block of memory.
To solve this problem: You should use a singleton locationManager that is a shared locationManager for the entire life cycle of the Application.
I believe you should not startMonitoringForRegion inside the delegate method -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:. The reason is, if you call startLocationTracking more once, there will be more than one locationManager. Multiple locationManagers could monitor the same region which may cause multiple notifications.
After you call [manager startMonitoringForRegion:region];, the region will not be monitored immediately. If you do not believe believe me, try the follow code:-
[locationManager startMonitoringForRegion:region];
NSLog(#"%#",locationManager.monitoredRegions);
You will find out that the region that you just monitored will not be inside the locationManager.monitoredRegions. Since this is handled on the iOS level, so, I think it might need a few minutes for the region to be ready to be monitored.
You should also understand other limitations for Region Monitoring in iOS:-
https://developer.apple.com/library/mac/documentation/CoreLocation/Reference/CLLocationManager_Class/CLLocationManager/CLLocationManager.html
An app can register up to 20 regions at a time. In order to report
region changes in a timely manner, the region monitoring service
requires network connectivity.
In iOS 6, regions with a radius between 1 and 400 meters work better
on iPhone 4S or later devices. (In iOS 5, regions with a radius
between 1 and 150 meters work better on iPhone 4S and later devices.)
On these devices, an app can expect to receive the appropriate region
entered or region exited notification within 3 to 5 minutes on
average, if not sooner.
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.
I don't know what your app is about, I believe you should redesign the flow of your app. You should try to monitor the region outside of the delegate methods.
For more information about the Singleton LocationManager, you may check out this answer: Background Location Services not working in iOS 7. There is a complete project on GitHub that contains a Singleton LocationManager class that I named as LocationTracker.
You might also want to check out a glitch for Region Monitoring in iOS 7 that I found out a month ago (with a workaround to solve the glitch): Region Monitoring Glitch on iOS 7 - Multiple Notifications at the same time
The most satisfactory answer to the delegates methods (didEnterRegion and didExitRegion) not being called is, apple docs says you will be notified after 3 to 5 minutes after the entry or exit, but in actual testing what I found is you have to wait for approx 7 to 8 minutes.
I tested it for 10 to 15 times and my region radius was around 80 meters. I was scratching my head to see what went wrong. I left the simulator open with the location tracking on (Used a gpx file for location simulation). After 8 minutes didExitRegion was called.
Also if you want to do this in background, you must enable background modes on your target.
Related
I have a location app that needs to get accurate location periodically. Currently I am getting constantly getting location in didUpdateLocation but I only ever log the location every 5 seconds. I am interested in a solution that gets accurate location periodically or on signification change. I would like either or both of these scenarios:
(by very accurate, I need 10m of desired accuracy)
Get a very accurate location every 5 seconds
Notify/callback if user moves a threshold ( eg moves 5 - 10 meters)
The app needs to work when backgrounded as well and location must still be logged if user switches to another app.
I was considering turning on/off location every 5 seconds but was not sure if that is the best practice. I also know there is also allowDeferredLocationUpdatesUntilTraveled but I believe that only applied to backgrounded mode. I would appreciate a solution that saves battery when the app is in use and in background mode. Please share your solutions and best practices for my use case.
I did write an app using Location services, app must send location every 10s. And it worked very well.
Just use the "allowDeferredLocationUpdatesUntilTraveled:timeout" method, following Apple's doc.
Steps are as follows:
Required: Register background mode for update Location.
Create LocationManger and startUpdatingLocation, with accuracy and filteredDistance as whatever you want:
-(void) initLocationManager
{
// Create the manager object
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
_locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
_locationManager.desiredAccuracy = 45;
_locationManager.distanceFilter = 100;
// Once configured, the location manager must be "started".
[_locationManager startUpdatingLocation];
}
To keep app run forever using "allowDeferredLocationUpdatesUntilTraveled:timeout" method in background, you must restart updatingLocation with new parameter when app moves to background, like this:
- (void)applicationWillResignActive:(UIApplication *)application {
_isBackgroundMode = YES;
[_locationManager stopUpdatingLocation];
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[_locationManager setDistanceFilter:kCLDistanceFilterNone];
_locationManager.pausesLocationUpdatesAutomatically = NO;
_locationManager.activityType = CLActivityTypeAutomotiveNavigation;
[_locationManager startUpdatingLocation];
}
App gets updatedLocations as normal with "locationManager:didUpdateLocations:" callback:
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// store data
CLLocation *newLocation = [locations lastObject];
self.userLocation = newLocation;
//tell the centralManager that you want to deferred this updatedLocation
if (_isBackgroundMode && !_deferringUpdates)
{
_deferringUpdates = YES;
[self.locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:10];
}
}
But you should handle the data in then "locationManager:didFinishDeferredUpdatesWithError:" callback for your purpose
- (void) locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
_deferringUpdates = NO;
//do something
}
NOTE: I think we should reset parameters of LocationManager each time app switches between background/forgeround mode.
Hopefully this should help
I am having difficulties getting this to work for when the app is not running. I have locationManager:didRangeBeacons:inRegion: implemented and it is called when the app is running in the foreground or background, however it doesn't seem to do anything when I quit the app and lock the screen. The location services icon goes away and I never know that I entered a beacon range. Should the LocalNotification still work?
I have Location updates and Uses Bluetooth LE accessories selected in Background Modes (XCode 5) I didn't think I needed them.
Any help greatly appreciated.
-(void)watchForEvents { // this is called from application:didFinishLaunchingWithOptions
id class = NSClassFromString(#"CLBeaconRegion");
if (!class) {
return;
}
CLBeaconRegion * rflBeacon = [[CLBeaconRegion alloc] initWithProximityUUID:kBeaconUUID identifier:kBeaconString];
rflBeacon.notifyOnEntry = YES;
rflBeacon.notifyOnExit = NO;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager startRangingBeaconsInRegion:rflBeacon];
[self.locationManager startMonitoringForRegion:rflBeacon];
}
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
if (beacons.count == 0 || eventRanged) { // breakpoint set here for testing
return;
}
eventRanged = YES;
if (backgroundMode) { // this is set in the EnterBackground/Foreground delegate calls
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = [NSString stringWithFormat:#"Welcome to the %# event.",region.identifier];
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
// normal processing here...
}
Monitoring can launch an app that isn't running. Ranging cannot.
The key to having monitoring launch your app is to set this poorly documented flag on your CLBeaconRegion: region.notifyEntryStateOnDisplay = YES;
This can launch your app on a region transition even after completely rebooting your phone. But there are a couple of caveats:
Your app launches into the background only for a few seconds. (Try adding NSLog statements to applicationDidEnterBackground and other methods in your AppDelegate to see what is going on.)
iOS can take its own sweet time to decide you entered a CLBeaconRegion. I have seen it take up to four minutes.
As far as ranging goes, even though you can't have ranging wake up your app, you can make your app do both monitoring and ranging simultaneously. If monitoring wakes up your app and puts it into the background for a few seconds, ranging callbacks start up immediately. This gives you a chance to do any quick ranging actions while your app is still running.
EDIT: Further investigation proves that notifyEntryStateOnDisplay has no effect on background monitoring, so the above should work regardless of whether you have this flag. See this detailed explanation and discussion of delays you may experience
Code for iOS 9 to range beacons in the background, by using Location Updates:
Open Project Settings -> Capabilities -> Background Modes -> Toggle Location Updates and Uses Bluetooth LE accessories to ON.
Create a CLLocationManager, request Always monitoring authorization (don't forget to add the Application does not run in background to NO and NSLocationAlwaysUsageDescription in the app's info.plist) and set the following properties:
locationManager!.delegate = self
locationManager!.pausesLocationUpdatesAutomatically = false
locationManager!.allowsBackgroundLocationUpdates = true
Start ranging for beacons and monitoring region:
locationManager!.startMonitoringForRegion(yourBeaconRegion)
locationManager!.startRangingBeaconsInRegion(yourBeaconRegion)
locationManager!.startUpdatingLocation()
// Optionally for notifications
UIApplication.sharedApplication().registerUserNotificationSettings(
UIUserNotificationSettings(forTypes: .Alert, categories: nil))
Implement the CLLocationManagerDelegate and in your didEnterRegion send both startRangingBeaconsInRegion() and startUpdatingLocation() messages (optionally send the notification as well) and set the stopRangingBeaconsInRegion() and stopUpdatingLocation() in didExitRegion
Be aware that this solution works but it is not recommended by Apple due to battery consumption and customer privacy!
More here: https://community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-
Here is the process you need to follow to range in background:
For any CLBeaconRegion always keep monitoring on, in background or foreground and keep notifyEntryStateOnDisplay = YES
notifyEntryStateOnDisplay calls locationManager:didDetermineState:forRegion: in background, so implement this delegate call...
...like this:
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
if (state == CLRegionStateInside) {
//Start Ranging
[manager startRangingBeaconsInRegion:region];
}
else{
//Stop Ranging
[manager stopRangingBeaconsInRegion:region];
}
}
I hope this helps.
You are doing two separate operations here - 'ranging' beacons and monitoring for a region. You can monitor for a region in the background, but not range beacons.
Therefore, your implementation of locationManager:didRangeBeacons:inRegion: won't get called in the background. Instead, your call to startMonitoringForRegion will result in one / some of the following methods being called:
– locationManager:didEnterRegion:
– locationManager:didExitRegion:
– locationManager:didDetermineState:forRegion:
These will get called in the background. You can at that point trigger a local notification, as in your original code.
Your app should currently wake up if you're just wanting to be notified when you enter a beacon region. The only background restriction I know of concerns actually hosting an iBeacon on an iOS device. In that case, the app would need to be physically open in the foreground. For that situation, you'd be better off just doing the straight CoreBluetooth CBPeripheralManager implementation. That way you'd have some advertising abilities in the background.
I'm looking for an open source app or library to track user location in the background. Now I'm trying to do it with CLLocation and background tasks, but accuracy is not enough for my case. Could you explain, how apps, like "moves", "runkeeper", "endmondo", creates my route? Should I use Accelerometer or/and compass to create a route between CLLocation background points?
Some code:
//location manager init
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;
#pragma mark - CLLocationManager Delegate
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
if ([self isInBackground]) {
if (self.locationUpdatedInBackground) {
bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
}];
self.locationUpdatedInBackground(newLocation);
[self endBackgroundTask];
}
} else {
if (self.locationUpdatedInForeground) {
self.locationUpdatedInForeground(newLocation);
}
}
}
UPD:
Justed tested my app with next properties
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.activityType = CLActivityTypeFitness;
self.locationManager.pausesLocationUpdatesAutomatically=NO;
In this case I have about 10 fired events during 1,5 hour trip
Use
kCLLocationAccuracyBestForNavigation
check this.
You need to add in your "Info.plist" file the key UIBackgroundModes (array) with the value "location" (app registers for location updates).
You can check all background modes here.
So your app uses location services. Then please read the Location Awareness Programming Guide.
You need to make some changes to your Info.plist:
If your app relies on location services to function properly, add location-services to UIRequiredDeviceCapabilities
if your app requires GPS hardware, add gps to UIRequiredDeviceCapabilities
if you need to run your app longer then 10 minutes in the background, add location to UIBackgroundModes. Then your location manager will deliver locations beyond the 10-minute-limit.
you should also set NSLocationUsageDescription (can also be localized)
Getting Location Events in the Background
If your app needs location updates delivered whether the app is in the foreground or background, there are multiple options for doing so. The preferred option is to use the significant location change service to wake your app at appropriate times to handle new events. However, if your app needs to use the standard location service, you can declare your app as needing background location services.
An app should request background location services only if the absence of those services would impair its ability to operate. In addition, any app that requests background location services should use those services to provide a tangible benefit to the user. For example, a turn-by-turn navigation app would be a likely candidate for background location services because of its need to track the user’s position and report when it is time to make the next turn.
Your problem is the background handler. Remove it and enable gps background mode in plist file. then you should get full power gps all the time.
Set property pausesLocationUpdatesAutomatically=NO
This is new in ios6.
From CLLocationManager:
Allowing the location manager to pause updates can improve battery
life on the target device without sacrificing location data. When this
property is set to YES, the location manager pauses updates (and
powers down the appropriate hardware) at times when the location data
is unlikely to change. For example, if the user stops for food while
using a navigation app, the location manager might pause updates for a
period of time. You can help the determination of when to pause
location updates by assigning a value to the activityType property.
The default value of this property is YES.
For analysis add these methods to your LocationManager delegate:
- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager {
NSLog(#"locMan: locationManagerDidPauseLocationUpdates");
}
- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager {
NSLog(#"locMan: locationManagerDidResumeLocationUpdates");
}
You can set up monitoring location stuff in you VC as below
in viewDidLoad method do as below
CLLocationManager locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;(Accuracy according to your need)
[locationManager startUpdatingLocation];
than you have to overrite below two optional delegate methods of CLLocationManagerDelegate protocol
for iOS6+
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{}
and for iOS 2 to 6
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
in these methods you will get updated location. use it as you want.
every time location updated these method get calls.
you don't ask for code. You ask for: "I'm looking for an open source app or library"
It may help you to visit this website.
hope it helps you,
Also a tutorial.
Here was my solution to this,
Declare the instance variable:
CLLocationManager *locationManager;
Be sure to include the delegate
<CLLocationManagerDelegate>
In viewDidLoad:
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move, location is updated
locationManager.desiredAccuracy = kCLLocationAccuracyBest; // get best current locaton coords
locationManager.headingFilter = 1;
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
Implement the delegate method:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
int degrees = newLocation.coordinate.latitude;
double decimal = fabs(newLocation.coordinate.latitude - degrees);
int minutes = decimal * 60;
double seconds = decimal * 3600 - minutes * 60;
NSString *lat = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
NSLog(#" Current Latitude : %#",lat);
latitudeLocation.text = lat;
degrees = newLocation.coordinate.longitude;
decimal = fabs(newLocation.coordinate.longitude - degrees);
minutes = decimal * 60;
seconds = decimal * 3600 - minutes * 60;
NSString *longt = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
NSLog(#" Current Longitude : %#",longt);
longitudeLocation.text = longt;
}
Disclaimer: I work for Cintric
We also wanted to be able to accurately track a users location in background (even after the app had been killed). We spent a long time solving the problem, especially focusing on battery drain.
We posted a great blog post on how we solved it. And also are providing a drag and drop SDK solution. It's not open source but you can integrate it for free:
You can download the .framework file, drag it into your project and initialize with one line of code:
[CintricFind initWithApiKey:#"YOUR_API_KEY_HERE" andSecret:#"YOUR_SECRET_HERE"];
You can get an API key for free. There are docs explaining everything here.
I've been having nothing but problems trying to do region monitoring on iPhone. First of all I have never (not even once) had either didEnterRegion or didExitRegion fire on my iPhone 4 device.
I decided to test on the simulator instead of wasting work hours walking around downtown (although I would like to see this work in a real scenario). First of all, the simulator is way off in terms of accuracy, you'd think it'd be pretty accurate (or am I wrong to have assumed that?).
The following was done in the simulator by changing the location under the Debug menu
I finally got didEnterRegion to fire, though I was about 8 city blocks away from the circle in question. When I exited the region didExitRegion fired about 200 times in a row. Is this a simulator bug? I'm almost ready to give up on this and start calculating this stuff myself because it's getting ridiculous.
Any ideas as to why the accuracy is so bad and why my methods are being fired so many times?
Here's the relevant code:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *) launchOptions
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
CLLocationDegrees latitude = 45.50568;
CLLocationDegrees longitude = -73.57033;
CLLocationCoordinates2D centerCoordinate = CLLocationCoordinate2DMake(latitude, longitude);
CLLocationDistance regionRadius = 200.0;
CLRegion *myRegion = [[CLRegion alloc] initCircularRegionWithCenter:centerCoordinate radius:regionRadius identifier:#"aroundWork"];
[locationManager startMonitoringForRegion:myRegion];
return YES:
}
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(#"Entered region: %#", region.identifier);
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(#"Exited region: %#", region.identifier);
}
First of all I assume you are testing it on the simulator with a GPX file, as any other way would be wrong.
Now, because I have done extensive research on Region Monitoring:
Region monitoring is not very effective.
It can miss a region enter or exit easily.
We have done a lot of tests and a lot of walks and driven with our cars through the city multiple times to test.
Sometimes it works beautifully, sometimes it fails miserably.
I suggest you play around a bit with the region border (radius) settings and do REAL tests (walk or drive around certain points) to see which behaves better.
Our tests showed that smaller values behave better (100 to 200 meters radius) and also that the region monitoring behaves better when you are actually driving, rather than walking.
Remember it uses the cell tower antennas to position you, which is far less accurate than gps.
I am using CLLocationManager to monitor regions in iOS. I set up the delegate in the normal way:
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
and implement several delegate functions including:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(#"GeoFence: didEnterRegion");
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(#"GeoFence: didExitRegion");
}
Then I start monitoring a region with:
CLLocationCoordinate2D coordinates = CLLocationCoordinate2DMake(lat, lng);
CLRegion *grRegion = [[CLRegion alloc] initCircularRegionWithCenter:coordinates radius:radius identifier:[NSString stringWithFormat:#"grRegion%i", 1]];
CLLocationAccuracy acc = kCLLocationAccuracyNearestTenMeters;
[self.locationManager startMonitoringForRegion:grRegion desiredAccuracy:acc];
with appropriate values for lat (51.116261), lng (-0.85300) and radius (200). After building and running the app in the iPhone 5.1 simulator, I use the location injection tool in Xcode 4.3 to move between a distant location to my target location and back again. Under this procedure, the didEnterRegion event correctly triggers but the didExitRegion never does. I also receive other delegate callbacks such as didUpdateToLocation. I have varied the pattern of simulated movements, used the simulator's location setting tool rather than Xcode's, and tried the same tests running the app on an iPhone 4S with iOS 5.1. All tests have the same result.
I have ensured WiFi is enabled as suggested in other threads and looked through other questions on related topics in vain. Any suggestions as why one of the region transition events would fire, but not the other?
I had this same issue in 5.1. I filed a radar with Apple as a bug. It would trip the first event, in or out, but no other events after that.
From what I can see, this issue has been resolved in the iOS 6 beta. So look for it to be resolved when iOS 6 goes live.
Radar: 11715223