如何在iOS中将CoreLocation值从一个VIewController传递到AppDelegate?

时间:2013-11-20 13:13:55

标签: ios core-location

我能够在一个ViewController中获取纬度和经度值。现在我想将这些值传递给AppDelegate,我可以在那里使用它们。我不想在AppDelegate中使用Core Location。那个方法不是用途。我怎样才能实现他的目标?

这是我的Appdelegate代码 -

-(void)updatePresence
{
 NSString *string = self.userLocationVC.locationInfo;// lat and long values as string.
 NSLog(@"value of string in appDelegate - %@", string);  // This shows null.
}

'userLocationVC'是我的ViewController,我计算位置值,'locationInfo'是该控制器的NSString属性,我存储获取的值。

 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
  {
   NSLog(@"didUpdateToLocation: %@", newLocation);
   CLLocation *currentLocation = newLocation;

  if (currentLocation != nil)
  {
    longitude = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
    latitude = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
    self.locationInfo = [NSString stringWithFormat:@"latitude - %@ , longitude - %@",latitude,longitude];
    NSLog(@"current location is - %@", locationInfo);
    AppDelegate *myappDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    [myappDelegate updatePresence];

3 个答案:

答案 0 :(得分:0)

有很多方法可以做到这一点,但最简单的解决方案是将一个实例变量添加到您的Application Delegate,然后在您的位置ViewController获取reference到您的Application Delegate并回顾性地设置ivar

但是我认为以这种方式使用app delegate是不好的做法。

我只有一次向app delegate添加了一个实例变量,那就是在我实现推送通知时存储设备ID。

答案 1 :(得分:0)

创建一个LocationManager单例类来检索您的位置,并在需要时调用它

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

static NSString * const LocationManagerDidGetFirstAccurateLocationNotification = @"LocationManagerDidGetFirstAccurateLocationNotification";

@interface LocationManager : CLLocationManager <CLLocationManagerDelegate>

@property (readonly, nonatomic) CLPlacemark * currentPlacemark;
@property (readonly, nonatomic) CLLocation  * currentLocation;
@property (readonly, nonatomic) NSNumber    * latitude;
@property (readonly, nonatomic) NSNumber    * longitude;

+ (LocationManager *)sharedManager;
- (void)start;

- (double)currentDistanceFromLatitude:(NSNumber *)latitude
                            longitude:(NSNumber *)longitude;

@end




//
//  LocationManager.m
//  Post
//
//  Created by Nicolas Manzini on 26.01.13.
//  Copyright (c) 2013 MySo. All rights reserved.
//

#import "LocationManager.h"

@interface LocationManager ()

@property (assign, nonatomic, getter = isWaitingFirstLocation) BOOL waitingFirstLocation;
@property (strong, nonatomic) NSTimer * timer;
@property (assign, nonatomic, getter = isStarted) BOOL started;

- (void)restartLocationUpdates:(NSTimer *)timer;
- (void)addObservers;
- (void)addTimer;
- (void)updatePlacemarkFromLocation:(CLLocation *)location;

@end

@implementation LocationManager

@dynamic latitude;
@dynamic longitude;

+ (LocationManager *)sharedManager
{
    static dispatch_once_t pred;
    static LocationManager * sharedManager = nil;
    dispatch_once(&pred, ^{
        sharedManager = [[self alloc] init];
    });
    return sharedManager;
}

- (void)start
{
    if (self.isStarted) {return;}

    _currentLocation          = nil;
    self.desiredAccuracy      = kCLLocationAccuracyBest;
    self.distanceFilter       = kCLDistanceFilterNone;
    self.delegate             = self;
    self.started              = YES;
    self.waitingFirstLocation = YES;

    [self startUpdatingLocation];
    [self addObservers];
    [self addTimer];
}

- (void)addObservers
{
    NSNotificationCenter * center = [NSNotificationCenter defaultCenter];

    [center addObserverForName:UIApplicationDidEnterBackgroundNotification
                        object:nil
                         queue:[NSOperationQueue mainQueue]
                    usingBlock:^(NSNotification *note)
    {
        [self stopUpdatingLocation];
        [self.timer invalidate];
         self.timer = nil;

        _currentPlacemark = nil;
        _currentLocation  = nil;
    }];

    [center addObserverForName:UIApplicationWillEnterForegroundNotification
                        object:nil
                         queue:[NSOperationQueue mainQueue]
                    usingBlock:^(NSNotification *note)
    {
        self.waitingFirstLocation = YES;
        [self startUpdatingLocation];
        [self addTimer];
    }];
}

- (void)addTimer
{
    self.timer =
    [NSTimer scheduledTimerWithTimeInterval:300
                                     target:self
                                   selector:@selector(restartLocationUpdates:)
                                   userInfo:nil
                                    repeats:YES];
}

#pragma mark - delegate

- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations
{
    CLLocation * location = [locations lastObject];
    _currentLocation      = location;

    if (location.horizontalAccuracy < 30.0)
    {
        [self stopUpdatingLocation];
        [self updatePlacemarkFromLocation:location];
    }
    else if (location.horizontalAccuracy < 100.0 && self.isWaitingFirstLocation)
    {
        self.waitingFirstLocation = NO;
        [[NSNotificationCenter defaultCenter] postNotificationName:LocationManagerDidGetFirstAccurateLocationNotification
                                                            object:nil];
        [self updatePlacemarkFromLocation:location];

    }
}

#pragma mark - timer

- (void)restartLocationUpdates:(NSTimer *)timer
{
    [self startUpdatingLocation];
}

#pragma mark - NSNumber Coordinates

- (NSNumber *)latitude
{
    return [NSNumber numberWithDouble:self.currentLocation.coordinate.latitude];
}

- (NSNumber *)longitude
{
    return [NSNumber numberWithDouble:self.currentLocation.coordinate.longitude];
}

#pragma mark - Distance From location

- (double)currentDistanceFromLatitude:(NSNumber *)latitude
                            longitude:(NSNumber *)longitude
{
    CLLocation * distantLocation =
    [[CLLocation alloc] initWithLatitude:[latitude doubleValue]
                               longitude:[longitude doubleValue]];
    double meters =
    [self.currentLocation distanceFromLocation:distantLocation];

    return meters;
}

#pragma mark - Placemark Lookup

- (void)updatePlacemarkFromLocation:(CLLocation *)location
{
    [[[CLGeocoder alloc] init] reverseGeocodeLocation:location
                                    completionHandler:^(NSArray *placemark, NSError *error)
     {
         if (error)
         {
             NSLog(@"could not get current geolocation infos %@",error);
         }
         _currentPlacemark = [placemark firstObject];
     }];
}

#pragma mark - dealloc

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end

答案 2 :(得分:0)

使用通知,您可以从视图控制器发送通知,并由您的应用代表观察。将位置字符串与通知一起传递。

这样做的好处是,如果您以后决定将位置数据移动到另一个模型类,那么您只需要在那里添加一个观察者,并停止在app delegate中观察。

如果您要这样做的原因是在app delegate中使用background / foreground委托方法,那么请考虑在视图控制器中使用这些方法的相应通知。