loadview ONLY when I get my GPS location - iphone

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.

Related

"StopUpdatingLocation" is called but GPS Arrow doesnt disappear

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.

Alert selection with mapview

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
}
}

Getting Longitude and Latitude Values

I am trying to connect to GPS from my code. I am doing so according to this tutorial.
- (void)viewDidLoad {
[super viewDidLoad];
CLController = [[CoreLocationController alloc] init];
CLController.delegate = self;
[CLController.locMgr startUpdatingLocation];
}
- (void)locationUpdate:(CLLocation *)location {
locLabel.text = [location description];
}
- (void)locationError:(NSError *)error {
locLabel.text = [error description];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
The above code is placed in a view controller called GetMyLocationViewController, and I have another view controller called MainScreenViewController.
When the screen loads, the MainScreenViewController gets loaded, and I will need the GPS location to continue operations with this screen.
In the ViewDidLoad method of MainScreenViewController I wrote the following;
- (void)viewDidLoad {
[super viewDidLoad];
GetMyLocationViewController *getMyLocationViewController = [[GetMyLocationViewController alloc]initwithXib:nil bundle:nil];
[self.navigationController pushViewController:getMyLocationViewController Animation:YES];
// AND THEN I NEED TO ACCESS THE LONGITUDE AND LATITUDE VALUES
}
When the above code gets executed, the viewDidLoad method of MainScreenViewController gets executed, but not the locationUpdate method. The only way I could get the values of longitude and latitude is by the execution of locationUpdate method. So how can I get these values?
Do you tested in a device? xcode before the version 4.2 dont have a GPS simulator, because of that the method locationUpdate never call.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
if([self.delegate conformsToProtocol:#protocol(CoreLocationControllerDelegate)]) { // Check if the class assigning itself as the delegate conforms to our protocol. If not, the message will go nowhere. Not good.
[self.delegate locationUpdate:newLocation];
}
}
Are you sure you are loading your GetMyLocationViewController? Your code only shows loading the MainScreenViewController, which, in its -viewDidLoad method, loads itself again, which would cause an infinite loop of loading and pushing MainScreenViewControllers.
UPDATE: That CoreLocationController class in the tutorial seems unnecessary. Rather that using it, make CLLocationManager a property of your GetMyLocationViewController. Make GetMyLocationViewController's -viewDidLoad method look like this:
-(void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
}
don't forget to import the CoreLocation library and implement the delegate methods.

How do I get CLLLocationManager to return immediately with a location?

I am trying to tweak my CLLocationManager settings so that when I call startUpdatingLocation it calls the delegate right away. Any idea on how to do this?
Thats not possible. The reason is simple, the device has no position fix that matches your desired accuracy the whole time. It might have to turn on the GPS chip to do this which also takes some time to ge a location (without additional infos and an outdated almanac this might take up to 15 minutes in the worst case).
It's not possible to tweak CLLocationManger in that way. However, what you could do is writing a wrapper around CLLocationManager which obtains the current position on startup and returns it everytime you ask for it. However, there might be situations where the location is not (yet) available, and this approach is quite power-consuming as you are using the GPS-device all the time.
This is by far NOT the best way (not even a good way probably) to use a CLLocationManager and when I find the time I am planning on going back and changing my code to only have a single CLLocationManager within my AppDelegate and have all sub view controller call the AppDelegate for their location needs.
I have the following code in a view controller (not the main controller or app delegate either), and about 5-10 seconds after the view controller is pushed by my main views navigation controller, it starts writing to NSLog with an accurate long/lat of my position (i.e. the delegate method locationManager:didUpdateToLocation:fromLocation: starts getting called):
- (void)viewDidLoad {
[super viewDidLoad];
// ....
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager startUpdatingLocation];
// ....
}
// This will be called just a few seconds after the view appears and the
// location is accurate (if I have location services on and good sky-line of sight)
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 5.0) {
self.latitude = [NSNumber numberWithDouble:newLocation.coordinate.latitude];
self.longitude = [NSNumber numberWithDouble:newLocation.coordinate.longitude];
NSLog(#"New Latitude %+.6f, Longitude %+.6f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
}
}
// Then, tear down the location Manager (so I can use it in another view controller)
// A bit excessive possibly, but I like to be absolutely sure that my App does not use the GPS
// when it doesn't need it to save batter life.
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[locationManager stopMonitoringSignificantLocationChanges];
[locationManager stopUpdatingHeading];
[locationManager stopUpdatingLocation];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[locationManager stopMonitoringSignificantLocationChanges];
[locationManager stopUpdatingHeading];
[locationManager stopUpdatingLocation];
}
- (void)viewDidUnload {
[locationManager stopUpdatingLocation];
[locationManager stopMonitoringSignificantLocationChanges];
[locationManager stopUpdatingHeading];
[locationManager setDelegate:nil];
self.locationManager = nil;
}
- (void)dealloc {
// ....
[locationManager stopUpdatingLocation];
[locationManager setDelegate:nil];
[locationManager release], locationManager = nil;
// ....
[super dealloc];
}
Then, in places like actionSheet:clickedButtonAtIndex:, I can get the location values on0demand with locationManager.location.coordinate.latitude / locationManager.location.coordinate.longitude or self.latitude / self.longitude.

iPhone - Initial user location with CCLocationManager

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
}