In my app, I used core location & Mapkit framework with mapview. When wwe install the app,it shows me alert like " would like to use current location" by default without coding for the one time only. And if i select "don't allow", the map view is just shown blue background?? and if i select "ok" then it works fine.
Help me!
my code is follow:
Appdelegate.m
CLLocationManager *locationManager;
CLLocation *userLocation;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
[self createEditableCopyOfDatabaseIfNeeded];
//=========================================Location Manager
if(locationManager == nil)
locationManager =[[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy= kCLLocationAccuracyBest;
self.locationManager.distanceFilter= 5;
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
//==========================================
}
-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
NSLog(#"new location");
self.userLocation=newLocation;
NSLog(#"user llocation %f , %f",userLocation.coordinate.latitude,userLocation.coordinate.longitude);
[self.locationManager startMonitoringSignificantLocationChanges];
}
Mapview.h
{
IBOutlet MKMapView *map;
CLLocation *currentLocation;
NSString *specificLatitude;
NSString *specificLongitude;
MKCoordinateRegion region;
}
Mapview.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[APPDELEGATE.locationManager startUpdatingLocation];
}
- (void)viewWillAppear:(BOOL)animated
{
self.map.delegate = self;
// Ensure that you can view your own location in the map view.
[self.map setShowsUserLocation:YES];
}
-(void)viewDidAppear:(BOOL)animated{
currentLocation =APPDELEGATE.userLocation;
region.center = self.currentLocation.coordinate;
MKCoordinateSpan span;
span.latitudeDelta = 0.05;
span.longitudeDelta = 0.03;
region.span = span;
[map setRegion:region animated:TRUE];
[self searchPressed];
NSLog(#"Mapview %f %f",currentLocation.coordinate.latitude,currentLocation.coordinate.longitude
);
}
If you select "Don't Allow" then call this delegate.
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
//Do something
}
I haven't tried this but maybe you can test to see if it works.
For your view controller that displays your map view, try conforming to the UIAlertViewDelegate.
Then in the alert view delegate callback method, you can do whatever you want, if it works:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
// you need to type the exact title of the alert popup
// button index starts from 0 (left most button), so if the are 2 buttons
// and "Don't allow" button is on the right, the button == 1 is that button
// the user tapped on
if([alertView.title isEqualToString:#"Type Exact Alert Title Here"] && buttonIndex == 1)
{
// do something
}
}
Related
I don´t understand why the gray gps arrow don´t disappear after stopUpdatingLocation is called. Here is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
if (self.locationManager == nil)
{
self.locationManager = [[[CLLocationManager alloc] init]autorelease];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;
}
CLLocation *location = [self.locationManager location];
CLLocationCoordinate2D coordinate = [location coordinate];
g_lat = coordinate.latitude;
g_lng = coordinate.longitude;
[self.locationManager startUpdatingLocation];
}
And here ist my didUpdateLocation:
- (void) locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"Core location has a position.");
CLLocationCoordinate2D coordinate = [newLocation coordinate];
global_lat = coordinate.latitude;
global_lng = coordinate.longitude;
[self.locationManager stopUpdatingLocation];
}
- (void) locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
NSLog(#"Core location can't get a fix.");
}
I also checked if any other app is using GPS!
After 20 minutes the Arrow is still there....
Thanks for help!
EDIT:
I think i missed something very important, on my first view after the App is started there is a Google Map! This is my Code:
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:g_lat
longitude:g_lng
zoom:15];
self.mapView = [GMSMapView mapWithFrame:CGRectMake(1.0f, 160.0f, 320.0f, 100)
camera:camera];
self.mapView.delegate = self;
self.showsUserLocation = YES;
self.mapView.trafficEnabled = YES;
self.mapView.myLocationEnabled = YES;
self.mapView.settings.myLocationButton = YES;
self.mapView.settings.compassButton = YES;
[self.mapView setUserInteractionEnabled:YES];
[self.mapView setCamera:camera];
[self.containerView addSubview:self.mapView];
Is it possible that the google map is updating all the time? If Yes, how can i stop that?
Regarding the google map: do you turn off the myLocationEnabled field when you push the new view controller? If not, then that can keep the GPS running. You can try it by not starting the GPS on the next view controller. If the GPS stays on, then the map is holding it.
Side note: This can be part of the normal operation. If your app stops receiving the location updates, then you are doing fine. iOS is doing lots of optimizations and leaving the GPS on for some time is probably part of this. During testing I saw that the arrow usually stays on for a while even if the app is killed from XCode.
I am having ClLocationManager code in my viewWillAppear. I the same view controller I am having a button which opens a web view. I want to stop location manager IMMEDIATELY, when user taps on button. I am using [locationManager stopUpdating] and locationManager.delegate = nil. From CLLOCATION delegate method I open MFMailComposer sheet.
Problem: Even after clicking on button (which is opening web view), my MailComposerCode executes. How to stop it?
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:animated];
[self setUpProgressBar];
if (webViewButtonClicked == YES)//when user came bck from web view pick up latest coordinates
{
webViewButtonClicked = NO;
[self getLocationCoordinates];
}
else//get latest coordinates from CLLocation manger
{
if (!locationManager) {
locationManager = [[CLLocationManager alloc] init];
}
if (!self.geocoder) {
self.geocoder = [[CLGeocoder alloc] init];
}
locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// When "tracking" the user, the distance filter can be used to control the frequency with which location measurements
// are delivered by the manager. If the change in distance is less than the filter, a location will not be delivered.
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
// Once configured, the location manager must be "started".
[locationManager startUpdatingLocation];
}
}
- (IBAction)goToWEBVIEW
{
NSLog(#"setting to YES");
webViewButtonClicked = YES;
[locationManager stopUpdatingLocation];
locationManager.delegate = nil;
aWebViewController = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:nil];
[self.navigationController aWebViewController animated:NO];
}
CLLocationManager delegate method:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
if (webViewButtonClicked==NO)
{
NSLog(#"1234");
if (!self.sender) {
[self.gpsActivityindicator stopAnimating];
[self stopUpdatingLocation:#""];
self.destinationForProgressView = .25;
[NSThread detachNewThreadSelector:#selector(startTheBackgroundJob) toTarget:self withObject:nil];
**[self openMailComposer];**
}
}
}
So you can see in goToWebView method I am having a flag webViewButtonClicked = YES, but delegate method is called before the user has tapped on web view button. So condition if (webViewButtonClicked==NO) becomes true? How can I stop this scenario?
Thanks.
- (IBAction)goToWEBVIEW
{
[locationManager stopUpdatingLocation];
NSLog(#"setting to YES");
webViewButtonClicked = YES;
[locationManager stopUpdatingLocation];
locationManager.delegate = nil;
aWebViewController = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:nil];
[self.navigationController aWebViewController animated:NO];}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
[locationManager stopUpdatingLocation];
if (webViewButtonClicked==NO)
{
NSLog(#"1234");
if (!self.sender) {
[self.gpsActivityindicator stopAnimating];
[self stopUpdatingLocation:#""];
self.destinationForProgressView = .25;
[NSThread detachNewThreadSelector:#selector(startTheBackgroundJob) toTarget:self withObject:nil];
**[self openMailComposer];**
}
}
}
I'm using that code running on an iPhone 4 :
- (id)init
{
self = [super initWithNibName:#"OfflineView" bundle:nil]; // ok, not perfect but for test, that works fine
if (self) {
self.locationMgr = [[CLLocationManager alloc] init];
self.locationMgr.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
self.locationMgr.distanceFilter = kCLDistanceFilterNone;
self.locationMgr.headingFilter = kCLHeadingFilterNone;
self.locationMgr.delegate = self;
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
// do things
}
// triggered when showing the view, first call here after the init
- (void) start
{
self.view.hidden = NO;
[self.locationMgr startUpdatingLocation];
[self.locationMgr startUpdatingHeading];
}
but the delegate method is not triggered.
It's only triggered when the phone moves.
How may I init my process with a valid user location when the view appears, without asking my user to shake it phone and make a 100m run, before being able to do something ?
You could "prime" it by kicking the delegate method yourself once.
- (void) start
{
self.view.hidden = NO;
[self.locationMgr startUpdatingLocation];
[self.locationMgr startUpdatingHeading];
[self locationManager: self.locationMgr didUpdateToLocation: [self.locationMgr currentLocation] fromLocation: nil];
}
where do you call start:? you should be getting first fix without moving. It's an asynchronous call back so might take time.
Ideally you should be calling startUpdateLocation in the init/viewDidLoad and then read it in locationUpdate:
- (void)locationUpdate:(CLLocation *)location {
// Read location
}
I am struggling with geolocation on simulator, but recently, I have tested it directly on device (iPhone) but the same issue remains, here is what I got when my app finish launching and the code of geolocation suppose to give me my location on the map (remember the picture above is for my app on iPhone and not with the simulator) :
so for my code, my app actually have a lot of views, but concerning this function, I have worked on the appdelegate(.m and .h) and the view concerning of showing the location on the map (PositionActuelleViewController).
appdelegate.m :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
sleep(3);
// Override point for customization after application launch.
self.locationManager=[[[CLLocationManager alloc] init] autorelease];
if([CLLocationManager locationServicesEnabled]) {
self.locationManager.delegate=self;
self.locationManager.distanceFilter=100;
[self.locationManager startUpdatingLocation];
}
// Add the view controller's view to the window and display.
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
and in the same file after the dealloc method :
#pragma mark CLLocationManagerDelegate Methods
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2;
MKCoordinateRegion region;
region.span=span;
region.center=newLocation.coordinate;
[viewCont.mapView setRegion:region animated:YES];
viewCont.mapView.showsUserLocation=YES;
viewCont.latitude.text=[NSString stringWithFormat:#"%f",newLocation.coordinate.latitude];
viewCont.longitude.text=[NSString stringWithFormat:#"%f",newLocation.coordinate.longitude];
}
my PositionActuelleViewController.m file :
#import "PositionActuelleViewController.h"
#implementation PositionActuelleViewController
#synthesize mapView;
#synthesize latitude;
#synthesize longitude;
-(IBAction)goBackToMenu {
[self dismissModalViewControllerAnimated:YES];
}
-(IBAction)goToRechercherView;
{
rechercherViewController.modalTransitionStyle=UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:rechercherViewController animated:YES];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[mapView release];
[latitude release];
[longitude release];
[super dealloc];
}
#end
What am I missing here?
Does the delegate method -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation ever get called? Maybe if you uncomment self.locationManager.distanceFilter=100; it will work because according to docs, distanceFilter property defines the minimum distance (measured in meters) a device must move laterally before an update event is generated.
I have been stuck on this for days, and was wondering if anyone had any clues? Should be simple, but it has me stuck! I get my location, then continue. But I want to stay IN THAT METHOD - LOOPING - until I get a valid location. Then loadview. THANKS for any tips!
I am using the standard:
- (id)init
{
if (self = [super init])
{
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self; // send loc updates to myself
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
}
return self;
}
- (void)viewDidLoad
{
// do my processing here ONLY when I get a valid location***************************
// and if I never get a valid location, then just go to my last location.
}
(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 5.0)
{
[manager stopUpdatingLocation]
printf("latitude %+.6f, longitude %+.6f\n", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
}
}
Rather than spinning in your viewDidLoad, how about putting up a temporary view until you have your GPS location?
// custom full-screen view class of your choice
// could just be a UIImageView if you wanted
SplashOverlay *splash;
- (void)viewDidLoad {
[super viewDidLoad];
splash = [[SplashOverlay alloc] initWithNibName:#"SplashOverlay" bundle:nil];
[self.view addSubview:splash.view];
}
// do this code to get rid of the view
- (void) doneWithSplashScreen {
[splash.view removeFromSuperview];
[splash release];
splash = nil;
}
your view will still be under the splash screen waiting, but nobody can interact with it until you're ready.