When I enter the following code and run it on the simulator and set the location to "City Run", it does not log anything. I don't know what I am doing wrong though.
.h
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController <UITextFieldDelegate,CLLocationManagerDelegate> {
CLLocationManager *locMgr;
}
#property (nonatomic, retain) CLLocationManager *locMgr;
#property NSInteger speed;
.m
#synthesize locMgr;
- (void)viewDidLoad {
[super viewDidLoad];
self.locMgr = [[CLLocationManager alloc] init];
self.locMgr.delegate = self;
self.locMgr.desiredAccuracy = kCLLocationAccuracyBest;
[self.locMgr startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
self.speed = roundf([newLocation speed]);
NSLog(#"speed: %ld", (long)self.speed);
}
Do you see anything that I am missing?
Try adding the NSLocationWhenInUseUsageDescription key, to your info.plist
You need to request authorization to use location services using either:
[self.locMgr requestAlwaysAuthorization];
or
[self.locMgr requestWhenInUseAuthorization];
Related
I create a sample project to get user location.
But When I run the app, the location permission not show to me.
What's wrong with my code?
Thanks.
ViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController<CLLocationManagerDelegate>
#property (nonatomic, strong) CLLocationManager *locationManager;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UILabel *latLabel;
#property (weak, nonatomic) IBOutlet UILabel *longLabel;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager.delegate = self;
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager startUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
CLLocation *currentLocation = [locations lastObject];
if(currentLocation != nil){
self.latLabel.text = [NSString stringWithFormat:#"%.2f",currentLocation.coordinate.latitude];
self.longLabel.text = [NSString stringWithFormat:#"%.2f",currentLocation.coordinate.longitude];
[self.locationManager stopUpdatingLocation];
}
}
#end
You need to start by checking locationServicesEnabled. If they are enabled, preceed to call authorizationStatus to learn your app's actual authorization status. You ask for the authorization dialog only if the status is "not determined".
If the status is anything else, there is no point asking for the authorization dialog; it won't appear.
Another problem is that this code is useless:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
CLLocation *currentLocation = [locations lastObject];
if(currentLocation != nil){
self.latLabel.text = [NSString stringWithFormat:#"%.2f",currentLocation.coordinate.latitude];
self.longLabel.text = [NSString stringWithFormat:#"%.2f",currentLocation.coordinate.longitude];
[self.locationManager stopUpdatingLocation];
}
}
You are calling stopUpdatingLocation as soon as you get your first location update. But the chances of your getting a useful location on the first location update are basically nil, because the sensors are just warming up.
(Also please note that it is pointless to check "Location updates" in your background modes. You will not get any location updates in the background unless you set the location manager's allowsBackgroundLocationUpdates to YES, and you are not doing that.)
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 found this good tutorial for develop an app with iBeacon:
http://www.appcoda.com/ios7-programming-ibeacons-tutorial/
But with this implementation, as the author say, if you start the receiver when it's already in the beacon range, it's not going to fire. If you want find an ibeacon you need to walk far away from its region, and then walk back into range.
How can I modify this code to find a beacon that it is in range when I lunch the app?
I use Xcode6, IPad air, IOS 8
This is the simplified code from the tutorial:
in ViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController<CLLocationManagerDelegate>
#property (strong, nonatomic) CLBeaconRegion *myBeaconRegion;
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
In ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:#"ACFD065E-C3C0-11E3-9BBE-1A514932AC01"];
self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
identifier:#"com.appcoda.testregion"];
[self.locationManager startMonitoringForRegion:self.myBeaconRegion];
}
- (void)locationManager:(CLLocationManager*)manager didEnterRegion:(CLRegion *)region
{
NSLog(#"Finding beacons.");
[self.locationManager startRangingBeaconsInRegion:self.myBeaconRegion];
}
-(void)locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion *)region
{
NSLog(#"None found.");
[self.locationManager stopRangingBeaconsInRegion:self.myBeaconRegion];
}
-(void)locationManager:(CLLocationManager*)manager
didRangeBeacons:(NSArray*)beacons
inRegion:(CLBeaconRegion*)region
{
NSLog(#"Beacon found");
}
The didEnterRegion and didExitRegion callbacks only fire when the user crosses the region boundary. In the case of an iBeacon this means moving from "Inside" to "Outside" or vice versa.
When you fire up the app and start monitoring for your beacon region, you can request the current state for your beacon region to determine if your user is inside or outside.
Implement the didDetermineState callback:
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
This callback gets triggered after you start monitoring your region, anytime a region boundary is crossed (so be careful you don't duplicate logic here and inside didEnter/ExitRegion), and in response to a call to requestStateForRegion:
Hope this helps... if you need more -> https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManagerDelegate_Protocol/index.html#//apple_ref/occ/intfm/CLLocationManagerDelegate/locationManager:didDetermineState:forRegion:
I cannot get even the simplest location updating code to work. I have a location app that worked fine for over a year, and now when I try to compile and run it (after upgrading to xcode 6.1 and with no changes to the code), after calling startUpdatingLocation, the didUpdateLocations callback never fires, and I can see that the gps indicator never appears next to the battery indicator as it should.
I have started a new test project that does nothing but attempts to register for location updates, and still the same results: no location updates on device or simulator.
Here is the code for the single view controller of the test project:
//ViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController <CLLocationManagerDelegate>
{
}
#property (strong, nonatomic) CLLocationManager* locationManager;
#end
//ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"got a location");
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"Error: %#",error.description);
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"got a location");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end
It would be fantastic if someone with the latest version of xcode could create a project like this that does nothing but receive location updates, verify that it works, and post the code in full. I have tried adding things to the plist file and all other remedies from similar questions to no avail.
Yes, a few things have changed in the new version and it can be a headache. I was having the same problem and this is the thread that solved it for me here.
You need to add these lines info.plist:
<key>NSLocationWhenInUseUsageDescription</key>
<string>The spirit of stack overflow is coders helping coders</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>I have learned more on stack overflow than anything else</string>
And make sure that you call [CLLocationManager requestWhenInUseAuthorization] or [CLLocationManager requestAlwaysAuthorization] before you try to update the users location.
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.