我一直在iOS 11中的「允許使用」和「始終允許」位置服務遇到問題。 iOS中的問題沒有問題< 11.在嘗試修復時遵循此thread,但仍然無效。我錯過了什麼?先謝謝你。iOS 11 - 添加代理後未收到位置更新
- 我在我的應用程序
UITabViewController
和UINavigationController
每個選項卡內。 - 我有一個singleton LocationManager類。我將我的UINavigationController的RootViewController設置爲委託ViewController的
viewWillAppear
來接收位置更新並在viewWillDisappear
中刪除。 - 現在,當我啓動應用程序時,在創建標籤欄之前,我可以看到LocationManager類中正在調用位置更新。
- 但是,當我添加我的UIViewController作爲委託,並給
startUpdatingLocation
我沒有收到我的UIVIewController中的位置更新。 - 然後我按Home按鈕並退出應用程序。再次立即啓動應用程序,我得到我的委託方法中的位置更新。
我在Info.plist文件中添加了全部三個位置授權說明。
的Info.plist:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Blah Blah Blah</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Blah Blah Blah</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Blah Blah Blah</string>
LocationController.m:
#import "LocationController.h"
//static int LOCATION_ACCESS_DENIED = 1;
//static int LOCATION_NETWORK_ISSUE = 2;
//static int LOCATION_UNKNOWN_ISSUE = 3;
enum {
LOCATION_ACCESS_DENIED = 1,
LOCATION_NETWORK_ISSUE = 2,
LOCATION_UNKNOWN_ISSUE = 3
};
static LocationController* sharedCLDelegate = nil;
@implementation LocationController
int distanceThreshold = 10.0; // in meters
@synthesize locationManager, currentLocation, locationObservers;
- (id)init
{
self = [super init];
if (self != nil) {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = distanceThreshold;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
[self.locationManager startMonitoringSignificantLocationChanges];
self.locationManager.delegate = (id)self;
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization]; //I tried both commenting this line and uncommenting this line. Didn't make any difference
}
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
{
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
[self.locationManager startUpdatingHeading];
locationObservers = [[NSMutableArray alloc] init];
}
return self;
}
#pragma mark -
#pragma mark CLLocationManagerDelegate Methods
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(@"locationManager didUpdateLocations = %@",locations);
CLLocation *newLocation = [locations lastObject];
if (newLocation.horizontalAccuracy < 0) {
return;
}
currentLocation = newLocation;
for(id<LocationControllerDelegate> observer in self.locationObservers) {
if (observer) {
// CLLocation *newLocation = [locations lastObject];
// if (newLocation.horizontalAccuracy < 0) {
// return;
// }
// currentLocation = newLocation;
NSTimeInterval interval = [currentLocation.timestamp timeIntervalSinceNow];
//check against absolute value of the interval
if (fabs(interval)<30) {
[observer locationUpdate:currentLocation];
}
}
}
}
- (void)locationManager:(CLLocationManager*)manager
didFailWithError:(NSError*)error
{
NSLog(@"locationManager didFailWithError: %@", error);
for(id<LocationControllerDelegate> observer in self.locationObservers) {
if (observer) {
[observer failedToGetLocation:error];
}
}
switch (error.code) {
case kCLErrorDenied:
{
break;
}
case kCLErrorNetwork:
{
break;
}
default:
break;
}
}
#pragma mark - Singleton implementation in ARC
+ (LocationController *)sharedLocationInstance
{
static LocationController *sharedLocationControllerInstance = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedLocationControllerInstance = [[self alloc] init];
});
return sharedLocationControllerInstance;
}
-(void) locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
NSLog(@"didChangeAuthorizationStatus = %i",status);
if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse) {
[self.locationManager stopUpdatingLocation];
[self.locationManager startUpdatingLocation];
}
}
- (void) addLocationManagerDelegate:(id<LocationControllerDelegate>)delegate {
if (![self.locationObservers containsObject:delegate]) {
[self.locationObservers addObject:delegate];
}
[self.locationManager startUpdatingLocation];
}
- (void) removeLocationManagerDelegate:(id<LocationControllerDelegate>)delegate {
if ([self.locationObservers containsObject:delegate]) {
[self.locationObservers removeObject:delegate];
}
}
+ (id)allocWithZone:(NSZone *)zone {
@synchronized(self) {
if (sharedCLDelegate == nil) {
sharedCLDelegate = [super allocWithZone:zone];
return sharedCLDelegate; // assignment and return on first allocation
}
}
return nil; // on subsequent allocation attempts return nil
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
#pragma mark UIAlertViewDelegate Methods
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (alertView.tag) {
case LOCATION_ACCESS_DENIED:
{
if (buttonIndex == 1) {
//[[UIApplication sharedApplication] openURL: [NSURL URLWithString: UIApplicationOpenSettingsURLString]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=LOCATION_SERVICES"]];
}
}
break;
case LOCATION_NETWORK_ISSUE:
break;
case LOCATION_UNKNOWN_ISSUE:
break;
default:
break;
}
[alertView dismissWithClickedButtonIndex:buttonIndex animated:YES];
}
@end
LocationController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <Foundation/Foundation.h>
// protocol for sending location updates to another view controller
@protocol LocationControllerDelegate
@required
- (void)locationUpdate:(CLLocation*)location;
- (void)failedToGetLocation:(NSError*)error;
@end
@interface LocationController : NSObject<CLLocationManagerDelegate,UIAlertViewDelegate>
@property (nonatomic, strong) CLLocationManager* locationManager;
@property (nonatomic, strong) CLLocation* currentLocation;
@property (strong, nonatomic) NSMutableArray *locationObservers;
+ (LocationController*)sharedLocationInstance; // Singleton method
- (void) addLocationManagerDelegate:(id<LocationControllerDelegate>) delegate;
- (void) removeLocationManagerDelegate:(id<LocationControllerDelegate>) delegate;
@end
ViewController.m
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"VC viewWillAppear");
[locationControllerInstance addLocationManagerDelegate:self];
}
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[LocationController sharedLocationInstance];
}
我沒有考慮你的問題,但它總是很好看[最新的核心位置WWDC視頻](https://www.google.com/search?q=wwdc + 2017 + +核心位置和OQ = WWDC + 2017 + +核心失水&AQS = chrome.0.0j69i57.3918j0j7&的SourceID =鉻&即= UTF-8)。你有看到它嗎? – Honey
@Honey不,我沒有。正在看。感謝鏈接 – Uma
@Honey我剛看完了。我不認爲還有什麼我錯過了。此外,後臺位置服務不需要,因此不啓用。我想,我沒有啓用它。我的問題不同於「未收到更新」。我收到更新。但我只能在應用程序進入後臺並重新打開之後。 – Uma