简体   繁体   中英

MKMapView or CLLocationManger - to determine user's current location

There are two classes that help regarding map plotting and determining user location - MKMapView and CLLocationManager .

MKMapView has a delegate “ didUpdateUserLocation ” that tells the user's current location. At the same time, CLLocationManger has a delegate “ didUpdateToLocation ” and it also does the same thing.

My question is when to use MKMapView and CLLocationManager . I am able to get current location of the device from MKMapView then why and when should I use CLLocationManager ? I tried to get it but I am still not sure.

I think you are confusing the MKMapView property showsUserLocation with CLLocationManager .

As a convenience MKMapView's allow you to simply enable a property to show the users current location on the map UI. This is really handy if you only need to show the user where they are on a map.

However, there are demonstrably many other use cases where simply showing location on a map is not enough and this is where CLLocationManager comes in.

Consider for example a running/training application, where a record of user locations is required to calculate running distance, or even an example from one of my own applications, where by I needed to find the users location (lat/long) to calculate distance to various train stations in real time to identify which was closest for the user. In these examples there is no need for a MapView so using a LocationManager is the right choice.

Anytime you need to programmatically interact with the users location and don't require a map UI basically!

I prefer to use CLLocationManager which is used internally by the MKMapView, so if you don't need to use the map, just use the below code from the location manager.

locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.delegate = self;
[locationManager startUpdatingLocation];

Just don't forget to store the locationManager instance somewhere in your class and you can implement the delegate like this.

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog(@"Error detecting location %@", error);
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    CLLocation* location = (CLLocation*)locations.lastObject;
    NSLog(@"Longitude: %f, Latitude: %f", location.coordinate.longitude, location.coordinate.latitude);
}

EDIT

You can get the address of the user based on their location using Apple's Geo coder

// Use Apple's Geocoder to figure the name of the place
    CLGeocoder* geoCoder = [[CLGeocoder alloc] init];
    [geoCoder reverseGeocodeLocation:location completionHandler: ^(NSArray* placemarks, NSError* error) {
        if (error != nil) {
            NSLog(@"Error in geo coder: %@", error);
        }
        else {
            if (placemarks.count == 0) {
                NSLog(@"The address couldn't be found");
            }
            else {
                // Get nearby address
                CLPlacemark* placemark = placemarks[0];

                // Get the string address and store it
                NSString* locatedAt = [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "];
                location.name = locatedAt;

                NSLog(@"The address is: %@", locatedAt);
            }
        }
    }];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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