【问题标题】:Capture location in all states app在所有州应用程序中捕获位置
【发布时间】:2015-11-30 07:48:38
【问题描述】:

我想知道如何在应用程序未运行时捕获位置并保存数据库。已经遵循了几个教程,但没有一个有效。请在重复评分之前,请您阅读完整的问题,因为它不可能。

我尝试了以下教程:

假设我没有捕获位置的实现。我需要每天中午,捕获用户的位置并保存数据库,然后发送到 Web 服务。 无论应用在后台是否处于活动状态(中间按钮上的两个环和拖动),都必须创建此捕获位置。

我尝试了一些在互联网上找到的教程,甚至一些社区建议的教程,但仍然没有奏效。

  • 我添加了背景模式 - 位置。
  • 我允许获取位置requestAlwaysAuthorization

语言可以是objective-c或swift,最重要的是,我学会了如何在应用处于所有状态时捕获这个位置。

【问题讨论】:

  • 要查看您到目前为止所获得的内容以及如何将所有研究组合在一起,请同时显示您的代码。
  • 首先,当应用程序未运行时,无法获取位置。当应用不处于前台模式时,您将需要后台模式来获取位置。
  • 完成最终编辑这是我回答并为我工作的完整代码 ios7 和 ios8 o 在应用程序终止/后台和活动时检索位置详细信息

标签: ios objective-c iphone swift


【解决方案1】:

好的,我将尽可能简单地做到这一点。启用后台模式并勾选后台获取,如下所示

每一步都遵循这个方法

应用终止时

AppDelegate.h

 #import <UIKit/UIKit.h>
 #import <CoreLocation/CoreLocation.h>

 @interface AppDelegate : UIResponder  <UIApplicationDelegate,CLLocationManagerDelegate>

  @property (strong, nonatomic) UIWindow *window;
  @property (strong,nonatomic) CLLocationManager *locationManager;

  @end

AppDelegate.m

#define userDef [NSUserDefaults standardUserDefaults]
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)


#import "AppDelegate.h"
#import <CoreLocation/CoreLocation.h>
#import "AFNetworking.h"
#import <GoogleMaps/GoogleMaps.h>


@implementation AppDelegate{
    BOOL fromTerminated;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{
   fromTerminated = NO;
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {
    fromTerminated = YES;
    self.locationManager = [[CLLocationManager alloc]init];
    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    self.locationManager.activityType = CLActivityTypeOtherNavigation;
    [self.locationManager startUpdatingLocation];
}

    return YES;
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
if(self.locationManager){
    [self.locationManager stopMonitoringSignificantLocationChanges];
    self.locationManager = nil;
    self.locationManager.delegate = nil;

}

self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.locationManager.activityType = CLActivityTypeOtherNavigation;

if(IS_OS_8_OR_LATER) {
    [self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startMonitoringSignificantLocationChanges];
}

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{

NSLog(@"locationManager didUpdateLocations: %@",locations);


if(fromTerminated){

    CLLocation * newLocation = [locations lastObject];
    CLLocationCoordinate2D theLocation = newLocation.coordinate;
    CLLocationAccuracy theAccuracy = newLocation.horizontalAccuracy;

    [userDef setObject:[NSString stringWithFormat:@"%f",theLocation.longitude] forKey:@"LONGITUDE"];
    [userDef setObject:[NSString stringWithFormat:@"%f",theLocation.latitude] forKey:@"LATITUDE"];
    self.myLocation = theLocation;
    self.myLocationAccuracy = theAccuracy;
    [self updateLocation];
   }
}


-(void)updateLocation{
// call your webservice for updating
}

@end

此代码将执行以下操作--> 后台获取将触发位置更改并启动应用程序,didFInishLaunchingWithOptions 将在选项字典中使用 UIApplicationLaunchOptionsLocationKey 调用。如果它发现这意味着应用程序已终止并被唤醒以进行后台提取。现在你有 30 秒左右的时间来做你的事情。因此,您创建一个位置管理器对象并开始更新,这将触发您的 didUpdateLocations 委托方法,然后您可以调用您的方法来触发服务器或数据库中更改的位置。

在您的普通 VC 中创建另一个位置管理器对象,就像您在 didFinishiLaunchingWithOptions 方法中创建的一样,并实现委托方法 didUpdateLocation 这将一直运行,直到应用程序处于前台或后台。应用程序委托方法 hack 将在应用程序终止时触发。

干杯:)

[编辑]

当应用在前台或后台时

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>

@interface ViewController ()<CLLocationManagerDelegate>
@property (nonatomic,strong) CLLocationManager *locationManager;

@end

@implementation ViewController{
}


 -(void)viewDidAppear:(BOOL)animated{
   if(self.locationManager == nil){
    _locationManager = [CLLocationManager new];
   }
    _locationManager.delegate = self;
    _locationManager.distanceFilter = kCLDistanceFilterNone;
    _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0 &&     [CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedWhenInUse) {
    [_locationManager requestAlwaysAuthorization];
    } else {
        [_locationManager startUpdatingLocation];
     }
  }


 - (void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {

    _locationManager = nil;
    CLLocation *location = [locations lastObject];
    theUser.latitude = [NSString stringWithFormat:@"%f",location.coordinate.latitude];
    theUser.longitude = [NSString stringWithFormat:@"%f",location.coordinate.longitude];

   }
}


- (void)locationManager:(CLLocationManager*)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
  {
switch (status) {
    case kCLAuthorizationStatusNotDetermined: {
    } break;
    case kCLAuthorizationStatusDenied: {
    } break;
    case kCLAuthorizationStatusAuthorizedWhenInUse:
    case kCLAuthorizationStatusAuthorizedAlways: {
        [_locationManager startUpdatingLocation]; //Will update location immediately
    } break;
    default:
        break;
   }
}


@end

[编辑]

要检查应用程序是否在终止状态后启动,请执行此更改并点击运行按钮并从情节提要中更改设备的位置

执行此更改,然后运行项目(在设备的调试模式下执行此操作) 并通过此更改位置,然后在applicationDidFinishLaunchingWithOptions 中设置断点,您将看到断点被命中,这意味着应用程序处于终止状态,但此位置更改已触发操作系统启动应用程序。

希望能让你明白

【讨论】:

  • 编辑发布完整状态答案
  • 谢谢,我完全理解了,我会做代码看看能不能用。一个疑问:在背景模式下,只有“后台获取”或“后台获取”和“更新位置”
  • 应用我提到的两个过程来获取所有州的位置更新。
  • 应用程序没有再次“激活”,应用程序终止后位置从未更新
  • 位置将在终止时更新应用程序将不会处于活动状态,但该代码块将被操作系统激活,通过走一点然后检查你的后端来进行测试,我自己检查了这个并通过在模拟器中测试,更改应用程序的方案正在编辑关于如何检查即使应用程序终止的答案
猜你喜欢
  • 2018-03-29
  • 1970-01-01
  • 1970-01-01
  • 2017-04-13
  • 1970-01-01
  • 2019-03-02
  • 2014-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多