I am trying to use the Google Maps API but am having trouble getting the user's location. The observed value never seems to change since observeValueForKeyPath is never called.
Note: I am running Xcode6-Beta 5 and iOS8 beta (code is in Swift)
override func viewDidLoad() {
super.viewDidLoad()
var camera:GMSCameraPosition? = nil
mapView_ = GMSMapView.mapWithFrame(CGRectZero, camera:camera);
mapView_!.addObserver(self, forKeyPath: "myLocation", options: NSKeyValueObservingOptions.fromRaw(0x01)!, context: nil);
camera = GMSCameraPosition.cameraWithTarget(mapView_!.myLocation.coordinate, zoom: 6);
mapView_!.camera = camera;
self.view = mapView_;
dispatch_async(dispatch_get_main_queue(), {
mapView_!.myLocationEnabled = true;
});
}
override func observeValueForKeyPath(keyPath: String!, ofObject object: AnyObject!, change: [NSObject : AnyObject]!, context: UnsafeMutablePointer<()>) {
if (keyPath == "myLocation" && object.isKindOfClass(GMSMapView)) {
mapView_!.animateToCameraPosition(GMSCameraPosition.cameraWithTarget(mapView_!.myLocation.coordinate, zoom: 6));
}
}
As of right now, Google Maps iOS SDK hasn't been updated to support iOS 8. So in order to use the location features, you're going to need to do the iOS 8 location authorization yourself.
You can do this by instantiating a CLLocationManager
object and executing either -requestWhenInUseAuthorization
or -requestAlwaysAuthorization
on that. You'll need to do this before setting myLocationEnabled
to YES
.
Be sure to also include the necessary keys in your Info.plist
file. If you are wanting to use always authorization (as in the code example below), provide NSLocationAlwaysUsageDescription
, or if you want when in use authorization, NSLocationWhenInUseUsageDescription
. One of them is required, and if you don't provide it, location features won't work.
Here's an example in Obj-C. Sorry, I'm not up to date with all the Swift stuff yet. :)
// Rather than setting -myLocationEnabled to YES directly,
// call this method:
- (void)enableMyLocation
{
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusNotDetermined)
[self requestLocationAuthorization];
else if (status == kCLAuthorizationStatusDenied || status == kCLAuthorizationStatusRestricted)
return; // we weren't allowed to show the user's location so don't enable
else
[self.view setMyLocationEnabled:YES];
}
// Ask the CLLocationManager for location authorization,
// and be sure to retain the manager somewhere on the class
- (void)requestLocationAuthorization
{
_locationAuthorizationManager = [[CLLocationManager alloc] init];
_locationAuthorizationManager.delegate = self;
[_locationAuthorizationManager requestAlwaysAuthorization];
}
// Handle the authorization callback. This is usually
// called on a background thread so go back to main.
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
if (status != kCLAuthorizationStatusNotDetermined) {
[self performSelectorOnMainThread:@selector(enableMyLocation) withObject:nil waitUntilDone:[NSThread isMainThread]];
_locationAuthorizationManager.delegate = nil;
_locationAuthorizationManager = nil;
}
}
Here is the code for others facing the same issue in iOS swift:
Add Delegates:
GMSMapViewDelegate, CLLocationManagerDelegate
Variables:
@IBOutlet var gmaps: GMSMapView?
var firstLocationUpdate: Bool?
let locationManager = CLLocationManager()
Function:
func startMaps() {
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.startUpdatingLocation()
locationManager.requestWhenInUseAuthorization()
let location: CLLocation = locationManager.location
var target: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
var camera: GMSCameraPosition = GMSCameraPosition(target: target, zoom: 6, bearing: 0, viewingAngle: 0)
if let map = gmaps? {
map.myLocationEnabled = true
map.camera = camera
map.delegate = self
}
}
Hope this will help.
Please don't forget to add this in Info.plist
<key>NSLocationWhenInUseUsageDescription</key>
<true/>
<key>NSLocationAlwaysUsageDescription</key>
<true/>