iOS 11.2.2后台定位服务失效问题技术求助
Hey there, let's dig into this CoreLocation issue you're facing on iOS 11.2.2—since it worked fine on iOS 10, the problem is almost certainly tied to iOS 11's stricter location service rules or behavior changes. Here are the key fixes and checks to try:
1. Fix the iOS 11+ Permission Request Flow
iOS 11 overhauled how "Always" location permissions are granted, and your current code doesn't handle the updated workflow properly:
- If the user hasn't granted any permission yet, you can't directly request "Always" access first. You need to start with "When In Use" authorization, then upgrade to "Always" after the user allows it.
- Add this logic to your
startLocationTrackingmethod where you check authorization status:CLAuthorizationStatus authorizationStatus = [CLLocationManager authorizationStatus]; if (authorizationStatus == kCLAuthorizationStatusNotDetermined) { if (@available(iOS 11.0, *)) { // iOS 11+ requires starting with When In Use [locationManager requestWhenInUseAuthorization]; } else { [locationManager requestAlwaysAuthorization]; } } else if (authorizationStatus == kCLAuthorizationStatusAuthorizedWhenInUse && @available(iOS 11.0, *)) { // Upgrade to Always permission after user allows When In Use [locationManager requestAlwaysAuthorization]; } - Double-check your
Info.plisthas all required description keys for iOS 11+:NSLocationAlwaysAndWhenInUseUsageDescription(primary for iOS 11+)NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescription(fallback for older iOS versions)
2. Verify Your LocationManager Singleton
Your LocationTracker singleton might not be reinitializing correctly after the app restarts, leading to broken delegate connections:
- Ensure the singleton's
sharedLocationManagermethod properly creates a fresh instance (or resets critical properties) on app launch:+ (CLLocationManager *)sharedLocationManager { static CLLocationManager *manager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ manager = [[CLLocationManager alloc] init]; // Set base properties here, but leave delegate assignment for when you use it manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; manager.distanceFilter = kCLDistanceFilterNone; }); return manager; } - Every time you call
startLocationTracking, explicitly re-set the delegate toself—the old delegate reference from before the app was terminated will be invalid after a restart.
3. Remove Unnecessary Background Tasks
When using allowsBackgroundLocationUpdates with the "Location updates" background mode enabled, you don't need to manually manage background tasks for location tracking. Your current beginNewBackgroundTask logic is redundant and might even interfere with iOS's location service prioritization:
- Delete the background task management code from
applicationDidEnterBackground—iOS will handle keeping the app alive for location updates automatically if you've configured the correct background modes and permissions.
4. Fix Debug Log Visibility
If you're manually restarting the app (not launching it via Xcode), the debugger won't automatically attach, so you won't see logs. To fix this:
- In Xcode, go to Debug > Attach to Process and select your app after manually launching it.
- Or, go to Edit Scheme > Run > Info and set "Launch" to "Wait for executable to be launched"—then manual app launches will auto-connect to the debugger.
5. Understand iOS 11's Forced Quit Behavior
iOS 11 changed how apps behave after being force-quit:
- The system will not automatically wake your app for regular location updates (
startUpdatingLocation) after a force quit. If you need location updates even after a force quit, you'll need to switch tostartMonitoringSignificantLocationChanges(lower accuracy, but system-managed wake-ups). - For regular post-restart functionality, ensure
startLocationTrackingis called reliably inapplication:didFinishLaunchingWithOptions:(not justapplicationDidBecomeActive) to initialize location services as soon as the app launches.
内容的提问来源于stack exchange,提问作者Tejas R.

