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.
Related
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];
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'm going through the Big Nerd Ranch iOS programming guide and the one of tutorials is telling you how to make an app that simply prints the devices location to the console. I have followed their code exactly and yet I am still getting an error when I run the app. The book that I am using is the previous year's edition so I'm guessing the error has something to do with changes to xcode or something of that sort. The book tells me to write methods for initiating objects in a werid way and I also think it might have something to do with it. Any thoughts on why this simple app doesn't work would be greatly appreciated. Below is my viewcontroller.m and viewcontroller.h files and the error that is printed to console when I run.
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface WhereamiViewController : UIViewController
{
CLLocationManager *locationManager;
}
#end
#import "WhereamiViewController.h"
#implementation WhereamiViewController
- (id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
//Create location manager object
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
//Make location as accurate as possible
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
//Look for location immediately
[locationManager startUpdatingLocation];
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(#"New Location: %#", newLocation);
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
NSLog(#"Could not find location: %#", error);
}
#end
2014-08-16 13:25:22.295 Whereami[2832:60b] Cannot find executable for CFBundle 0x9650af0 </Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/System/Library/AccessibilityBundles/GeoServices.axbundle> (not loaded)
2014-08-16 13:25:22.298 Whereami[2832:60b] Cannot find executable for CFBundle 0x9255180 </Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/System/Library/AccessibilityBundles/CertUIFramework.axbundle> (not loaded)
When this happens while building for the simulator your should Reset Content and Settings and then rebuild.
I am developing an iOS 7 app that uses location. I never get the location updated. If I do the same with startUpdatingLocation it works good. I have read the documentation and I don't know where is the problem.
The location is enabled for the app, and it ask you if you want to enabled it the first time I run the app. Also the location icon in the status bar is not showed.
Update: In the simulator it works, it gives me an updated location. Why it doesn't work in the device?
It's only going to be used in a class, here is the configuration.
#import <CoreLocation/CoreLocation.h>
#interface ClassLocation : UIViewController <CLLocationManagerDelegate>{
}
Setting the property in the .h and in the .m the synthesize
#property (strong, nonatomic) CLLocationManager *localizacionManager;
#synthesize localizacionManager;
ViewDidLoad:
localizacionManager=[[CLLocationManager alloc] init];
[localizacionManager setDelegate:self];
[localizacionManager setDesiredAccuracy:kCLLocationAccuracyKilometer];
[localizacionManager startMonitoringSignificantLocationChanges];
And the two delegate methods:
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(#"error: %#",error.description);
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
NSLog(#"Location updated");
}
Add a key to your Info.plist and request authorization from the location manager asking it to start.
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
You need to request authorization for the corresponding location method.
[self.locationManager requestWhenInUseAuthorization]
[self.locationManager requestAlwaysAuthorization]
The same happens to me in iOS 7. I presume it's due to the last location being cached; if the current location has no significant changes compared to the last one, the delegate never gets called.
You can access the last cached location by using the "location" property of the CLLocationManager :
#property (readonly, nonatomic, copy) CLLocation *location ;
Hope this helps.
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.