将 locationManager 在 appDelegate 中获取的坐标传递到 viewController

5

我正在尝试在视图控制器出现时获取用户的坐标。我需要在多个视图控制器中使用此位置,因此将locationManager放在appDelegate中。我的问题是,在第一个viewDidAppear上,坐标尚未被找到。我该如何更改呢?非常感谢大家!!!

我的AppDelegate代码如下:

- (NSString *)getUserCoordinates
{
NSString *userCoordinates = [NSString stringWithFormat:@"latitude: %f longitude: %f", 
locationManager.location.coordinate.latitude,     locationManager.location.coordinate.longitude];
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
return userCoordinates;
}

我的视图控制器通过以下方式获取坐标:

- (void)viewDidAppear 
{
NSString *userCoordinates =[(PDCAppDelegate *)[UIApplication sharedApplication].delegate 
getUserCoordinates];
}
2个回答

7

我最近也实现了相同的功能,即在AppDelegate中使用位置管理器,以便我的所有视图控制器都可以访问位置数据。

不要忘记实现CoreLocation委托方法,特别是didUpdateLocations方法,以便获得新的位置数据。我建议将其放在AppDelegate类中。

由于您有一个对象(AppDelegate)需要通知许多视图控制器有关位置更新的关系,所以我建议使用NSNotification。

在您的AppDelegate中,您将编写...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// set up location manager
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager startUpdatingLocation];
return YES;
}

- (void)locationManager:(CLLocationManager *)manager
 didUpdateLocations:(NSArray *)locations {
CLLocation * newLocation = [locations lastObject];
// post notification that a new location has been found
[[NSNotificationCenter defaultCenter] postNotificationName:@"newLocationNotif"
                                                            object:self
                                                          userInfo:[NSDictionary dictionaryWithObject:newLocation
                                                                                               forKey:@"newLocationResult"]];
}

在您的ViewController中,您将不会使用viewDidAppear方法。相反,您应该这样做...
- (void)viewDidLoad
{
[super viewDidLoad];
// subscribe to location updates
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(updatedLocation:)
                                             name:@"newLocationNotif"
                                           object:nil];
}

您将拥有一个名为updatedLocation的方法,其代码如下:
-(void) updatedLocation:(NSNotification*)notif {
CLLocation* userLocation = (CLLocation*)[[notif userInfo] valueForKey:@"newLocationResult"];
}

您可以将其他视图控制器作为观察者添加,以便订阅通知更新。


非常好!谢谢。 然而,由于监听视图在通知发送后才加载,因此将错过用户的初始位置。我已经在AppDelegate中添加了变量以保留所有视图都可以访问的位置。 - thedp
@thedp你是怎么做到的?能示范一下如何让该变量能够从所有视图中访问吗? - Utku Dalmaz
@UtkuDalmaz 我在AppDelegate中放置了一个CLLocation变量,从其他视图控制器中使用appDelegateInst = (AppDelegate *)[[UIApplication sharedApplication] delegate];。现在您可以访问所有的appDelegate变量,就像全局变量一样。 - thedp

0
你还可以将CLLocation保存为一个字典,包含纬度和经度,并将其存储到用户默认设置中的键路径@"currentUserLocation"下(这只是一个命名示例)。
在你的viewDidLoad中,你可以将控制器设置为键路径的观察者,如下所示:
[[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"currentUserLocation" options:NSKeyValueObservingOptionNew context:NULL];

并实现类似以下的功能:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"currentUserLocation"]) {

    NSUserDefaults *df = [NSUserDefaults standardUserDefaults];
    NSDictionary *dict = [df objectForKey:@"currentUserLocation"];
    NSLog(@"yea we have updated location dict %@", dict);
}

}

这意味着您可以在应用程序中的任何位置更新用户位置,只要您更新了UserDefault(在我的情况下是keyPath @"currentUserLocation"),任何观察者都会收到此更新。我猜这有点像通知中心? :)
对于我的情况,这个解决方案完美地运作了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接