【问题标题】:iOS GPS tracking app that runs all the time一直运行的 iOS GPS 跟踪应用程序
【发布时间】:2016-06-01 15:06:41
【问题描述】:

我正在尝试制作一个应用程序来一直跟踪用户 GPS,这个应用程序是一种汽车 GPS 跟踪器,可以一直获取驾驶员的位置并将其发送到服务器。

我尝试将“位置更新”添加到“后台模式”,但应用程序会在进入后台 10 分钟后自动挂起。

有没有办法让这个应用程序一直运行并获取 GPS 位置?

【问题讨论】:

    标签: ios gps core-location


    【解决方案1】:

    您有两种选择:

    1) 常规位置跟踪。
    这种类型的跟踪适用于 kCLAuthorizationStatusAuthorizedWhenInUsekCLAuthorizationStatusAuthorizedAlways 授权。当CLLocationManager 开始跟踪位置时,它将在委托方法locationManager:didUpdateLocations: 中接收位置更新。应用程序可以进入挂起状态,但是当位置管理器收到新位置时,应用程序会进入后台状态并在委托方法中处理新位置。如何设置位置管理器:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.locationManager = [[CLLocationManager alloc] init];
    
        // Setup location tracker accuracy
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    
        // Distance filter
        self.locationManager.distanceFilter = 50.f;
    
        // Assign location tracker delegate
        self.locationManager.delegate = self;
    
        // This setup pauses location manager if location wasn't changed
        [self.locationManager setPausesLocationUpdatesAutomatically:YES];
    
        // For iOS9 we have to call this method if we want to receive location updates in background mode
        if([self.locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)]){
            [self.locationManager setAllowsBackgroundLocationUpdates:YES];
        }
    
        [self.locationManager startUpdatingLocation];
    }
    


    2) 标识位置更改跟踪。
    这种类型的跟踪仅适用于kCLAuthorizationStatusAuthorizedAlways 授权。它仅每 500 米接收新位置,因此距离过滤器和期望精度在这里不起作用。应用程序可以进入挂起状态,甚至可以被系统终止,但是当位置更新时,应用程序进入后台状态并在委托方法locationManager:didUpdateLocations:中接收位置。
    如果应用程序被系统终止,它将在后台重新启动在didFinishLaunchingWithOptions 应用程序委托方法中使用UIApplicationLaunchOptionsLocationKey 键在启动选项中。如何在跟踪中设置此类型:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.locationManager = [[CLLocationManager alloc] init];
    
        // Assign location tracker delegate
        self.locationManager.delegate = self;
    
        // For iOS9 we have to call this method if we want to receive location updates in background mode
        if([self.locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)]){
            [self.locationManager setAllowsBackgroundLocationUpdates:YES];
        }
    
        [self.locationManager startMonitoringSignificantLocationChanges];
    }
    


    您应该注意到,这两种方法都不能保证您的应用程序不会进入挂起状态。
    此外,如果应用程序被用户终止(例如从应用程序切换器通过滑动),后台的位置跟踪将不起作用。


    UPDATE(对应cmets)

    这是适用于我的代码示例:
    For Regular tracking。运行示例,提供对用户位置的访问,点击 Start 按钮开始位置更新。要在模拟器中测试位置,请在模拟器菜单 Debug > Location > Freeway Drive 中选择。现在您可以通过主页按钮 (Command+Shift+H) 将应用程序推到后台。离开模拟器超过 10 分钟,所有这段时间应用程序都会收到位置。当您返回应用程序时,您会在地图上看到红色图钉。
    For Significant changes。以与上一个示例相同的方式运行应用程序并进行测试。
    监控 重大变更只能通过[self.locationManager startMonitoringSignificantLocationChanges];方法启动

    更新(iOS 11)

    iOS 11 中位置跟踪的变化

    iOS 11 还对现有 API 进行了一些重大更改。受影响的领域之一是位置跟踪。 如果您的应用只在应用处于前台时使用位置,就像大多数应用一样,您可能根本不需要更改任何内容;但是,如果它是全天持续跟踪用户位置的应用之一,那么您可能应该在今年夏天预订一些时间来对跟踪和测试可能的使用场景的方式进行一些更改。

    点击此链接:https://mackuba.eu/2017/07/13/changes-to-location-tracking-in-ios-11/

    【讨论】:

    • 感谢您的回答,对于选项1,您说当收到新位置时,状态会从暂停变为后台,我已经测试了几天,这种情况从未发生在我身上,应用程序只有在手动运行应用程序时才能恢复活力,然后在 10 分钟后挂起,为什么???
    • 对于选项 2,有没有办法让 startMonitoringSignificantLocationChanges 以某种方式运行 [self.locationManager startUpdatingLocation]?这将使其至少每 500 米运行一次
    • 为您的 cmets 更新了答案。我没有看到您的代码,因此我在此处为选项 1 和 2 提供了指向我的代码示例的链接。
    • 我已将您的帖子标记为答案,因为您写的正是我正在寻找的内容“您应该注意到这两种方法都不能保证您的应用程序不会进入暂停状态”
    • “应用程序可以进入挂起状态,但是当位置管理器收到新的位置应用程序进入后台状态”这似乎并非如此。我的应用在暂停后停止发送位置更新(通常在几小时/几天后发生)。
    【解决方案2】:

    回复解决方案中的评论 1(我无法在任何地方发表评论):您似乎没有解决问题,因为您的应用程序被暂停并且 10 分钟后不再更新位置。

    我遇到了同样的问题:我将setAllowsBackgroundLocationUpdates 设置为YES,并且我的NSLocationAlwaysUsageDescription 键在我的Info.plist 中,但我的应用程序也曾经在10 分钟后停止跟踪位置。

    我通过将NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription 添加到Info.plist 文件来解决它,所以它看起来像这样:

        <key>NSLocationAlwaysUsageDescription</key>
        <string>This app needs to use your location</string>
    
        <key>NSLocationWhenInUseUsageDescription</key>
        <string>This app needs to use your location</string>
    

    【讨论】:

    • 只要应用程序没有终止,它就会跟踪他们的位置?终止时会发生什么?
    【解决方案3】:

    设置它。它需要电池供电,但您的应用程序在后台运行。OS 不会暂停您的应用程序

    [self.locationManager setPausesLocationUpdatesAutomatically:NO];
    

    【讨论】:

      【解决方案4】:

      我相信这对作者很有用,因为这个问题是在 2016 年 2 月提出的,我在 2019 年 6 月给出了答案。这个答案可能对其他用户有用。

      最近,我正在处理相同的要求。经过2-3周的努力,我做到了。对于其他用户,我为它创建了一个帮助类。可以在 GitHub 中找到。

      请使用HSLocationManager 满足您的要求。我在我的一个项目中达到了同样的要求

      位置管理器,允许每次获取后台位置更新 n 秒,具有所需的位置精度。

      优势:

      • 如果位置管理器当前处于 正在运行。

      • 在需要时定期更新位置(范围在 2 - 170 秒(受允许的最大后台任务时间限制))

      • 可自定义定位精度和时间段。

      • 低内存消耗(单例类)

      【讨论】:

      • 但这不会跟踪处于终止/暂停状态的位置。
      • 它只适用于前台和后台模式(我保证你的应用程序永远不会被操作系统杀死)。众所周知,由于苹果的限制,在 kill 状态下无法进行跟踪。要在终止状态下实现跟踪,您需要实施重要的位置更新。即使通过使用重要的位置更新,在终止状态下也无法继续跟踪。要克服这个限制,您可以使用 Apple PushKit,但这不是一种标准的方法,而且有时您会因此而面临审稿人的拒绝,因此请记住这一点。
      • 你能推荐任何关于 PushKit 的好教程,即使应用程序被终止/暂停也能跟踪位置?
      • 这适用于 iOS:medium.com/ios-expert-series-or-interview-series/…,您还需要后端支持
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-07
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      相关资源
      最近更新 更多