如何将 CoreLocation 值从一个 VIewController 传递到 iOS 中的 AppDelegate?
Posted
技术标签:
【中文标题】如何将 CoreLocation 值从一个 VIewController 传递到 iOS 中的 AppDelegate?【英文标题】:how to pass CoreLocation values from one VIewController to AppDelegate in iOS? 【发布时间】:2013-11-20 13:13:54 【问题描述】:我能够在一个 ViewController 中获取纬度和经度值。现在我想将这些值传递给我可以使用它们的 AppDelegate。我不想在 AppDelegate 中使用核心位置。所以这种方法不是使用。我怎样才能实现他的?
这是我的 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];
【问题讨论】:
为什么不使用“[myappDelegate updatePresence:self.locationInfo];”? 如果我这样做,我会收到一条错误消息 - 'AppDelegate' 没有可见的@interface 声明选择器'updatePresence'。 为什么不想声明呢? 我被告知要以这种方式实现 :-( 【参考方案1】:使用通知,您从视图控制器发送通知,并由您的应用委托观察。将位置字符串与通知一起传递。
这样做的好处是,如果您稍后决定将位置数据移动到另一个模型类,那么您只需要在那里添加一个观察者,然后在应用委托中停止观察。
如果您想要这样做的原因是在应用程序委托中使用后台/前台委托方法,那么请考虑在您的视图控制器中使用这些等效的通知。
【讨论】:
【参考方案2】:有很多方法可以做到这一点,但最简单的解决方案是向您的 Application Delegate 添加一个实例变量,然后在您的位置 ViewController 中为您的 Application Delegate 获取 reference 并追溯设置 ivar。
但是我认为以这种方式使用应用程序委托是一种不好的做法。
在实现推送通知时,我只向应用委托添加了一次实例变量,即存储设备 ID。
【讨论】:
【参考方案3】:创建一个 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
【讨论】:
这是我的课,你可以复制过去以上是关于如何将 CoreLocation 值从一个 VIewController 传递到 iOS 中的 AppDelegate?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 NsDictionary 值从 tableview 传递到下一个视图