iOs(CoreLocation)-位置管理器:DidUpdateLocation:未按预期工作

iOs(CoreLocation)-位置管理器:DidUpdateLocation:未按预期工作,ios,core-location,Ios,Core Location,我编写了一个简单的iPhone应用程序,可以检索位置信息并简单地显示它们。 我想在每次位置改变时增加distance变量。 我的问题是,在方法locationManager:(CLLocationManager*)manager didUpdateLocations:(NSArray*)locations,locations.count始终等于一。我以为每次调用该方法时都会向数组中添加一个元素,但似乎不是这样 我正在模拟器中运行应用程序(我现在没有设备) 这是我的代码: // BIDViewCo

我编写了一个简单的iPhone应用程序,可以检索位置信息并简单地显示它们。 我想在每次位置改变时增加
distance
变量。 我的问题是,在方法
locationManager:(CLLocationManager*)manager didUpdateLocations:(NSArray*)locations
locations.count
始终等于一。我以为每次调用该方法时都会向数组中添加一个元素,但似乎不是这样

我正在模拟器中运行应用程序(我现在没有设备)

这是我的代码:

// BIDViewController.h

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface BIDViewController : UIViewController <CLLocationManagerDelegate>

@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) CLLocation *startingPoint;

@property (strong, nonatomic) IBOutlet UILabel *latitudeLabel;
@property (strong, nonatomic) IBOutlet UILabel *longitudeLabel;
@property (strong, nonatomic) IBOutlet UILabel *horizontalAccuracyLabel;
@property (strong, nonatomic) IBOutlet UILabel *altitudeLabel;
@property (strong, nonatomic) IBOutlet UILabel *verticalAccuracyLabel;
@property (strong, nonatomic) IBOutlet UILabel *distanceTraveledLabel;

@end



// BIDViewController.m :

#import "BIDViewController.h"

@interface BIDViewController ()

@property (strong, nonatomic)CLLocation *currentLocation;
@property (strong, nonatomic)CLLocation *lastLocation;
@property CLLocationDistance distanceTraveled;

@end

@implementation BIDViewController

@synthesize latitudeLabel;
@synthesize locationManager;
@synthesize longitudeLabel;
@synthesize startingPoint;
@synthesize altitudeLabel;
@synthesize distanceTraveledLabel;
@synthesize horizontalAccuracyLabel;
@synthesize verticalAccuracyLabel;
@synthesize currentLocation;
@synthesize lastLocation;
@synthesize distanceTraveled;

- (void)viewDidLoad
{
    [super viewDidLoad];

    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    //locationManager.distanceFilter = 10.0f;

    [locationManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    if (startingPoint == nil) {
        startingPoint = [locations lastObject];
        NSLog(@"first time -- locations.count = %d", locations.count);
        distanceTraveled = 0;
        distanceTraveledLabel.text = @"0m";
    }
    else if (locations.count > 1) {
        NSLog(@"into the else if -- locations.count = %d", locations.count);
        lastLocation = locations[locations.count -2];
        distanceTraveled = distanceTraveled + [currentLocation distanceFromLocation:lastLocation];
        distanceTraveledLabel.text = [NSString stringWithFormat:@"%gm", distanceTraveled];
    }

    NSLog(@"locations.count = %d", locations.count);

    currentLocation = [locations lastObject];

    latitudeLabel.text =
        [NSString stringWithFormat:@"%g\u00B0", currentLocation.coordinate.latitude];
    longitudeLabel.text =
        [NSString stringWithFormat:@"%g\u00B0", currentLocation.coordinate.longitude];
    horizontalAccuracyLabel.text =
        [NSString stringWithFormat:@"%gm", currentLocation.horizontalAccuracy];
   verticalAccuracyLabel.text =
        [NSString stringWithFormat:@"%gm", currentLocation.verticalAccuracy];
    altitudeLabel.text =
        [NSString stringWithFormat:@"%gm", currentLocation.altitude];

}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSString *errorString = [[NSString alloc] init];

    switch (error.code) {
        case kCLErrorLocationUnknown:
            errorString = @"Location unknown";
            break;

        case kCLErrorDenied:
            errorString = @"Access denied";
            break;

        case kCLErrorNetwork:
            errorString = @"No network coverage";
            break;

        case kCLErrorDeferredAccuracyTooLow:
            errorString = @"Accuracy is too low to display";
            break;

        default:
            break;
    }

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error getting location"
                                                    message:errorString
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alert show];
}

@end
等等


有什么建议吗?谢谢大家,一如既往,为糟糕的英语感到抱歉

模拟器不会返回多个位置,因为它使用计算机的位置,因此您可以获得Wi-Fi的精度,除非您在运行时切换到其他地方的另一个Wi-Fi网络,否则它永远不会返回更高精度/不同的位置

如果您在移动的实际设备上进行测试,或者如果该设备首先为您提供了基站精度,然后是Wi-Fi,然后是GPS精度,那么您将在阵列中接收到多个位置


希望这能澄清问题。

为什么您期望不止一个位置?通常一个就可以了。下面是doc所说的包含位置数据的CLLocation对象数组。此数组始终至少包含一个表示当前位置的对象。如果更新事件被延迟,或者如果多个事件在交付之前到达,则数组可能包含其他条目。数组中的对象按发生顺序组织。因此,最近的位置更新位于阵列的末尾。当然,如果oyu只模拟一个位置,sim不会有帮助。谢谢你的回答;我在问题中没有说,但我正在通过模拟器模拟位置变化(在模拟器中运行我的应用程序时改变模拟位置的值)。。。所以我认为它会触发代理并在数组中添加另一个具有新位置的条目…@aveschini我也面临同样的问题。你找到解决方案了吗?对不起。。。我不再做那个项目了。。。我不记得我是否找到了解决方案,也不记得我是否已经没有了源代码。所以,对不起,我帮不了你!谢谢你的回答;我在问题中没有说,但我正在通过模拟器模拟位置变化(在模拟器中运行我的应用程序时改变模拟位置的值)。。。因此,我认为它会触发委托,并在数组中添加另一个具有新位置的条目……您如何在模拟器中手动触发位置更改?我将重点放在模拟器上:调试->位置->自定义位置。我使用的是意大利版的模拟器,所以它的名称可能会有所不同。当我像你一样使用菜单更改模拟器的位置时,我注意到一些奇怪的行为。似乎新位置在我停止并重新启动模拟器之前不会生效。听起来在模拟器中运行此类测试可能会有问题。
2012-11-21 11:28:34.882 WhereAmI[652:11c03] first time -- locations.count = 1
2012-11-21 11:28:34.897 WhereAmI[652:11c03] locations.count = 1
2012-11-21 11:28:35.835 WhereAmI[652:11c03] locations.count = 1
2012-11-21 11:28:36.835 WhereAmI[652:11c03] locations.count = 1
2012-11-21 11:28:37.836 WhereAmI[652:11c03] locations.count = 1
2012-11-21 11:28:38.836 WhereAmI[652:11c03] locations.count = 1
2012-11-21 11:28:39.837 WhereAmI[652:11c03] locations.count = 1
2012-11-21 11:28:40.837 WhereAmI[652:11c03] locations.count = 1
2012-11-21 11:28:41.838 WhereAmI[652:11c03] locations.count = 1
2012-11-21 11:28:42.839 WhereAmI[652:11c03] locations.count = 1