当前位置: 动力学知识库 > 问答 > 编程问答 >

ios - How to Compare CurrentLocation to GPS Coordinate and Display a Message if Equal?

问题描述:

I'm trying to create an app that ultimately will vibrate at certain locations. I just started learning Objective-C this week, and found this tutorial which seemed useful for initial testing: http://www.appcoda.com/how-to-get-current-location-iphone-user/

Instead of vibrating, I'm testing it so that the label changes at a designated coordinate. However, when I run the app it does not change the labels. In the bottom debug output bar in xCode it displays the coordinates, and they're the same as what I want them to be, but instead of changing the label "For Latitude Value" to "Success" it changes nothing. Here's the current code:

// ViewController.m

#import "ViewController.h"

@import CoreLocation;

@interface ViewController ()<CLLocationManagerDelegate>

@property (strong, nonatomic) CLLocationManager *locationManager;

@property (strong, nonatomic) CLGeocoder *geocoder;

@property (strong, nonatomic) CLPlacemark *placemark;

@end

@implementation ViewController {

CLLocationManager *locationManager;

}

- (void)requestAlwaysAuthorization{

}

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

locationManager = [[CLLocationManager alloc] init];

if ([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {

[locationManager requestAlwaysAuthorization];

}

}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

{

NSLog(@"%@", [locations lastObject]);

}

- (IBAction)getCurrentLocation:(id)sender {

locationManager.delegate = self;

locationManager.desiredAccuracy = kCLLocationAccuracyBest;

[locationManager startUpdatingLocation];

}

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error

{

NSLog(@"didFailWithError: %@", error);

UIAlertView *errorAlert = [[UIAlertView alloc]

initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];

[errorAlert show];

}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

{

NSLog(@"didUpdateLocations: %@", newLocation);

CLLocation *currentLocation = newLocation;

if ((currentLocation.coordinate.longitude == 51.50998000)&&(currentLocation.coordinate.latitude == -0.13370000)) {

self.longitudeLabel.text = [NSString stringWithFormat:@"success"];

}

}

- (void)didReceiveMemoryWarning {

[super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

@end

And here's the .h if that helps:

// ViewController.h

#import <UIKit/UIKit.h>

#import <AudioToolbox/AudioToolbox.h>

#import <CoreLocation/CoreLocation.h>

@interface ViewController : UIViewController <CLLocationManagerDelegate>

@property (weak, nonatomic) IBOutlet UILabel *latitudeLabel;

@property (weak, nonatomic) IBOutlet UILabel *longitudeLabel;

@property (weak, nonatomic) IBOutlet UILabel *addressLabel;

- (IBAction)getCurrentLocation:(id)sender;

@end

I've also tried it with:

if (currentLocation != nil) {

longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];

latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];

}

like they do in the tutorial where it should change the labels to display the GPS coordinates, but they don't change either. Again, it just shows the GPS coordinates in the debug bar.

Any ideas on why this isn't working? I apologize if this has already been covered somewhere, I've spent a few hours searching for and trying solutions online but since I'm new to this I may not know the right terms to search for. Any advice is greatly appreciated!

网友答案:

I would not recommend comparing two double values for equality. In theory they are never going to be equal. A better approach is to check whether the location is close enough to your reference location. Below an example from my code base. This is from a C file I use with utility functions. Here it handles float values, but you can do the same with double values.

int relativelyClose(CGFloat value, CGFloat reference, CGFloat precision) 
{
    return fabs(value - reference) / reference < range;
}

int relativelyClosePoints(CGPoint point, CGPoint r, CGFloat precision) 
{
    CGFloat dx = point.x -r.x;
    CGFloat dy = point.y-r.y;
    CGFloat distance = sqrt(dx*dx + dy*dy);
    CGFloat reflength = sqrt(r.x*r.x + r.y*r.y);
    return (distance < reflength * precision);
}

Additionally, to ensure that setting the label value is executed on the main thread, you can wrap those calls like this:

dispatch_async(dispatch_get_main_queue(), ^ {
    longitudeLabel.text = ...;
    latitudeLabel.text = ....;
});
分享给朋友:
您可能感兴趣的文章:
随机阅读: