iOS Location permission not work to show by Objective-C - ios

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.)

Related

Measuring the distance between latest coordinates with a fixed one in iOS showing larger distance while they are very near

I am getting inaccurate result while measuring distance between latest coordinate and some a fixed coordinate which can be done by taping on the "Set fixed location" button.
Initially the distance is 0.0 meter as no location is fixed which is the first screenshoot below. Once I tap on the "Set fix location" button, it sets the the coordinate where I am standing at the time of pressing the button and the distance is immediately started calculated which is in the second screenshoot.
When I walk around 10 meters or more and come back to the position where I took the initial fixed location coordinate, its showing me more than 7 meters distance, although it should be less than half meter. I am testing this demo app outside in an open ground.
I have pasted all my code below and could you please help me to fixed the issue? I am new in GPS location related world and please kindly let me know if I am missing anything in the code. Are there any other ways to achieve more accurate result? I have been checking many stack-overflow articles and none help me to improve in my case.
ViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController<CLLocationManagerDelegate>
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (strong, nonatomic) CLLocation *fixedLocation;
#property (strong, nonatomic) CLLocation *latestLocation;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UILabel *fixedLocationLatitude;
#property (weak, nonatomic) IBOutlet UILabel *fixedLocationLongitude;
#property (weak, nonatomic) IBOutlet UILabel *latestLocationLatitude;
#property (weak, nonatomic) IBOutlet UILabel *latestLocationLongitude;
#property (weak, nonatomic) IBOutlet UILabel *distanceBetweenLocations;
- (IBAction)setFixLocation:(UIButton *)sender;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//self.fixedLocation = [[CLLocation alloc] initWithLatitude:90.0 longitude:0.0]; // North pole if no location is fixed for the first time
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
if([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]){
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
if(locations.lastObject!=nil){
self.latestLocation = locations.lastObject;
self.latestLocationLatitude.text = [NSString stringWithFormat:#"%.8f", self.latestLocation.coordinate.latitude];
self.latestLocationLongitude.text = [NSString stringWithFormat:#"%.8f", self.latestLocation.coordinate.longitude];
}
if(self.fixedLocation != nil && self.latestLocation != nil){
CLLocationDistance distanceInMeter = [self.latestLocation distanceFromLocation:self.fixedLocation];
self.distanceBetweenLocations.text = [NSString stringWithFormat:#"%.2f",distanceInMeter] ;
} else {
self.distanceBetweenLocations.text = [NSString stringWithFormat:#"%.f",0.0] ;
}
}
- (IBAction)setFixLocation:(UIButton *)sender {
if(self.locationManager.location != nil){
self.fixedLocation = self.locationManager.location;
self.fixedLocationLatitude.text = [NSString stringWithFormat:#"%.8f", self.fixedLocation.coordinate.latitude];
self.fixedLocationLongitude.text = [NSString stringWithFormat:#"%.8f", self.fixedLocation.coordinate.longitude];
}
}
#end

Core Location not responding

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];

iBeacon not found if it is already in range

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:

NSLog of CLLocation does not print at launch, only when button is pressed

My app display the user's last known/current coordinates in a text label when a button is pressed.
I set up a block of code in my main file to print the user's latitude coordinate to the log, but it does not print anything to the log when I run the app.
Why won't the NSLog print to the console?
Here is the snippet of code that is supposed to be printing the location to the log once the app launches and the user allows the app to access their location:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
CLLocation * currentLocation = [locations lastObject];
NSLog(#"%f", currentLocation.coordinate.latitude);
Below is my full ViewController.h code:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController <CLLocationManagerDelegate>
#property (nonatomic, strong) IBOutlet UILabel * gpsLabel;
#property (nonatomic, strong) CLLocationManager * gpsLM;
-(IBAction)gpsButton;
#end
And here is my full ViewController.m code:
#import "ViewController.h" //This imports the all of the code we have typed in the ViewController.h file.
#import <CoreLocation/CoreLocation.h> //This imports the CoreLocation framework needed for location apps.
//This assigns the Location Manager's delegate to this view controller
#interface ViewController () <CLLocationManagerDelegate>
//This tells the delegate that new location data is available. Manager is the object that updates the event, and the locations object is where the array of location data is stored.
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//This allocates memory for and initializes the gpsLM object we setup in ViewController.h
//This means that we can now use the object and do things with it.
self.gpsLM = [[CLLocationManager alloc]init];
//This calls a startUpdatingLocation method for our CLLocationManager object called gpsLM.
//Because this is all in viewDidLoad, it all gets executed right away as soon as the app is opened.
[self.gpsLM startUpdatingLocation];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//This executes the instance method that we declared above in the header.
//Now we are actually implementing the method and can tell it what we want it to do.
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
//This creates an object called currentLocation and sets it's value to whatever the last value is in the locations array.
//Notice how it is also calling a method of lastObject for the object called locations.
//So remember that you can set variables and objects equal to the result of a method call.
CLLocation * currentLocation = [locations lastObject];
//This prints out text to the debug console that states the latitude coordinate of the user's iPhone.
NSLog(#"%f", currentLocation.coordinate.latitude);
}
-(IBAction)gpsButton{
CLLocation * currentLocation = self.gpsLM.location;
self.gpsLabel.text = [NSString stringWithFormat:#"Your Location is %#", currentLocation];
}
#end
It seems that you forgot to assign the location manager delegate:
self.gpsLM = [[CLLocationManager alloc]init];
self.gpsLM.delegate = self; // <-- ADD THIS
[self.gpsLM startUpdatingLocation];
Without this assignment, the location manager doesn't know what object to give the location update to. The method locationManager:didUpdateLocations: never runs.

objective-c locationManager as delegate, be notified if location changed

I sourced my locationManager out in a own class and file
Now I want to be notified when the location is updated. So I tried to implement the delegation pattern. But for some reason it does not work. What I did:
In Location.h: specified class, protocol, ivar and property id, delegation method
In Location.m: added a call to the delegation method
In ViewController.h: added delegation protocol
In ViewController.m: implemented the delegation method
Build and run the code. But the delegation method in ViewController.m is not called :(
Any ideas what i missed?
Output
2013-07-04 11:55:30.429 Sandbox2[2001:c07] Inside Lokation::getLocation
2013-07-04 11:55:30.443 Sandbox2[2001:c07] Inside Lokation::locationManager
2013-07-04 11:55:30.449 Sandbox2[2001:c07] currentLat: 51.509980 currentLng -0.133700
// Missing NSLog Statement of the delegate method didFindLocation...
ViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
// added Lokation header
#import "Lokation.h"
// added LokationDelegate
#interface ViewController : UIViewController <CLLocationManagerDelegate, LokationDelegate>
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#property (strong, nonatomic) Lokation *lokation;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//[self getLocation];
self.lokation = [[Lokation alloc] init];
self.lokation.delegate = self;
[self.lokation getLocation];
}
// added delegate function of Lokation
// Should be run after the locationmanager found a location
-(void)didFindLocation {
NSLog(#"I am found a lokation and I am now in the ViewController");
}
Lokation.h (20130704 updated to working code)
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
// Added class, protocol and method for the delegate
#class Lokation;
#protocol LokationDelegate <NSObject>
-(void)didFindLocation;
#end
#interface Lokation : NSObject <CLLocationManagerDelegate> {
CLLocationDegrees currentLat;
CLLocationDegrees currentLng;
}
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (nonatomic, strong) CLLocation *currentLoc;
// added delegate property
#property (assign, nonatomic) id<LokationDelegate> delegate;
-(void)getLocation;
#end
Lokation.m (20130704 updated to working code)
#import "Lokation.h"
#implementation Lokation
#synthesize locationManager = _locationManager;
#synthesize currentLoc = _currentLoc;
-(void)getLocation {
NSLog(#"Inside Lokation::getLocation");
// active location determination
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
// We don't want to be notified of small changes in location,
// preferring to use our last cached results, if any.
self.locationManager.distanceFilter = 50;
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(#"Inside Lokation::locationManager");
if (!oldLocation ||
(oldLocation.coordinate.latitude != newLocation.coordinate.latitude &&
oldLocation.coordinate.longitude != newLocation.coordinate.longitude)) {
currentLat = newLocation.coordinate.latitude;
currentLng = newLocation.coordinate.longitude;
} else { // oldLocation
currentLat = oldLocation.coordinate.latitude;
currentLng = oldLocation.coordinate.longitude;
}
self.currentLoc = [[CLLocation alloc] initWithLatitude:currentLat longitude:currentLng];
NSLog(#"currentLat: %f currentLng %f", currentLat, currentLng);
// added call to the delegate function
[self.delegate performSelector:#selector(didFindLocation)];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
NSLog(#"%#", error);
}
Hmm..i think you are doing right but if i do change like below:
remove __unsafe_unretained id<LokationDelegate> delegate; and replace #property (assign, nonatomic) id<LokationDelegate> delegate with #property (retain) id<LokationDelegate> delegate (and synthesize property),it works like charm for me

Resources