Geofencing Implementation in Mobile Apps: Overcoming Platform Limitations
An app with geofences that stops delivering notifications on iOS 17 is not a bug in your code. Apple rewrote the background location monitoring logic, tightened permission description requirements, and added new limits. A similar picture on Android: Doze mode, aggressive vendor battery optimizations, and a separate permission for background location with manual review in Google Play. Developers ignoring these nuances get a silent app and poor reviews.
We integrate geofences considering all platform constraints. With 10+ years of experience and 50+ geofencing projects, we ensure stable operation on the latest OS versions.
Platform Limitations: Comparison Table
| Platform | Max Zones | Min Radius | Background Restrictions | Works without GMS |
|---|---|---|---|---|
| iOS | 20 | 100 m | Delay 3-5 min, iOS 13+ Always requires two-step request | Yes (iOS only) |
| Android | 100 (recommend <=50) | ~100 m for stability | Doze, battery saver, ACCESS_BACKGROUND_LOCATION with manual review | Need HMS on Huawei |
| Huawei HMS | 100 | 100 m | Similar to Android, but no Doze (EMUI has its own mode) | Yes (HMS) |
iOS. CLLocationManager supports up to 20 active geofences simultaneously—system limit, not ours. Minimum radius is 100 meters; smaller radii are not monitored. On devices without A12+ chips, accuracy is even lower. CLCircularRegion delivers didEnterRegion / didExitRegion events, but delay can be 3-5 minutes depending on power saving mode. On iOS 13+ you must request Always authorization through a two-step dialog: first whenInUse, then the user goes to Settings. You can't directly ask for Always anymore—Apple will reject during review.
Android. Geofencing API in com.google.android.gms:play-services-location requires Google Play Services. On Huawei without GMS—need a separate path via HMS LocationKit. Android 10+ introduced ACCESS_BACKGROUND_LOCATION as a separate permission that the user grants in Settings, not in the standard dialog. On Android 12 SCHEDULE_EXACT_ALARM was added for precise alarms—without it, Geofencing on Doze devices may not trigger at the right time. Some manufacturers (Xiaomi MIUI, Samsung One UI with aggressive battery saver) kill background services before the API delivers the event.
How to Solve the Geofence Limit Exceeded Problem?
iOS: Basic Scenario
let region = CLCircularRegion( center: CLLocationCoordinate2D(latitude: 55.7558, longitude: 37.6173), radius: 200, identifier: "office_zone" ) region.notifyOnEntry = true region.notifyOnExit = false locationManager.startMonitoring(for: region) When exceeding the 20-zone limit, we prioritize by distance from current position and dynamically reload the set of active regions via stopMonitoring / startMonitoring. Rotation logic is in locationManager(_:didUpdateLocations:).
For projects needing more than 20 zones or radius less than 100 meters, we switch to Visit Monitoring (startMonitoringVisits()) or Significant Location Changes combined with server-side geofence check by coordinates.
Android: Geofencing API + WorkManager
val geofence = Geofence.Builder() .setRequestId("warehouse_exit") .setCircularRegion(lat, lon, 150f) .setExpirationDuration(Geofence.NEVER_EXPIRE) .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT) .setLoiteringDelay(30_000) // DWELL after 30 seconds .build() val request = GeofencingRequest.Builder() .addGeofence(geofence) .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER) .build() geofencingClient.addGeofences(request, geofencePendingIntent) The PendingIntent leads to a BroadcastReceiver that launches a WorkManager task instead of executing logic directly. This is important: direct execution of a long task from a Receiver on Android 8+ causes a BackgroundExecutionLimits exception.
For Huawei HMS, com.huawei.hms:location provides almost identical API, but requires a separate PendingIntent registration via GeofenceService.
Why Server-Side Validation Is Not an Option But a Necessity?
Mobile geofencing is inherently unreliable. For critical business scenarios (transport departure control, gamification with prizes) we build an additional server-side check: the device periodically sends coordinates, the server checks polygon intersection via PostGIS or geofence via Redis GEORADIUS. Mobile Geofencing provides a fast trigger; the server is the final arbiter.
Handling Permissions Correctly
The most common reason for App Store rejection is improper explanation of NSLocationAlwaysAndWhenInUseUsageDescription. Apple reads the strings in Info.plist and requires a specific description: "to send a notification when entering the pickup zone" instead of "for app operation".
In Google Play, since May 2023, background location undergoes manual review. The application must explain the specific use case and show a video demo. Allow 3-7 days for this.
What Is Included in the Work
- Geofencing API integration code for iOS (Swift 5.9+, SwiftUI/UIKit) and Android (Kotlin, Jetpack Compose).
- Handling limits and zone rotation.
- Proper permission management with text for App Store/Google Play.
- Testing: Walk Test on iOS and real drives on Android.
- Architecture documentation and description for review.
- Post-launch support: refinements, monitoring, bug fixes.
Work Process
Analysis of requirements: number of zones, minimum radius, platforms, presence of GMS in the target audience. Architecture design considering platform constraints. Implementation with correct permission management. Testing: Walk Test via Xcode Simulator Location, real drives for Android. Preparation of descriptions for review.
Timeline: from 3 to 6 days depending on the number of platforms and complexity of triggers. We will evaluate your project in 1 day—contact us for a consultation. Order turnkey geofencing implementation with a guarantee of correct operation on the latest OS versions.







