簡體   English   中英

如何將CoreLocation值從一個VIewController傳遞到iOS中的AppDelegate?

[英]how to pass CoreLocation values from one VIewController to AppDelegate in iOS?

我可以在一個ViewController中獲取緯度和經度值。現在我想將這些值傳遞給AppDelegate,在這里我可以使用它們。我不想在AppDelegate中使用Core Location..so這樣的方法就沒有用了。我能實現他的目標嗎?

這是我的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];

有很多方法可以做到這一點,但是最簡單的解決方案是在Application Delegate中添加一個實例變量,然后在您的位置ViewController中獲取對Application Delegate的引用並追溯設置ivar。

但是,我認為以這種方式使用應用程序委托是不好的做法。

在實現推送通知時,我僅向應用程序委托添加了一個實例變量,該實例變量用於存儲設備ID。

創建一個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

使用通知,在該通知中,您從視圖控制器發送通知,並且您的應用程序代理會觀察到該通知。 隨通知一起傳遞位置字符串。

這樣做的好處是,如果您以后決定將位置數據移動到另一個模型類,則只需在其中添加一個觀察者,然后在應用程序委托中停止觀察即可。

如果您要這樣做的原因是利用應用程序委托中的background / foreground委托方法,則可以考慮在視圖控制器中使用這些通知等效項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM