I am implementing the route directions from my current location to some destination location.
When I enter in a specific page, my application crashes. But if I run the app again, it shows the route directions.
I found out the problem is that the first time, current location is showing as 0.00000,0.00000 coordinates. The second time I launch the app, current location is showing up correctly.
What is going wrong?
I want to get my current position correctly at first time.
I am writing the code on below. Once please check it out and let me know the where is the problem in my code
#import "MapWithRoutesViewController.h"
#import "TFSViewController.h"
#implementation MapWithRoutesViewController
#synthesize locationManager,lat,lon;
- (void) updateCurrentLabel {
NSObject *latitude = [NSString stringWithFormat:#"%f", locationManager.location.coordinate.latitude];
NSObject *longitude = [NSString stringWithFormat:#"%f", locationManager.location.coordinate.longitude];
locationlable.text = [NSString stringWithFormat: #"Current Location: %#,%#", latitude, longitude];
}
- (void)viewDidLoad {
[self getCurrentLocation];
[super viewDidLoad];
}
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
[self updateCurrentLabel];
}
-(void) getCurrentLocation {
MapView* mapView = [[[MapView alloc] initWithFrame:
CGRectMake(0, 90, self.view.frame.size.width, self.view.frame.size.height)] autorelease]; [self.view
addSubview:mapView];
Place* home = [[[Place alloc] init] autorelease];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
if (locationManager==NO) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Location Service Disabled"
message:#"To re-enable, please go to Settings and turn on Location Service for
this app."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
} else {
// if (locationManager==NO)
// [mapView.lo addObserver:self forKeyPath:#"location"
// options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
// context:nil];
}
locationManager.pausesLocationUpdatesAutomatically = NO;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[locationManager setPausesLocationUpdatesAutomatically:YES];
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
CLLocation *Loc = [locationManager location];
CLLocationCoordinate2D coordinate = [Loc coordinate];
NSObject *latitude = [NSString stringWithFormat:#"%f", locationManager.location.coordinate.latitude];
NSObject *longitude = [NSString stringWithFormat:#"%f", locationManager.location.coordinate.longitude];
NSLog(#"lat,lon %#%#",latitude,longitude);
home.name = #"";
home.description = #"";
home.latitude = coordinate.latitude;
home.longitude = coordinate.longitude;
Place* office = [[[Place alloc] init] autorelease];
office.name = #"";
office.description = #"";
office.latitude = 22.0000;
office.longitude = 88.0008;
[mapView showRouteFrom:home to:office];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)back:(id)sender{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(IBAction)tfs:(id)sender{
TFSViewController *tfs = [[TFSViewController alloc]initWithNibName:#"TFSViewController" bundle:nil];
[self presentViewController:tfs animated:YES completion:nil];
}
#end
The trouble is you're making the location manager and then expecting it to have a location a few micro seconds later. You should be setting the location manager's delegate and then waiting for it to be called. When LM has a location it will call didUpdateLocation and you can use that to call updateCurrentLabel
You should use delegate method -locationManager:didUpdateLocations: to get the locations. CLLocationManager takes few seconds to establish a GPS connection and determine the current location.
http://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManagerDelegate_Protocol/CLLocationManagerDelegate/CLLocationManagerDelegate.html#//apple_ref/occ/intfm/CLLocationManagerDelegate/locationManager:didUpdateLocations:
You could also use CLLocation's horizontalAccuracy property to check the accuracy of the location to determine if you want to use the value or discard it.
http://developer.apple.com/library/ios/#documentation/CoreLocation/Reference/CLLocation_Class/CLLocation/CLLocation.html#//apple_ref/occ/cl/CLLocation
Related
I have made one demo for getting Current Location.
I have used .GPX file for my current Location.
I have used Delegates method of CLLocation Method.
I have Also use Key "Privacy - Location When In Use Usage Description" in my plist file.
I know this question already asked so many time but could not able to get result.
code is
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface ViewController ()<CLLocationManagerDelegate,MKMapViewDelegate>
#property (nonatomic,assign)CLLocationCoordinate2D cordinateLocation;
#property (nonatomic,strong)MKPointAnnotation *point;
#property (nonatomic,weak)IBOutlet MKMapView *mapView;
#end
#implementation ViewController
CLLocationManager *locationManager;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
locationManager = [[CLLocationManager alloc]init];
locationManager.delegate = self;
self.mapView.delegate = self;
[self updateCurrentLocation];
}
- (void)updateCurrentLocation {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
if ([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[locationManager requestWhenInUseAuthorization];
}
[locationManager startUpdatingLocation];
}
//-(void)getCurrentLocation
//{
// [locationManager requestWhenInUseAuthorization];
// locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// [locationManager startUpdatingHeading];
// [locationManager startUpdatingLocation];
//
//}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
UIAlertController *errorAlert =[UIAlertController alertControllerWithTitle:#"Error" message:#"error reported" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *alertStyle = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil];
[errorAlert addAction:alertStyle];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
CLLocation *updatedLocation = [locations lastObject];
if(updatedLocation != nil)
{
self.cordinateLocation=CLLocationCoordinate2DMake(updatedLocation.coordinate.latitude, updatedLocation.coordinate.longitude);
[manager stopUpdatingLocation];
[self setCurrentLocationFocus];
}
else{
NSLog(#"Can't access desire location");
}
}
-(void)setCurrentLocationFocus{
MKCoordinateRegion region;
region.center = self.cordinateLocation;
//Adjust span as you like
MKCoordinateSpan span;
span.latitudeDelta = 1;
span.longitudeDelta = 1;
region.span = span;
[self.mapView setRegion:region animated:YES];
///Drop the pin on Current Locatio ////
self.point = [[MKPointAnnotation alloc] init];
self.point.coordinate = self.cordinateLocation;
self.point.title = #"FlockStation";
self.point.subtitle = #"It Department";
[self.mapView addAnnotation:self.point];
//set a new camera angle
MKMapCamera *newCamera=[[MKMapCamera alloc] init];
[newCamera setCenterCoordinate:self.cordinateLocation];
[newCamera setPitch:60.0]; ///For zooming purpose///
[newCamera setHeading:90]; ///For Compass Purpose ///
[newCamera setAltitude:100.0]; ///On which height you want to see your map ///
[self.mapView setCamera:newCamera animated:YES];
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
UIStoryboard *mainStoryBoard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *viewController = [mainStoryBoard instantiateViewControllerWithIdentifier:#"NewViewController"];
[self presentViewController:viewController animated:YES completion:nil];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
// self.updatedHeading.text = [NSString stringWithFormat:#"%f",newHeading.magneticHeading];
}
Help Me guys not able to get location.Because delegates method is not calling.
Every Time it called this method.
- (void)locationManager:(CLLocationManager *)manager didFailWithError:`(NSError *)error
You need to check permission of location. then after you can call the delegate methods.
- (void)viewDidLoad {
[super viewDidLoad];
locationManager=[[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
[locationManager requestWhenInUseAuthorization];
}
if ([CLLocationManager locationServicesEnabled]){
NSLog(#"Location Services Enabled");
if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){
alert = [[UIAlertView alloc] initWithTitle:#"Permission Denied"
message:#"To re-enable, please go to Settings and turn on Location Service for this app."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
CLLocation *currentLocation = newLocation;
txtlocations.text = [NSString stringWithFormat:#"%f & %f",currentLocation.coordinate.latitude, currentLocation.coordinate.longitude];
}
Tried with your code with little changes and its working fine.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self updateCurrentLocation];
}
- (void)updateCurrentLocation {
if([CLLocationManager locationServicesEnabled] &&
[CLLocationManager authorizationStatus] != kCLAuthorizationStatusDenied) {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
locationManager.distanceFilter=kCLDistanceFilterNone;
[locationManager requestWhenInUseAuthorization];
[locationManager startMonitoringSignificantLocationChanges];
[locationManager startUpdatingLocation];
// show the map
} else {
// show error
}
}
I have methods in viewDidLoad, and it seems like the order of methods getting called is weird.
- (void)viewDidLoad
{
[super viewDidLoad];
// Get Location
self.locationManager = [[CLLocationManager alloc] init];
self.geocoder = [[CLGeocoder alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
// Retrieve Data
[self retrieveData];
}
After viewDidLoad is called, it calls the retrieveData method before locationManager.
Shouldn't the locationManager be called before retrieveData because of the order?
I am new in Objective C, thank you for your help in advance.
as per your need call your method in inside the delegate methods, so remove the [self retrieveData]; from ViewDidLoad and add into inside the didFailWithError or didUpdateLocations methods.
- (void)viewDidLoad
{
[super viewDidLoad];
// Get Location
self.locationManager = [[CLLocationManager alloc] init];
self.geocoder = [[CLGeocoder alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:#"Error"
message:#"Failed to Get Your Location"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[errorAlert show];
// call here
[self retrieveData];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// set or stop your location update
manager = nil;
[self.locationManager stopUpdatingLocation];
[manager stopUpdatingLocation];
CLLocation *newLocation = locations[[locations count] -1];
CLLocation *currentLocation = newLocation;
NSString *longitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
NSString *latitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
if (currentLocation != nil) {
NSLog(#"latitude: %#", latitude);
NSLog(#"longitude: #"%#", longitude);
}else {
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:#"Error" message:#"Failed to Get Your Location"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[errorAlert show];
}
// call here
[self retrieveData];
}
Note
objective -C is the interpreter , it execute the every in step by step , so or may be your [self retrieveData]; is called in main thread, that is the reason it execute in prior.
Hi i have below code which works fine on iPod touch 5, but same code is not working on iPhone 6, i done research on same issue but i have not found anything useful. both devices have latest iOS.
Both devices have iOS 8
// MapViewController.m
// SidebarDemo
//
// Created by Simon on 30/6/13.
// Copyright (c) 2013 Appcoda. All rights reserved.
//
#import "PetFinderViewController.h"
#import "SWRevealViewController.h"
#interface PetFinderViewController ()
#end
#implementation PetFinderViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithRed:(51/255.0) green:(51/255.0) blue:(51/255.0) alpha:1] ;
self.title = #"Pet Finder";
// Change button color
//_sidebarButton.tintColor = [UIColor colorWithWhite:0.96f alpha:0.2f];
// Set the side bar button action. When it's tapped, it'll show up the sidebar.
_sidebarButton.target = self.revealViewController;
_sidebarButton.action = #selector(revealToggle:);
// Set the gesture
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
// Check if beacon monitoring is available for this device
if (![CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Monitoring not available" message:nil delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil]; [alert show]; return;
}
else
{
// Initialize location manager and set ourselves as the delegate
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Create a NSUUID
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:#"ebefd083-70a2-47c8-9837-e7b5634df524"];
// Setup a new region AND start monitoring
str_beaconIdentifier = #"in.appstute.marketing";
self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:1 minor:1 identifier:str_beaconIdentifier];
self.myBeaconRegion.notifyEntryStateOnDisplay = YES;
self.myBeaconRegion.notifyOnEntry = YES;
self.myBeaconRegion.notifyOnExit = YES;
[self.locationManager startMonitoringForRegion:self.myBeaconRegion];
self.lbl_rangeStatus.text = #"Finding Your Pet";
self.lbl_regionStatus.text = #"";
self.lbl_distance.text = #"";
}
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
if (![CLLocationManager locationServicesEnabled]) {
NSLog(#"Couldn't turn on ranging: Location services are not enabled.");
}
if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized) {
NSLog(#"Couldn't turn on monitoring: Location services not authorised.");
[self.locationManager requestAlwaysAuthorization];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Core Location Delegate methods
- (void)locationManager:(CLLocationManager*)manager didEnterRegion:(CLRegion *)region
{
UILocalNotification *notify = [[UILocalNotification alloc] init];
notify.alertBody = #"You are near your Pet's region.";
notify.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:notify];
// We entered a region, now start looking for our target beacons!
//self.statusLabel.text = #"Finding beacons.";
self.lbl_rangeStatus.text = #"Pet Found";
self.lbl_regionStatus.text = #"Status : Entered Region";
[self.locationManager startRangingBeaconsInRegion:self.myBeaconRegion];
//Opening camera
/*if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.allowsEditing = YES;
//[self presentModalViewController:imagePicker animated:YES];
[self presentViewController:imagePicker animated:YES completion:nil];
}
else
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Camera Unavailable"
message:#"Unable to find a camera on your device."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[alert show];
alert = nil;
}*/
}
-(void)locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion *)region
{
UILocalNotification *notify = [[UILocalNotification alloc] init];
notify.alertBody = #"You are far away from your Pet's region.";
notify.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:notify];
// Exited the region
//self.statusLabel.text = #"None found.";
self.lbl_rangeStatus.text = #"Pet Not Found";
self.lbl_regionStatus.text = #"Status : Exited Region";
[self.locationManager stopRangingBeaconsInRegion:self.myBeaconRegion];
}
-(void)locationManager:(CLLocationManager*)manager didRangeBeacons:(NSArray*)beacons inRegion:(CLBeaconRegion*)region
{
CLBeacon *foundBeacon = [beacons firstObject];
// Retrieve the beacon data from its properties
NSString *uuid = foundBeacon.proximityUUID.UUIDString;
NSString *major = [NSString stringWithFormat:#"%#", foundBeacon.major];
NSString *minor = [NSString stringWithFormat:#"%#", foundBeacon.minor];
NSLog(#"uuid=%#, major=%#, minor=%#",uuid, major, minor);
self.lbl_regionStatus.text = #"Status : Entered Region";
if(foundBeacon.proximity==CLProximityImmediate)
{
NSLog(#"Immediate");
//self.Lb_proxomity.text = #"Immediate";
}
else if (foundBeacon.proximity==CLProximityNear)
{
NSLog(#"Near");
//self.Lb_proxomity.text = #"Near";
}
else if(foundBeacon.proximity==CLProximityFar)
{
NSLog(#"Far");
//self.Lb_proxomity.text = #"Far";
}
else if(foundBeacon.proximity==CLProximityUnknown)
{
NSLog(#"Unknown");
//self.Lb_proxomity.text = #"Unknown";
}
float actualDistance = foundBeacon.accuracy/10;
NSLog(#"Distance = %f",actualDistance);
if(actualDistance >= 0.0)
{
self.lbl_distance.text = [NSString stringWithFormat:#"Distance : %.2f m",actualDistance];
}
//self.Lb_meter.text = [NSString stringWithFormat:#"%.2f",foundBeacon.accuracy];
//self.Lb_centimeter.text = [NSString stringWithFormat:#"%.2f",(foundBeacon.accuracy*100)];
//[self presentExhibitInfoWithMajorValue:foundBeacon.major.integerValue];
//Calling this method to display strength for distance between user and the pet
[self fn_showStrengthForDistanceBetweenUserAndPet:actualDistance];
}
#pragma mark - Check Background App Refresh status
-(BOOL)CanDeviceSupportAppBackgroundRefresh
{
// Override point for customization after application launch.
if ([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusAvailable) {
NSLog(#"Background updates are available for the app.");
return YES;
}else if([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusDenied)
{
NSLog(#"The user explicitly disabled background behavior for this app or for the whole system.");
return NO;
}else if([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusRestricted)
{
NSLog(#"Background updates are unavailable and the user cannot enable them again. For example, this status can occur when parental controls are in effect for the current user.");
return NO;
}
return NO;
}
#pragma mark - Check if monitoring region failed
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
NSLog(#"monitoringDidFailForRegion - error: %#", [error localizedDescription]);
}
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLBeaconRegion *)region{
if (state == CLRegionStateInside) {
//Start Ranging
[manager startRangingBeaconsInRegion:region];
}
else{
//Stop Ranging
[manager stopRangingBeaconsInRegion:region];
}
}
#end
I suspect you are having authorization issues on your iPhone. Set a breakpoint or add NSLog statements to make sure this line is getting called:
[self.locationManager requestAlwaysAuthorization];
Do you get prompted? If not, uninstall and reinstall.
Also, check in setting that Bluetooth and Location services are enabled on the phone, and check settings on your app to see that location services are actually enabled for it.
You need to set one of
NSLocationAlwaysUsageDescription
or
NSLocationWhenInUseUsageDescription when requesting location updates (even with iBeacons).
If you don't, in iOS 8, this will fail silently.
I have a MapViewController that imports SWRevealViewController and I honestly didn't code this lines below. I tried to run the app but unfortunately the map is not showing the current location and even the location service does not get turn on the phone even the app is granted permission to access GPS. Since i'm not a expect in iOS development I need someone to look the code and explain what is missing in this code. I looked at similar question but they seem straight forward even for someone learning objective-c. The problem with this code i assume is the SWRevealViewController imported here, which I think is a library or something i don't know.
#import "MapViewController.h"
#import "SWRevealViewController.h"
// New York
#define NY_LATITUDE 40.754445
#define NY_LONGITUDE -73.977364
// Span and distance
#define SPAN_VALUE 1.0f
#define DISTANCE 500
#interface MapViewController ()
- (void)startLocationServices;
- (void)stopLocationServices;
#end
#implementation MapViewController
#synthesize locationManager;
#synthesize gpsDisplay;
#synthesize mapk;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (IBAction)sendRequest:(id)sender {
[self alertStatus:#"An assistance request has been sent, you will be contacted shortly." :#"Send assistance request" :0];
[self performSegueWithIdentifier:#"sendRequest" sender:nil];
}
- (void) alertStatus:(NSString *)msg :(NSString *)title :(int) tag
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:msg
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil, nil];
alertView.tag = tag;
[alertView show];
}
-(void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex: (NSInteger)buttonIndex
{
if(buttonIndex==0)
{
//NSLog(#"OK Clicked");
// [self alertStatus:#"An assistance request has been sent, you will be contacted shortly. " :#"I just had an accident" :0];
// [self performSegueWithIdentifier:#"checkProgress" sender:nil];
}}
- (void)viewDidLoad
{
[super viewDidLoad];
[self startLocationServices];
if ([CLLocationManager locationServicesEnabled]) {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
} else {
NSLog(#"Location services are not enabled");
}
// Set a timer to stop the Location services
//[NSTimer scheduledTimerWithTimeInterval:100.0 target:self selector:#selector(stopLocationServices) userInfo:nil repeats:NO];
_sidebarButton.tintColor = [UIColor colorWithWhite:0.1f alpha:0.9f];
// Set the side bar button action. When it's tapped, it'll show up the sidebar.
_sidebarButton.target = self.revealViewController;
_sidebarButton.action = #selector(revealToggle:);
// Set the gesture
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
// CLLocationManager *cllocationManager = [[CLLocationManager alloc] init];
// cllocationManager.delegate = self;
// cllocationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
// cllocationManager.distanceFilter = 20.0f;
//
// if ([CLLocationManager locationServicesEnabled])
// {
// [cllocationManager startUpdatingLocation];
// }
// else
// {
// UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Turn On Location Services to find your location"
// message:nil delegate:nil
// cancelButtonTitle:#"OK"
// otherButtonTitles:nil];
// [alert show];
// // [alert release];
// }
}
- (IBAction)mapChanger:(id)sender {
switch (((UISegmentedControl *) sender).selectedSegmentIndex) {
case 0:
self.mapk.mapType = MKMapTypeStandard;
break;
case 1:
self.mapk.mapType = MKMapTypeSatellite;
break;
case 2:
self.mapk.mapType = MKMapTypeHybrid;
break;
default:
break;
}
}
- (void)startLocationServices
{
// create the Location Manager
if (self.locationManager == nil) {
self.locationManager = [CLLocationManager new];
}
// settings
[self.locationManager setDelegate:self];
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
// start services
[self.locationManager startUpdatingLocation];
self.gpsDisplay.text = #"Location Service started.";
}
- (void)stopLocationServices
{
// stop services
[self.locationManager stopUpdatingLocation];
[self.locationManager setDelegate:nil];
self.gpsDisplay.text = #"Location Services stopped.";
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
CLLocationCoordinate2D loc = [userLocation coordinate];
// CLLocationDistance in meters (1 meter = 3.3 feet)
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, DISTANCE, DISTANCE);
[mapView setRegion:region animated:YES];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSString *coords =#"lat";
coords = [coords stringByAppendingString:[NSString stringWithFormat:#"%f", newLocation.coordinate.latitude]];
coords = [coords stringByAppendingString:#"lon"];
coords = [coords stringByAppendingString:[NSString stringWithFormat:#"%f", newLocation.coordinate.longitude]];
self.gpsDisplay.text = coords;
MKCoordinateRegion region;
region.center.latitude = newLocation.coordinate.latitude;
region.center.longitude = newLocation.coordinate.longitude;
region.span.latitudeDelta = SPAN_VALUE;
region.span.longitudeDelta = SPAN_VALUE;
[self.mapk setRegion:region animated:YES];
}
- (void)viewDidUnload {
//[self setUpdates:nil];
[super viewDidUnload];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
In addition to the previous answer, note that you have to specify the reason for accessing the user's location information adding the relative key (NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription) to your project's Info.plist
for example:
<key>NSLocationWhenInUseUsageDescription</key>
<string>Location is required to find out jobs around you are</string>
On iOS 8, they changed how you ask for location permission. Instead of just being able to call startUpdatingLocation you need to now call either requestWhenInUseAuthorization or requestAlwaysAuthorization.
I have location Manager. User can create tasks and pick distinction location. When user come to location - I show local notification. It works for one task. When I have more that one task some strange appear: I receive many notifications. I receive all scheduled notifications.
Question: how can I manage location Manager and push local notifications for different regions? Example: I have three regions - one in Moscow, one in London and one in New York. So, when user come to Moscow I want see only one notification (#"Notification 1"). When in London - notification 2. When in New York - notification 3.
Here my code:
//
// AddTaskViewController.m
// TaskManager
//
// Created by Vladyslav Semenchenko on 2/10/14.
// Copyright (c) 2014 Vladyslav Semenchenko. All rights reserved.
//
#import "AddTaskViewController.h"
#interface AddTaskViewController ()
#end
#implementation AddTaskViewController
#pragma mark - Defaul View life cycle methods
- (void)viewDidLoad
{
[super viewDidLoad];
// Positioning user location to center of mapView
userRegionPosition = MKCoordinateRegionMakeWithDistance([self.mapView userLocation].coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:userRegionPosition] animated:YES];
// Set up delegates
self.textField.delegate = self;
self.mapView.delegate = self;
[self addGestureRecogniserToMapView];
// Add Location Manager
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager stopMonitoringSignificantLocationChanges];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;
NSLog(#"Monitored regions: %#", self.locationManager.monitoredRegions);
}
-(void)viewDidAppear:(BOOL)animated
{
// Positioning user location to center of mapView
userRegionPosition = MKCoordinateRegionMakeWithDistance([self.mapView userLocation].coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:userRegionPosition] animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"createTask"])
{
NSDictionary *newTask = [[NSDictionary alloc] initWithObjectsAndKeys:[self.textField text], #"Task text", nil];
[TasksIO addTasksToFile:newTask];
// Add Location Manager
if (self.enableLocationMonitoring.isOn){
taskRegion = [[CLCircularRegion alloc] initWithCenter:taskPlace.coordinate radius:1 identifier:[self.textField text]];
[self.locationManager startMonitoringForRegion:taskRegion];
}
}
}
#pragma mark - MapView methods
- (void)addGestureRecogniserToMapView{
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(addPinToMap:)];
lpgr.minimumPressDuration = 0.5; //
[self.mapView addGestureRecognizer:lpgr];
}
- (void)addPinToMap:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateBegan)
return;
CGPoint touchPoint = [gestureRecognizer locationInView:self.mapView];
CLLocationCoordinate2D touchMapCoordinate =
[self.mapView convertPoint:touchPoint toCoordinateFromView:self.mapView];
// Add annotation
NSArray *existingAnnotations = self.mapView.annotations;
[self.mapView removeAnnotations:existingAnnotations];
taskPlace = [[MKPointAnnotation alloc]init];
taskPlace.coordinate = touchMapCoordinate;
taskPlace.title = [self.textField text];
longitude = taskPlace.coordinate.longitude;
latitude = taskPlace.coordinate.latitude;
[self.mapView addAnnotation:taskPlace];
}
#pragma mark - TextField delegate methods
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField == self.textField) {
[textField resignFirstResponder];
}
return NO;
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager
didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
if(state == CLRegionStateInside)
{
UILocalNotification* localNotificationInside = [[UILocalNotification alloc] init];
localNotificationInside.fireDate = [NSDate date];
localNotificationInside.alertBody = #"It's time to do some work here!";
localNotificationInside.alertAction = #"Open App to view tasks..";
localNotificationInside.soundName = UILocalNotificationDefaultSoundName;
localNotificationInside.timeZone = [NSTimeZone defaultTimeZone];
localNotificationInside.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotificationInside];
}
else if(state == CLRegionStateOutside)
{
}
else{
}
}
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
/*UILocalNotification* localNotificationInside = [[UILocalNotification alloc] init];
localNotificationInside.fireDate = [NSDate date];
//localNotificationInside.alertBody = #"It's time to do some work here!";
localNotificationInside.alertBody = self.textField.text;
localNotificationInside.alertAction = #"Open App to view tasks..";
localNotificationInside.soundName = UILocalNotificationDefaultSoundName;
localNotificationInside.timeZone = [NSTimeZone defaultTimeZone];
localNotificationInside.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotificationInside];*/
}
#pragma mark - Helpers
-(void) showMessage:(NSString *) message
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Debug info"
message:message
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:Nil, nil];
alertView.alertViewStyle = UIAlertViewStyleDefault;
[alertView show];
}
- (IBAction)clearMonitoredLocations:(id)sender {
for (CLRegion *monitored in [self.locationManager monitoredRegions])
[self.locationManager stopMonitoringForRegion:monitored];
}
#end
Each CLRegion you add to monitor has an identifier, you can use this to identify which region is entered.