捕获所有州应用程序中的位置

Gia*_*ian 4 iphone objective-c ios swift

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

我尝试了以下教程:

假设我没有捕获位置的实现.我需要每天中午,捕获用户的位置并保存数据库,然后发送到Web服务.无论应用程序在后台运行还是未运行(中间按钮上的两个环并拖动),都必须进行此捕获位置.

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

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

语言可以是客观c或快速,最重要的是,我学习如何在所有州的应用程序中捕获此位置.

Sah*_*Roy 5

好的,我将尽可能简单.启用背景模式和勾选背景这样在此输入图像描述

每个步骤都遵循此方法

当应用程序被终止时

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

此代码将执行以下操作 - >后台获取将触发位置更改并将启动应用程序,didFInishLaunchingWithOptions并将UIApplicationLaunchOptionsLocationKey在选项字典中使用a进行调用.如果它发现这意味着应用程序已终止并唤醒后台获取.现在你有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
Run Code Online (Sandbox Code Playgroud)

[编辑]

要检查应用程序是否在终止状态后启动,请执行此更改并点击运行按钮并从故事板中更改设备的位置 在此输入图像描述

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

希望可以让你明白