繁体   English   中英

从不重新启动React-native应用程序以处理iOS中的位置更新

[英]React-native app is never relaunched to handle location updates in iOS

我正在尝试终止本机应用程序中的位置更新。 在几天后无法使react-native-background-geolocation或CLLocationManager始终正常工作后,我现在尝试使用intuit / LocationManager窗格,但是我的应用程序未响应位置更新而重新启动(或者可能只是不记录它们?)

这是Intuit处理基于位置的发射的示例:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // If you start monitoring significant location changes and your app is subsequently terminated, the system automatically relaunches the app into the background if a new event arrives.
    // Upon relaunch, you must still subscribe to significant location changes to continue receiving location events. 
    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {
        INTULocationManager *locMgr = [INTULocationManager sharedInstance];
        [locMgr subscribeToSignificantLocationChangesWithBlock:^(CLLocation *currentLocation, INTULocationAccuracy achievedAccuracy, INTULocationStatus status) {
            // This block will be executed with the details of the significant location change that triggered the background app launch,
            // and will continue to execute for any future significant location change events as well (unless canceled).
        }];
    }
    return YES;
}

这是我的代码:

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

  INTULocationManager *locMgr = [INTULocationManager sharedInstance];
  [locMgr subscribeToSignificantLocationChangesWithBlock:^(CLLocation *currentLocation, INTULocationAccuracy achievedAccuracy, INTULocationStatus status) {
    // This block will be executed with the details of the significant location change that triggered the background app launch,
    // and will continue to execute for any future significant location change events as well (unless canceled).
    NSLog(@"--- location update");
  }];

  _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];

  return YES;
}

为了测试这一点,我在模拟器中打开应用程序,等待位置更新(应用程序记录“位置更新”),然后关闭应用程序(双击command-shift-h并滑走应用程序)。 然后,我等待模拟器的调试位置设置为“ Freeway drive”。

据我了解,该应用程序应该在后台启动,并且应该看到日志“正在初始化应用程序”和“位置更新”,但这从未发生。

我的info.plist文件中包含以下条目:

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>CHANGEME: NSLocationAlwaysAndWhenInUseUsageDescription</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>CHANGEME: NSLocationAlwaysUsageDescription</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>CHANGEME: NSLocationWhenInUseUsageDescription</string>
<key>NSMotionUsageDescription</key>
<string>CHANGEME: NSMotionUsageDescription</string>
<key>UIBackgroundModes</key>
<array>
    <string>fetch</string>
    <string>remote-notification</string>
    <string>location</string>
</array>

为什么我的应用程序不处理位置更新?

iOS有几种方法可以在后台正确运行应用程序。 这些方法已在iOS中启用。 我们将使用您的应用程序将要使用的和我们需要的那个。 我们可以在UIBackgroundModes数组中看到的所有服务:

请遵循此链接: -https : //developer.apple.com/documentation/corelocation/cllocationmanager/1620568-allowsbackgroundlocationupdates?language=objc

如果应用程序在前台,我们可以简单地停止监视,然后在间隔后再次启动它,例如使用NSTimer。 在这种情况下,我们必须考虑应用程序的寿命。 该应用程序在后台运行,在空闲期间停止工作。

在iOS内部,我们无法更改系统更新用户位置的时间间隔。 如果有GPS信号,IOS会每秒定期更新位置。

应用程序每5分钟更新一次后台位置,请执行以下操作:

进入项目的“目标”->功能->后台模式->选择位置更新

我的最后一个过程是通过使用UIApplication:beginBackgroundTaskWithExpirationHandler: 在后台使用NSTimer 当应用程序在后台运行时,此计时器会定期触发。

现在,当您的应用程序在后台运行时,使位置正常工作,并每5分钟将坐标发送到Web服务或对它们执行任何操作即可实现,如下面的代码所示。

AppDelegate.m

//update location
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
 {
     NSLog(@"Location: %f, %f", newLocation.coordinates.longtitude, newLocation.coordinates.latitude);
 }

//run background task
-(voud)runBackgroundTask: (int) time
{
     //check if application is in background mode
     if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) 
     {
          //create UIBackgroundTaskIdentifier and create tackground task, which starts after time
            __block UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
           [app endBackgroundTask:bgTask];
              bgTask = UIBackgroundTaskInvalid;
            }]; 

          dispatch_async(dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

           NSTimer* t = [NSTimer scheduledTimerWithTimeInterval:time target:self selector:@selector(startTrackingBg) userInfo:nil repeats:NO];
          [[NSRunLoop currentRunLoop] addTimer:t forMode:NSDefaultRunLoopMode];
          [[NSRunLoop currentRunLoop] run];

          });
       }
 }

 //starts when application switchs into backghround
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    //check if application status is in background
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) 
    {
        NSLog(@"start backgroun tracking from appdelegate");

        //start updating location with location manager
        [locationManager startUpdatingLocation];
    } 

     //change locationManager status after time
     [self runBackgroundTask:20];
}

 //starts with background task
 -(void)startTrackingBg{
     //write background time remaining
     NSLog(@"backgroundTimeRemaining: %.0f", [[UIApplication sharedApplication] backgroundTimeRemaining]);
     //set default time
     int time = 60;
     //if locationManager is ON
     if (locationStarted == TRUE ) {
         //stop update location
         [locationManager stopUpdatingLocation];
         locationStarted = FALSE;
     }else{
          //start updating location
          [locationManager startUpdatingLocation];
          locationStarted = TRUE;
          //ime how long the application will update your location
          time = 5;
    }
   [self runBackgroundTask:time];
 }

//application switchs back from background
 - (void)applicationWillEnterForeground:(UIApplication *)application
 {
      locationStarted = FALSE;
      //stop updating
      [locationManager stopUpdatingLocation];
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM