ios CLLocationManager委托方法未被调用

ar7v8xwq  于 12个月前  发布在  iOS
关注(0)|答案(6)|浏览(132)

我使用CLLocationManager类。我有一个简单的类方法来捕获位置

+(void)captureLocation{
    mLocationManager = [[CLLocationManager alloc]init];
    mLocationManager.delegate = (id<CLLocationManagerDelegate>)self;
    mLocationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [mLocationManager startUpdatingLocation];
}

我还有CLLocationManager的委托方法

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation   *)newLocation fromLocation:(CLLocation *)oldLocation
{
}

现在我尝试在我的viewDidLoad中调用这个方法,

- (void)viewDidLoad
{
    [super viewDidLoad];
    [myclass captureLocation];
}

方法被调用,但委托方法没有被调用。
我还有其他类方法,如果我试图再次调用该方法,captureLocation方法会被调用,但委托方法不会被调用。下面是另一个类方法

+(void)initialize{
    [self captureLocation];
}

请帮助我找出为什么委托方法没有得到调用,因为我是新来这个领域。先谢了。

eimct9ow

eimct9ow1#

另外,CoreLocation权限在iOS 8中发生了变化。如果您不请求新的权限授权,CoreLocation不会做任何事情。它会悄悄地失败,因为委托方法从未被调用。
我知道这个问题在2013年被问到,但是如果你有类似的委托方法没有被调用的问题,这篇文章非常有帮助:
http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
虽然这篇文章非常详细和长,但实际的代码修复可以像这样小:

if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
    [locationManager requestWhenInUseAuthorization];
}

您还必须向info.plist添加一个值,这是要在权限警报中显示的消息。见屏幕抓取。

关键字:NS位置IncubationUsageDescription
价值:位置是找到你在哪里所必需的(你可以改变你想要的)

gtlvzcf8

gtlvzcf82#

您正在类方法中设置CLLocationManagerdelegate(即,一个前缀为+而不是-)。所以,当你在这个类方法中引用self时,它就是这个类,而不是这个类的示例。因此,您试图将delegate设置为类,而不是类的示例。
那没用的委托方法是示例方法,而不是类方法。(这大概就是为什么在分配delegate时必须使用CLLocationManagerDelegate强制转换的原因。)
您必须实际示例化已实现CLLocationManagerDelegate方法的任何类。如果你不想把这个示例绑定到一个特定的视图控制器上,你可以使用单例模式。无论如何,您可以设置位置管理器的委托指向该类的示例。
例如,如果你希望它是一个单例:

//  MyClass.h

#import <Foundation/Foundation.h>

@interface MyClass : NSObject

+ (instancetype)sharedManager;
- (void)startCapture;
- (void)stopCapture;

@end

//  MyClass.m

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

@interface MyClass () <CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;

@end

@implementation MyClass

+ (instancetype)sharedManager
{
    static id sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

- (void)startCapture
{
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [self.locationManager startUpdatingLocation];
}

- (void)stopCapture
{
    [self.locationManager stopUpdatingLocation];
    self.locationManager = nil;
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    // ...
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    // ...
}

@end

然后

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[MyClass sharedInstance] startCapture];
}
kxkpmulp

kxkpmulp3#

在+方法中调用self将委托设置为nil,因为它意味着ClassName,就像在[[ClassName alloc] init]中一样。
您需要:
mLocationManager.delegate = mLocationManager
而不是

mLocationManager.delegate (id<CLLocationManagerDelegate>)self;
afdcj2ne

afdcj2ne4#

ios6中,locationManager:didUpdateToLocation:fromLocation:已被弃用,因此您需要在代码中添加另一个方法。

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

      // this method get called in ios7 . 
}
fzsnzjdm

fzsnzjdm5#

在iOS -8中需要做一些更改:
请看一下这个:Get current location in iOS-7 and iOS-8

j91ykkif

j91ykkif6#

另一个原因是没有在带有NSRunLoop的线程上初始化CLLocationManager(如主线程)。这是最好的工作与你的位置经理的主要线程。
从这里的文档:https://developer.apple.com/documentation/corelocation/cllocationmanager?language=objc
Core Location使用初始化CLLocationManager对象所在线程的NSRunLoop调用委托对象的方法。该线程本身必须有一个活动的NSRunLoop,就像在应用的主线程中找到的那样。

相关问题