Currently, I am not able to get my location in the app I am developing.
Basically, in the documentation for Google Maps iOS SDK, Google mentions that you can:
enable the blue "My Location" dot and compass direction by setting
myLocationEnabled on GMSMapView
https://developers.google.com/maps/documentation/ios/map#my_location
However, when I do that, the dot does not appear in my view.
Here's my setup, I have a view controller that contains a view. This view contains three things, two buttons and a map view:
I have linked my mapView with GMSMapView and I can see the map without any problems.
Now, what I would want, is to be located.
I tried two things. First, using a custom, draft button (the i for information), I tried to manually set the location to the mapView but this wasn't working even though the locationServicesEnabled method returned YES.
Then, I tried using GoogleMaps's dot but this isn't working either.
Here's my code:
StudyDisplayViewController.h:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import "GoogleMaps/GoogleMaps.h"
#interface StudyDisplayViewController : UIViewController <CLLocationManagerDelegate> {
}
#property (strong, readwrite) CLLocationManager *locationManager;
#property (weak, nonatomic) IBOutlet GMSMapView *mapView;
#end
StudyDisplayViewController.m
#import "StudyDisplayViewController.h"
#interface StudyDisplayViewController ()
- (IBAction)closeStudyDisplay:(id)sender;
- (IBAction)locateMe:(id)sender;
#end
#implementation StudyDisplayViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
NSLog(#"Starting the location service");
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager startMonitoringSignificantLocationChanges];
if([CLLocationManager locationServicesEnabled]) {
NSLog(#"all good");
}
else {
NSLog(#"Damn son");
}
}
self.mapView.settings.compassButton = YES;
self.mapView.myLocationEnabled = YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
}
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
NSLog(#"Getting Location");
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)closeStudyDisplay:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)locateMe:(id)sender {
NSLog(#"User's location: %#", self.mapView.myLocation);
}
I am using Xcode 6.3.2 and iOS 8.3.
First check out following things are there or not.
locationManager = [[CLLocationManager alloc]init];
locationManager.delegate= self;
if([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]){
[locationManager requestWhenInUseAuthorization];
}
[locationManager startUpdatingLocation];
_mapView.myLocationEnabled = YES;
_mapView.settings.myLocationButton = YES;
If Everything is there and if you are testing on Simulator then try to change the location in Simulator from debug Tab, e.g. change It to Free car run of any of them.
Also, check if you have added Description in PLIST for NSLocationWhenInUseUsageDescription.
Related
I have this code in my file,
#synthesize myLocation;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.locationManager = [[CLLocationManager alloc] init];
myLocation.delegate = self;
[self.locationManager requestWhenInUseAuthorization];
[myLocation setShowsUserLocation: YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.myLocation setRegion:[self.myLocation regionThatFits:region] animated:YES];
}
But, method didUpdateUserLocation not calling.
I already added required frameworks in app.
I added everything in info.plist file. But still it is not calling.
This is my .h file,
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface MapView : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *myLocation;
#property(nonatomic, retain) CLLocationManager *locationManager;
#end
I just solved the problem,
locationManager = [[CLLocationManager alloc] init];
myLocation.delegate = self;
[locationManager requestWhenInUseAuthorization];
[locationManager startUpdatingLocation];
[myLocation setShowsUserLocation: YES];
Use setShowUserLocation with value YES after startUpdatingLocation
You have not called the method to update the location yet so the delegate method is not getting called. You need to call method for startUpdatingLocation.
For Objective - C:
[locationManager startUpdatingLocation];
For Swift:
locationManager.startUpdatingLocation()
Brother I tried your code.The delegate method is not called.
Then I found out the solution you did not add below line at the end of the viewDidLoad method. Please add
[self.locationManager startUpdatingLocation];
After I added above line code in viewDidLoad method,the delegate method called successfully.
I am trying to show my current Location on a MapView. I added a Button to my Storyboard.
First problem: The Current Location is not shown on my screen.
Second problem: The MapView doesn't zoom to the Location if I click on the Button.
My ViewController.m :
(The Button Methods Name are: getLocation )
#import "ViewController.h"
#import CoreLocation;
#interface ViewController () <CLLocationManagerDelegate>
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
#implementation ViewController
#synthesize mapview = _mapview;
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
mapview.showsUserLocation = YES;
[self.locationManager startUpdatingLocation];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)setMap:(id)sender
{
switch (((UISegmentedControl *) sender).selectedSegmentIndex) {
case 0:
mapview.mapType = MKMapTypeStandard;
break;
case 1:
mapview.mapType = MKMapTypeSatellite;
break;
case 2:
mapview.mapType = MKMapTypeHybrid;
break;
default:
break;
}
}
// The sender here are a Button on my Storyboard, who should show the current device Location if i click on it.
-(IBAction)getLocation:(id)sender
{
mapview.showsUserLocation = YES;
//NSLog(#"Koordinaten des Geräts: %#", mapview.userLocation.description );
//[mapview setCenterCoordinate:mapview.userLocation.coordinate animated:YES];
}
#end
pragma mark - CLLocationManagerDelegate Methods
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *newLocation = locations.lastObject;
}
- (void)locationManager: (CLLocationManager *)manager didFailWithError: (NSError *)error
{
}
And for zoom try this
#property (weak, nonatomic) IBOutlet MKMapView *mapAllLocations;
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
mapAllLocations.ZoomEnabled = true;
mapAllLocations.ScrollEnabled = true;
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude =newLocation.latitude;
zoomLocation.longitude=newLocation.longitude;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation,1000.0, 1000.0);
[self.mapAllLocations setRegion:viewRegion animated:YES];
You might be missing NSLocationWhenInUseUsageDescription on your info.plist file and it is required iOS 8 onwards, you can optionally leave its value empty. In the past, one could optionally include a 'NSLocationUsageDescription' key , a string explaining to the user for what the app planning to use location services. And now it has been split up into two separate keys (NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription), and is now mandatory; if you call requestWhenInUseAuthorization or requestAlwaysAuthorization without the corresponding key, the prompt simply won't be shown to the user.
Please bear in mind, if you specify requestAlwaysAuthorization key but your app didn't use the locator always, preferably in the background, then you can face rejection from the apple during app store submission.
I've updated to Xcode 6 (from Xcode 5) and now my app is not working anymore (I was quite proud it worked under IOS7). I have this "famous" debug output:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
Of course I've been googling this message to find a solution but it seems that nothing's working. So I am asking for your advice.
Here is my header file:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#import "MapPoint.h"
#define kGOOGLE_API_KEY #"my google api"
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#interface XYZViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
CLLocationCoordinate2D currentCentre;
int currenDist;
BOOL firstLaunch;
}
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#end
And here is my implementation file:
#import "XYZViewController.h"
#import "DetailViewController.h"
#interface XYZViewController ()
#end
#implementation XYZViewController
-(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//Make this controller the delegate for the map view.
self.mapView.delegate = self;
// Ensure that you can view your own location in the map view.
[self.mapView setShowsUserLocation:YES];
//Instantiate a location object.
locationManager = [[CLLocationManager alloc] init];
//Make this controller the delegate for the location manager.
[locationManager setDelegate:self];
//Set some parameters for the location object.
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
firstLaunch=YES;
}
You need to do as the error description tell you, and add a call to requestWhenInUseAuthorization or requestAlwaysAuthorization. This has been covered before, ie. iOS alertview for location permission doesn't pop up
The required changes could look like this:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//Make this controller the delegate for the map view.
self.mapView.delegate = self;
//Instantiate a location object.
locationManager = [[CLLocationManager alloc] init];
//Make this controller the delegate for the location manager.
[locationManager setDelegate:self];
//Set some parameters for the location object.
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
// Request use on iOS 8
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
// Ensure that you can view your own location in the map view.
[self.mapView setShowsUserLocation:YES];
} else {
[locationManager requestWhenInUseAuthorization];
}
firstLaunch=YES;
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
// Ensure that you can view your own location in the map view.
[self.mapView setShowsUserLocation:YES];
}
}
The above code do a version check (in the apple recommended way), you could also do a feature check, which is cleaner, but sometime cause problems in my own experience.
The tricky part is you need to provide a description of your use in the app Info.plist. Else the UIAlert will not appear and you will not be given permission. Go to the project/target settings in xcode, click the "Info" tab. Click the + button. For the key enter NSLocationWhenInUseUsageDescription and the value should be a string describing how you will use the user's location. You can also open the 'Info.plist' file under 'Supporting Files'.
I suspect this is why it hasn't worked for you yet.
I am having a really weird problem here. I am trying to build an app to detect beacons. I don't have any real beacons yet so I am testing with an iPhone 5 and an iPad 3. The strange thing is that the transmitting is only working on the iPad, the iPhone doesn't work as a transmitter even though I used the same app on it.
But even with the iPad as a transmitter, the app only works sometimes - sometimes the iPhone will notify me that it has found a beacon, sometimes it doesn't. I've force-closed the app on the iPad and after the restart it worked, but then another time it doesn't.
Since everything is working sporadically I think it can't be the code causing that behaviour, but it might be - I am not an experienced coder, I've just started this. My code is based on this tutorial http://www.devfright.com/ibeacons-tutorial-ios-7-clbeaconregion-clbeacon/
I first thought this might be the answer, but taht didn't solve it: it still did work sometimes, and sometimes it didn't.
Can anybody tell me what I am dealing with her?
Here is my code for the Tracker:
ladBeaconTracker.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#interface ladBeaconTracker : UIViewController <CLLocationManagerDelegate>
#property (strong, nonatomic) CLBeaconRegion *beaconRegion;
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (weak, nonatomic) IBOutlet UILabel *beaconFoundLabel;
#end
ladBeaconTracker.m
#import "ladBeaconTracker.h"
#interface ladBeaconTracker ()
#property NSUUID *uuid;
#end
#implementation ladBeaconTracker
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self initRegion];
}
- (void)initRegion {
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:#"A5456D78-C85B-44C6-9F20-8268FD25EF8A"];
self.beaconRegion = [[CLBeaconRegion alloc]initWithProximityUUID:uuid identifier:#"Museum"];
[self.locationManager startMonitoringForRegion:self.beaconRegion];
NSLog(#"Region %# initated", _beaconRegion.identifier);
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
self.beaconRegion.notifyEntryStateOnDisplay = YES;
NSLog(#"Region %# entered", _beaconRegion.identifier);
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
NSLog(#"Region %# exit", _beaconRegion.identifier);
}
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region{
CLBeacon *beacon = [[CLBeacon alloc] init];
beacon= [beacons lastObject];
self.beaconFoundLabel.text =#"Yes";
NSLog(#"Ranged Region %#", _beaconRegion.identifier );
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
And this is the transmitter-Code:
configViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#interface ConfigViewController : UIViewController <CBPeripheralManagerDelegate>
#property (strong,nonatomic) CLBeaconRegion *beaconRegion;
#property(strong,nonatomic) NSDictionary *beaconPeripheralData;
#property (strong, nonatomic) CBPeripheralManager *PeripheralManager;
#end
ConfigViewController.m
#import "ConfigViewController.h"
#interface ConfigViewController ()
#end
#implementation ConfigViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self initBeacon];
}
- (void) peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
if (peripheral.state == CBPeripheralManagerStatePoweredOn) {
NSLog(#"Powered ON");
[self.PeripheralManager startAdvertising:self.beaconPeripheralData];
}
else if (peripheral.state == CBPeripheralManagerStatePoweredOff){
NSLog(#"Powered OFF");
[self.PeripheralManager stopAdvertising];
}
}
- (void)initBeacon {
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:#"A5456D78-C85B-44C6-9F20-8268FD25EF8A"];
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
major:1
minor:1
identifier:#"Museum"];
}
- (IBAction)transmitBeacon:(UIButton *)sender {
self.beaconPeripheralData = [self.beaconRegion peripheralDataWithMeasuredPower:nil];
self.PeripheralManager = [[CBPeripheralManager alloc]initWithDelegate:self queue:nil options:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Your code looks fine for detecting beacons in the background. Two suggestions:
I suspect the problem when the iPad is transmitting is not with the iPad but that the iPhone cannot receive. Try cycling power to the iPhone tto clear a known bug in iOS 7.1.
iOS can detect iBeacons much more quickly in the foreground if you set up ranging at the same time you set up monitoring. Move [self.locationManager startRangingBeaconsInRegion:self.beaconRegion]; into initRegion and take out stopRangingBeaconsInRegion entirely.
Once you have done (2), repeat your tests in the foreground and look for your log statement Ranged Region. You should see this every second when the beacon is on.
In the background, know that it can take up to 15 minutes to both detect an iBeacon and detect that an iBeacon is no longer around. Again, watch your log lines for hints about the current state, and know that you cannot get a new region entry event until you first get a region exit event or reboot your phone.
I'm following this tutorial for creating a program that shows the location of a user. I've told Xcode to simulate a location for me already, and even on the simulator made sure it was allowing my application to keep track of locations. However, nothing is being logged to my console.
The header file:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface WhereamiViewController : UIViewController <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
}
#end
And the main file:
#import "WhereamiViewController.h"
#implementation WhereamiViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager setPausesLocationUpdatesAutomatically:NO];
[locationManager startUpdatingLocation];
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
NSLog(#"%#", [locations lastObject]);
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
NSLog(#"Error: %#", error);
}
#end
I am not 100% sure about the answer but this is what i have got.
iOS 7 allows location fetch only when app is in foreground.
When you write your code in initwithNibName, your app is not actually in foreground it is creating controls from xib files and all.That is why OS is not giving you the location updates.