2017-10-17 138 views
0

我试图在应用程序终止时响应位置更新。 Apple's documentation状态:CLLocationManager`didUpdateToLocation`在应用程序终止时不会调用

IOS支持到是 悬浮或不再运行的应用程序的传递位置的事件。

报告还指出,startUpdatingLocation

可以在后台模式下使用的位置更新是

然而,当应用程序在前台还是在运行我didUpdateToLocation方法只叫背景。当我终止应用程序时,它永远不会处理位置更新。我已经在几个模拟设备(iPhone 6,7,8,X)以及真正的iPhone 5s上测试了这个功能。我也确认setAllowsBackgroundLocationUpdates被调用。

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

请注意,委托方法'didUpdateToLocation'已弃用。您应该使用'didUpdateLocations' – Paulw11

回答

2

这不正是你想要的工作。当您监视使用

startMonitoringSignificantLocationChanges()显著位置变化的位置更新工作

这里阅读答案在有人试图几乎同样的事情 - Restart location updates from the background

你可以在这里读到的实施https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html

+0

根据应用程序的目的,您还可以使用CLVisit或区域监视。都在后台唤醒终止的应用程序并调用更新位置。 –

相关问题