Mac 上的 iOS 7 模拟器不适用于自定义位置(也不会请求许可)

Posted

技术标签:

【中文标题】Mac 上的 iOS 7 模拟器不适用于自定义位置(也不会请求许可)【英文标题】:iOS 7 Simulator on Mac doesn't work with custom location (Also doesn't ask permission) 【发布时间】:2014-02-18 16:30:35 【问题描述】:

我正在尝试制作一个使用设备当前位置的 ios7 应用程序。我在我的 Mac 上使用 iPhone 模拟器,但我遇到了一些问题。每次出现位置管理器所在的视图时,它都会打印出 0.000000 的纬度和经度,即使在我设置了自定义位置(从模拟器>调试>位置)之后也是如此。

此外,模拟器在打开应用程序时没有请求使用当前位置的权限似乎很奇怪。有人知道这里发生了什么吗?

- (void)viewDidLoad

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [super viewDidLoad];
    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
    locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
    [locationManager startUpdatingLocation];

    _location = [locationManager location];


    _coord.longitude = _location.coordinate.longitude;
    _coord.latitude = _location.coordinate.latitude;


- (void)viewWillAppear:(BOOL)animated

    [super viewWillAppear:animated];
    _coord.longitude = _location.coordinate.longitude;
    _coord.latitude = _location.coordinate.latitude;
    printf("%f\n",self.coord.longitude);
    printf("%f\n",self.coord.latitude);

【问题讨论】:

Is it possible to get the 'live' current location with an iOS Simulator? 的可能重复项 默认模拟器位置设置为无。因此,您需要转到模拟器菜单 Debug -> Location 并选择苹果的位置之一,或者选择您自己的自定义坐标。您也可以从 Xcode 底部的控制台位置图标中选择一个。在那里您可以选择著名的 ww 地点,如伦敦或莫斯科等。您还可以在方案(编辑方案)中设置默认模拟器位置。 您在 viewDidLoad 方法中调用了两次 [super viewDidLoad] 你需要从委托方法didUpdateLocationToLocation:fromLocation:中获取newLocation。同时实现 didFailWithError 委托方法。 最简单的答案,在实际的 iphone / iPad 上运行您的应用 【参考方案1】:

您需要从委托方法 didUpdateLocationToLocation:fromLocation: 中获取 newLocation。还要实现 didFailWithError 委托方法。您需要一些时间才能开始获取更新的位置,因此需要委托调用。

最后一个位置通常会被缓存,因此检查位置的时间戳并将旧位置过滤掉可能是明智之举。

编辑:

这是我能提供的最简洁的例子。在 Xcode 中启动新项目,选择 Single View 应用程序模板,iPhone。不要触摸故事板,只需用它替换 ViewController.m 的内容并在模拟器或设备中运行。如果在模拟器上,请转到调试并设置一些位置,您将在控制台中获得坐标。当视图打开或关闭屏幕时,我也会开始和停止位置更新。

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>

@interface ViewController () <CLLocationManagerDelegate>

@property (strong, nonatomic) CLLocationManager *locationManager;

@end

@implementation ViewController

#pragma mark - Location Manager delegate methods

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

    if ([newLocation.timestamp timeIntervalSinceNow] >= -300.0) 

        NSLog(@"updated location with latitude %f longitude %f", newLocation.coordinate.longitude, newLocation.coordinate.latitude);
    


- (void)viewWillAppear:(BOOL)animated

    [super viewWillAppear:animated];

    [self.locationManager startUpdatingLocation];


- (void)viewWillDisappear:(BOOL)animated

    [super viewWillDisappear:animated];

    [self.locationManager stopUpdatingLocation];


- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error     
    if(error.code == kCLErrorDenied) 

        // alert user
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Access to location services is disabled"
                                                        message:@"You can turn Location Services on in Settings -> Privacy -> Location Services"
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alertView show];

     else if(error.code == kCLErrorLocationUnknown) 
        NSLog(@"Error: location unknown");
     else 
        NSLog(@"Error retrieving location");
    


#pragma mark - Location Manager getter

- (CLLocationManager *)locationManager

    if (!_locationManager) 
        _locationManager = [[CLLocationManager alloc] init];
        _locationManager.delegate = self;
        _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
        _locationManager.distanceFilter = 60.0;
    
    return _locationManager;


@end

【讨论】:

谢谢!我回家后要试试这个。 当我尝试覆盖 didUpdateToLocation 时,它会发疯并说“方法 'locationManager:didUpdateToLocation:fromLocation' 的重复声明” 这意味着你的类中已经有了方法 didUpdateToLocation:fromLocation。您最初的问题是您试图以错误的方法访问更新位置。 viewWillAppear 在加载所有内容之前调用一次,并且视图将出现在屏幕上。但当时您的 locationManager 还没有发布任何位置更新。在调用 didUpdateToLocation 之前需要几秒钟。要解决您最初的问题,只需将您的位置打印代码移动到 didUpdateToLocation,例如 NSLog(@"%@", newLocation);在 // 在我的例子中做你的事情。 我在整个项目的任何地方都没有使用过 didUpdateToLocation,但它仍然说存在重复声明。 我已经用完整的代码示例更新了我的答案,这是我能提供的最干净的。另请参阅这些有用的教程:http://www.devfright.com/ios-6-core-location-tutorial/ 或 http://www.devfright.com/ios-6-core-location-tutorial/

以上是关于Mac 上的 iOS 7 模拟器不适用于自定义位置(也不会请求许可)的主要内容,如果未能解决你的问题,请参考以下文章

适用于 iOS 8 但不适用于 iOS 7 的简单动画

在 App Purchase 中不适用于 Xcode 5、iOS 7 模拟器

Open in... 自定义文件类型适用于 iOS 5、6 和 7,但不适用于 iOS 4

带有自定义声音的 UILocalNotification 仅适用于 iOS 6.1 和 iOS 7.1,不适用于 iOS 7.0

iOS 7.1 模拟器不适用于 Xcode 7.1

Adobe ANE 适用于 iOS 和 Android 设备,但不适用于 AIR 模拟器