简体   繁体   English

从appDelegate中的locationManager传递坐标到viewController

[英]Pass Coordinates from locationManager in appDelegate to viewController

I am trying to get the user's coordinates when a viewController appears. 我想在viewController出现时获取用户的坐标。 I need the location in several viewControllers, so I put the locationManager in the appDelegate. 我需要几个viewControllers中的位置,所以我将locationManager放在appDelegate中。 My problem is that on the very first viewDidAppear, the coordinates have not yet been found. 我的问题是,在第一个viewDidAppear上,尚未找到坐标。 How should I go about changing this? 我该怎么做才能改变这个? Thank you all!!! 谢谢你们!!!

My AppDelegate has this: 我的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;
}

My viewController gets the coordinates with this: 我的viewController获取坐标:

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

I've recently implemented the same thing, location manager in AppDelegate so that my ViewControllers all have access to the location data. 我最近在AppDelegate中实现了同样的东西,位置管理器,以便我的ViewControllers都可以访问位置数据。

Don't forget to implement the CoreLocation delegate methods, particularly didUpdateLocations in order to get the new location data. 不要忘记实现CoreLocation委托方法,特别是didUpdateLocations以获取新的位置数据。 I would put that in AppDelegate class. 我会把它放在AppDelegate类中。

Since, you have a relationship where one object (AppDelegate) needs to notify many viewControllers about a location update, I recommend using NSNotification. 因为,你有一个关系,一个对象(AppDelegate)需要通知许多viewControllers有关位置更新,我建议使用NSNotification。

In your AppDelegate, you would write... 在你的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"]];
}

And in your ViewController, you wouldn't use the viewDidAppear method. 在ViewController中,您不会使用viewDidAppear方法。 Instead, you would do this... 相反,你会这样做......

- (void)viewDidLoad
{
[super viewDidLoad];
// subscribe to location updates
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(updatedLocation:)
                                             name:@"newLocationNotif"
                                           object:nil];
}

and you would have a method updatedLocation that looks like this 你会有一个看起来像这样的方法updatedLocation

-(void) updatedLocation:(NSNotification*)notif {
CLLocation* userLocation = (CLLocation*)[[notif userInfo] valueForKey:@"newLocationResult"];
}

You can have other viewControllers also subscribe to notification updates by adding them as observers. 您可以让其他viewControllers通过将它们添加为观察者来订阅通知更新。

What you also can do is to save the CLLocation as a dictionary with latitude and longitude to the userDefaults under keypath @"currentUserLocation" (just an namingexample). 你还可以做的是将CLLocation保存为具有纬度和经度的字典到keypath @“currentUserLocation”下的userDefaults(只是一个namingexample)。

And in your viewDidLoad you set the controller as a observer to the keypath like this: viewDidLoad您将控制器设置为keypath的观察者,如下所示:

[[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"currentUserLocation" options:NSKeyValueObservingOptionNew context:NULL];

and implement something like: 并实现类似的东西:

-(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);
}

} }

This means that you can update your userlocation wherever you want in your app and as soon as you update the UserDefault (keyPath @"currentUserLocation" in my case) any observer will get this. 这意味着您可以在应用程序中的任何位置更新用户位置,并且一旦更新UserDefault (在我的情况下为keyPath @“currentUserLocation”),任何观察者都会得到此信息。 I guess its kinda like a notificationCenter in a way? 我想它在某种程度上有点像通知中心? :) :)

This solution worked perfectly for my case. 这个解决方案适合我的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM