2017-10-17 26 views
0

J'essaie de répondre aux mises à jour de position lorsque mon application est terminée. Apple's documentation états:CLLocationManager `didUpdateToLocation` non appelé lorsque l'application est terminée

iOS prend en charge la distribution des événements de localisation aux applications qui sont suspendus ou ne soit plus.

Il indique également que startUpdatingLocation

peut utiliser des mises à jour de localisation en arrière-plan OUI

Cependant, ma méthode didUpdateToLocation est appelée uniquement lorsque l'application est en cours d'exécution au premier plan ou dans le Contexte. Lorsque je termine l'application, elle ne se réveille jamais pour gérer les mises à jour de localisation. J'ai testé cela sur plusieurs appareils simulés (iPhone 6, 7, 8, X) ainsi que sur un vrai iPhone 5s. J'ai également confirmé setAllowsBackgroundLocationUpdates est appelé.

AppDelegate.m

#import "AppDelegate.h" 
#import "RNFIRMessaging.h" 
#import <CoreLocation/CoreLocation.h> 

#import <React/RCTBridgeModule.h> 
#import <React/RCTBundleURLProvider.h> 
#import <React/RCTRootView.h> 
#import "NoteManager.h" 

@implementation AppDelegate { 
    UIApplication *_app; 
    NoteManager *_noteManager; 
    CLLocationManager* _locationManager; 
} 

- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    NSLog(@"--- Initializing application"); 
    _app = application; 

    id<RCTBridgeDelegate> moduleInitialiser = self; 
    RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:moduleInitialiser launchOptions:launchOptions]; 

    RCTRootView *rootView = [[RCTRootView alloc] 
    initWithBridge:bridge 
    moduleName:@"GoNote" 
    initialProperties:nil 
    ]; 
    rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 
    UIViewController *rootViewController = [UIViewController new]; 
    rootViewController.view = rootView; 
    self.window.rootViewController = rootViewController; 
    [self.window makeKeyAndVisible]; 

    [FIRApp configure]; 
    [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self]; 
    [self setupLocationManager]; 

    return YES; 
} 

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { 
    // return [NSURL URLWithString:@"http://192.168.1.177:8081/index.ios.bundle?platform=ios"]; 
    return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; 
} 

- (NSArray *)extraModulesForBridge:(RCTBridge *)bridge { 
    NSLog(@"--- extraModulesForBridge"); 
    // Initialize our native modules here 
    _noteManager = [[NoteManager alloc] initWithApp:_app]; 
    return @[ 
    _noteManager 
    ]; 
} 

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { 
    NSLog(@"--- pushNotifications willPresentNotification"); 
    [RNFIRMessaging willPresentNotification:notification withCompletionHandler:completionHandler]; 
} 

#if defined(__IPHONE_11_0) 
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler { 
    NSLog(@"--- pushNotifications didReceiveNotificationResponse"); 
    [RNFIRMessaging didReceiveNotificationResponse:response withCompletionHandler:completionHandler]; 
} 
#else 
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler { 
    NSLog(@"--- pushNotifications didReceiveNotificationResponse"); 
    [RNFIRMessaging didReceiveNotificationResponse:response withCompletionHandler:completionHandler]; 
} 
#endif 

//You can skip this method if you don't want to use local notification 
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { 
    NSLog(@"--- pushNotifications didReceiveLocalNotification"); 
    [RNFIRMessaging didReceiveLocalNotification:notification]; 
} 

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{ 
    NSLog(@"--- pushNotifications didReceiveLocalNotification"); 
    [RNFIRMessaging didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; 
} 

- (void) applicationDidEnterBackground:(UIApplication *)application { 
    NSLog(@"--- applicationDidEnterBackground"); 
    [_locationManager stopUpdatingLocation]; 

    __block UIBackgroundTaskIdentifier bgTask = [_app beginBackgroundTaskWithExpirationHandler:^{ 
    bgTask = UIBackgroundTaskInvalid; 
    }]; 

    [NSTimer 
    scheduledTimerWithTimeInterval: 10.0 
    target: self 
    selector: @selector(startTrackingBg) 
    userInfo: nil 
    repeats: YES 
    ]; 
} 

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError*)error { 
    NSLog(@"--- (NoteManager) locationManager didFailWithError %@", error); 
} 

- (void) setupLocationManager { 
    NSLog(@"--- setupLocationManager"); 
    CLLocationManager* locationManager = _locationManager = [[CLLocationManager alloc] init]; 
    if([locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) { 
    NSLog(@"--- setAllowsBackgroundLocationUpdates:YES"); 
    [locationManager setAllowsBackgroundLocationUpdates:YES]; 
    } else { 
    NSLog(@"--- setAllowsBackgroundLocationUpdates:NO"); 
    } 
    [locationManager setDelegate:self]; 
    [locationManager requestAlwaysAuthorization]; 
    [locationManager setDesiredAccuracy:kCLLocationAccuracyBest]; 
    [locationManager setDistanceFilter:10]; 
    [locationManager setPausesLocationUpdatesAutomatically:NO]; 
    [locationManager startUpdatingLocation]; 
} 

- (void) startTrackingBg { 
#if !TARGET_OS_TV 
    NSLog(@"--- startTrackingBg"); 
    [_locationManager startUpdatingLocation]; 
#endif 
} 

- (void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 
    NSLog(@"--- didUpdateToLocation"); 
    if(_noteManager != nil) { 
    [_noteManager updateLocation:newLocation]; 
    } 
} 

@end 

AppDelegate.h

#import <UIKit/UIKit.h> 
#import <React/RCTBridgeDelegate.h> 
#import <CoreLocation/CoreLocation.h> 
@import UserNotifications; 

@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate, RCTBridgeDelegate, CLLocationManagerDelegate> 

@property (nonatomic, strong) UIWindow *window; 

@end 
+0

Notez que la méthode déléguée 'didUpdateToLocation' est obsolète. Vous devez utiliser 'didUpdateLocations' – Paulw11

Répondre

2

Cela ne fonctionne pas exactement comme vous le voulez. Les mises à jour de l'emplacement de travail lorsque vous surveillez les changements de localisation importants en utilisant

startMonitoringSignificantLocationChanges()

Lire cette réponse ici où quelqu'un a essayé presque la même chose - Restart location updates from the background

Vous pouvez lire la mise en œuvre ici

+0

Selon le but de l'application, vous pouvez également utiliser CLVisit ou la surveillance de région. Les deux réveillent l'application terminée en arrière-plan et appellent l'emplacement de mise à jour. –