可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm trying to use some fancy iBeacons without success, kCLAuthorizationStatusNotDetermined all time.
According to other questions it's a requirement to add those keys to info.plist (some questions says one, other says both). According to an article for iBeacons I need the Always option.
<key>NSLocationWhenInUseUsageDescription</key>
<string>Nothing to say</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Permiso para acceder siempre</string>
At viewDidAppear:
self.locManager = [[CLLocationManager alloc]init];
self.locManager.delegate = self;
[self.locManager requestAlwaysAuthorization];
NSUUID* region1UUID = [[NSUUID alloc]initWithUUIDString:@""]; //ibeacon real UUID between "". Checked it's not nil.
self.beaconRegion = [[CLBeaconRegion alloc]
initWithProximityUUID:proximityUUID
identifier:@"myCoolString"];
self.beaconRegion.notifyEntryStateOnDisplay = YES;
self.beaconRegion.notifyOnEntry = YES;
self.beaconRegion.notifyOnExit = NO;
[self.locManager startMonitoringForRegion:self.beaconRegion];
[self.locManager startRangingBeaconsInRegion:self.beaconRegion];
Icon didn't appear at Settings/Privacy/Location until it was executed one of the two last methods. The Alert View to approve permissions never appears.
If I perform a manual change at Location Settings and check it it will change status but at a few moments later Location at Settings will delete "Always" status for my app and will leave it blank again. Later I check with no luck
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
Any ideas what is missing or wrong? Thank you
回答1:
For iOS 11 developers, you should take a look at this post: Location Services not working in iOS 11.
TL;DR: you need ALL THREE location keys in the Info.plist:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>...</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>...</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>...</string>
Along with InfoPlist.strings
translations in case of multilingual apps.
回答2:
Had exactly the same problem.
It turned out that in my case the NSLocationAlwaysUsageDescription
was required in my InfoPlist.strings
localization files as well. Having NSLocationAlwaysUsageDescription
in Info.plist
wasn't enough...
回答3:
I have noticed that if your instance of CLLocationManager is destroyed before the alert shows, you will never see the alert.
In my case I was creating a local variable of the location manager in the AppDelegate to ask for permission.
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
if ([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[locationManager requestAlwaysAuthorization];
}
Changing the local variable to an instance variable made the alert to display:
@interface AppDelegate () {
CLLocationManager *_locationManager;
}
@end
_locationManager = [[CLLocationManager alloc] init];
if ([_locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[_locationManager requestAlwaysAuthorization];
}
回答4:
Just add this lines to your .plist file
<key>NSLocationAlwaysUsageDescription</key>
<string>Optional message</string>
回答5:
Try to Start Updating Location (have helped for me)
[self.locationManager startUpdatingLocation];
回答6:
Found, documented at forums and tested it's an Objective-C iOS 8 related bug.
Same code written in Swift just works. Working swift code, delegate is call.
Add Core Location framework to
Project Settings / Targets / Capabilities / Background Modes set "Location Updates" and "Uses Bluetooth LE Accessories"
Add key at Info.plist NSLocationAlwaysUsageDescription
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
var locManager: CLLocationManager?
override func viewDidLoad() {
super.viewDidLoad()
self.locManager = CLLocationManager();
self.locManager!.delegate = self;
if (!CLLocationManager.locationServicesEnabled()) {
println("Location services are not enabled");
}
self.locManager!.requestAlwaysAuthorization();
self.locManager!.pausesLocationUpdatesAutomatically = false;
let uuidString = "" // My ibeacon string there
let beaconIdentifier = "myCompany"
let beaconUUID:NSUUID = NSUUID(UUIDString: uuidString)
let beaconRegion:CLBeaconRegion = CLBeaconRegion(proximityUUID: beaconUUID,
identifier: beaconIdentifier)
self.locManager!.startMonitoringForRegion(beaconRegion)
self.locManager!.startRangingBeaconsInRegion(beaconRegion)
self.locManager!.startUpdatingLocation()
}
Dialog appears OK
回答7:
Make sure you add the keys to the correct Info.plist file. Don't forget there's one for your App and one for AppTest.
回答8:
Swift 3.X Latest code easily usage
import CoreLocation
public var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let altitudeG = locations.last?.altitude
let longitudeG = locations.last?.coordinate.longitude
let latitudeG = locations.last?.coordinate.latitude
print("\(altitudeG) \(longitudeG) \(latitudeG)")
}
回答9:
I got a similar problem recently with IOS 11 when I tried to use
locationManager.requestAlwaysAuthorization()
The solution for me was to add all the 4 permissions in plist.info to get the alert:
- Privacy - Location When In Use Usage Description
- Privacy - Location Usage Description
- Privacy - Location Always Usage Description
- Privacy - Location Always and When In Use Usage Description
回答10:
I copied this tutorial ...
http://willd.me/posts/getting-started-with-ibeacon-a-swift-tutorial
It didn't work out the box, although the fix was very simple, don't declare
let locationManager = CLLocationManager()
But move it into the class as variable
var locationManager = CLLocationManager()
And it works!!
回答11:
It will show a prompt when the location permission for your app isn't set and once when 'in use' location permission for your app is set, subsequent calls do not show (and I don't think there is any API feedback that the call was swallowed).
From Apple docs:
Discussion When the current authorization status is notDetermined ,
this method runs asynchronously and prompts the user to grant
permission to the app to use location services. The user prompt
contains the text from the NSLocationAlwaysUsageDescription key in
your app’s Info.plist file, and the presence of that key is required
when calling this method. After the status is determined, the location
manager delivers the results to the delegate’s
locationManager(:didChangeAuthorization:) method. If the current
authorization status is anything other than notDetermined, this method
does nothing and does not call the
locationManager(:didChangeAuthorization:) method, with one exception.
If your app has never requested always authorization and its current
authorization status is authorizedWhenInUse , you may call this
method one time to try and change your app's authorization status to
authorizedAlways .
回答12:
Please check this Reference link
It has described all the changes regarding iOS 11. Your issue is also seems to be one among the cases it described. It might give you an idea what changes you need to make in your code to correct the issue.