After trial/error, testing, and conversations with Apple, I can confirm it's not a bug with region monitoring, it's a bug with Apple's new prewarming feature in iOS 15.
In a nutshell, iOS 15 will half-launch apps silently in the background that iOS believes the person will use. In our testing this happens about every half hour. It makes app launching feel faster because a bunch of the app is already loaded and ready to go.
If Apple prewarms your app, and the user doesn't fully launch it, and then a region monitor needs to notify your app, it won't happen. That's sometimes region monitoring alerts your app and sometimes it doesn't. If your app is "cold", it will work. If your app is in memory, it will work. If your app is in this prewarm state, you are dead in the water.
Rebooting the whole phone works, because you're evicting any app in a prewarmed state.
I have it from Apple that this is really multiple bugs, some fixed and some not yet. The notes in the iOS 15.2 betas also specifically mention this likely affects HealthKit too.
The solution that works around the bug is to detect in main.m
when Apple is prewarming your app and exit
. This doesn't permit your app to launch when Apple prewarms and forces your app to fully boot when the time comes.
Here's the code for inside the main()
method inside main.m
. Note that it's prudent to add an iOS version detection so when Apple does fix this it can eventually be phased out and removed.
double systemVersion = [[UIDevice currentDevice] systemVersion].doubleValue;
if (systemVersion >= 15.0) {
NSDictionary* environment = [[NSProcessInfo processInfo] environment];
BOOL prewarmed = false;
for (NSString *key in environment.allKeys) {
if ([key.lowercaseString containsString:@"prewarm"]) {
prewarmed = true;
break;
}
}
if (prewarmed) {
exit(0);
}
}