Does CLLocationManager work without internet/cellular connection? - iphone

Silly question !! Though I want to know that is it possible that CLLocationManager works without Internet ?????
i.e. iPhone is not connected to internet at all

iPhoneiPadDev's answer is slightly wrong: whilst sometimes the location manager will fail, it can work without network connectivity. If you want to see this for yourself, go for a drive somewhere with terrible or nonexistent cellular reception: GPS will still work.
It very much depends on the environmental conditions around you, and the device you're using. iPod Touches and some iPads don't have GPS, and rely on WiFi hotspots to determine their location data. If you don't have network access the CLLocationManager will return an invalid location.
iPhones and 3G iPads do have GPS, so you may get an appropriate location returned. However, they use A-GPS (assisted GPS), which uses information from the network to allow a faster GPS lock. If you don't have internet connectivity it may take some time for the GPS chip to obtain a signal and provide an accurate location: and accuracy may be wildly off, if you're indoors or don't have plain sight of the sky.
Important point: CLLocationManager can and will return you locations even if none are available: the coordinates, however, will be invalid. It's important to test the locations being returned and make sure you're satisfied they are correct before using them.

Yeah it works if Location Services are enabled in the device settings. No need for Internet connection.

Yes but in open sky(Means on road, ground).
If you are online, you will get location coordinate from wifi, mobile data then if you switch off internet and change your location(Away from that location), Say you are now in building(3rd floor) then you won't get correct location update instead you will get cache coordinates.
To fix this:
Record timestamp(Say "RecordDate") in offline mode when you want location then compare timestamp given by didUpdateToLocations: method.
if didUpdateToLocations's timestamp > Recorded Timestamp then use it
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations
{
CLLocation *currentLocation = [locations lastObject];
NSLog(#"didUpdateToLocation: %#", currentLocation);
NSDate *eventDate=[[NSUserDefaults standardUserDefaults] objectForKey:#"RecordDate"];
NSComparisonResult result = [currentLocation.timestamp compare:eventDate];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd HH:mm:ss z"];
switch (result)
{
case NSOrderedAscending: {
NSLog(#"Location%# is greater than %#", [df stringFromDate:eventDate], [df stringFromDate:currentLocation.timestamp]);
}
break;
case NSOrderedDescending:
NSLog(#"%# is less %#", [df stringFromDate:eventDate], [df stringFromDate:currentLocation.timestamp]);
if (currentLocation != nil)
{
//Use them
//currentLocation.coordinate.latitude
// currentLocation.coordinate.longitude
}
break;
case NSOrderedSame:
//Use them
break;
default:
NSLog(#"erorr dates %#, %#", [df stringFromDate:eventDate], [df stringFromDate:currentLocation.timestamp]);
break;
}
}

Core Location uses a number of sensors to get a location: Bluetooth, Wi-Fi, GPS, barometer, magnetometer, and what Apple calls "cellular hardware". GPS, BLE, barometer, and magnetometer all don't need a data connection.

Related

iOS - LocationManager gives newLocation timestamp wrong

I just want to say that I have read everything about filtering old locations etc, but this is not the issue. What I just noticed when testing my app on a real iPhone device, was that when I change the "date & time" in "Settings" in the device, the newLocation I get from locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation gives me the same "date & time" as I have in my iPhone device.
I need to get the real timestamp according to network time, and not the phone's, because then I can manipulate the data. How on earth am I supposed to achieve this, did I miss something?
Btw, my locationmanager look like this:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
You won't get access to the raw GPS data (with a real timestamp). Why not use an actual ntp server instead?

Iphone GPS is not giving accurate latitude and longitude

Hello Friend i have seen many post regarding accuracy problem with gps but its not working all the time
-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSString *latstr = [NSString stringWithFormat:#"%f", newLocation.coordinate.latitude];
NSString *longstring=[NSStringstringWithFormat:#"%f",newLocation.coordinate.longitude];
if (abs(howRecent)>5.0)
{
[self.locationManager startUpdatingLocation];
return;
}
if(abs(newLocation.horizontalAccuracy)<0.0f)
{
[self.locationManager startUpdatingLocation];
return;
}
if(newLocation.horizontalAccuracy>65.0f)
{
[self.locationManager startUpdatingLocation];
return;
}
self.latstring = [latstr copy];
self.longstr = [longstring copy];
if((updateLocationFirst||loadFirstView))
{
[[NSUserDefaults standardUserDefaults]setObject:latstring forKey:#"Latitude"];
[[NSUserDefaults standardUserDefaults]setObject:longstr forKey:#"Longitude"];
[self displayParticularDaySpecial];
loadFirstView=FALSE;
updateLocationFirst=FALSE;
[self.locationManager stopUpdatingLocation];
}
}
Here the problem is I am sending the latitude and longitude to the google api with respect to some addresses if i am decreasing the accuracy value its taking lot of time to load and this value is having problem when you reach at destination with respect to destination with 0.6 miles difference.
You should refer to the Location Awareness Programming Guide which provides excellent programming examples for determining your location.
As you'll see in the demo in that document, when you start the standard location manager, you generally tell it what accuracy you require. And once you start the location manager, you don't have to start it again (like you appear to be doing in your code sample). The didUpdateLocations method will be called again and again, with increasing accuracy, all on its own. You don't need to start the location manager again ... it keeps going until you turn it off. By definition, if you're in didUpdateLocations, it means it's already on.
I also notice that you're using the old didUpdateToLocation. If you're programming for iOS 6, you really want to use didUpdateLocations, which is the current version of that CLLocationManagerDelegate method.
Finally, you mention it takes a long time to get your location. That's very possible. In fact, in certain areas, you will never get very close (or any location at all). Your app should assume that accurate locations will take a while, and you should gracefully handle if you never get a really accurate location, which is very possible.
Have you set desiredLocationAccuracy in your CLLocationManager? By default the range is somewhat wide.
It will take some time to acquire a very exact value.

Geocoding address into coordinates in iPhone

I am trying to geocode address into coordinates using following code:
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:#"6138 Bollinger Road, San Jose, United States" completionHandler:^(NSArray* placemarks, NSError* error){
for (CLPlacemark* aPlacemark in placemarks)
{
// Process the placemark.
NSString *latDest1 = [NSString stringWithFormat:#"%.4f",aPlacemark.location.coordinate.latitude];
NSString *lngDest1 = [NSString stringWithFormat:#"%.4f",aPlacemark.location.coordinate.longitude];
lblDestinationLat.text = latDest1;
lblDestinationLng.text = lngDest1;
}
}];
I have tried it many times but the debugger never enters the block and I am not able to get the location. What can I try next?
All right I found my mistake.
The code is correct and works perfect. All the while I was working on it was through debugger and was trying to figure out why the debugger did not enter the block. But now I have found out debugger does not enter the block at that moment. It takes little in getting the location values. It is done asynchronously so I was not able to find it and I was getting crash because of no values just after the crash. I have moved my code post block to inside the block and everything works fine for me now.
I just ran that exact code and it worked as expected. Make sure that you have an active internet connection.
Try adding a NSLog on the strings and see if it gets called.
NSLog(#"lat: %#, lng: %#", latDest1, lngDest1);
Are you running it in the simulator or the device?
Blocks are new features to Objective C from iOS4.0 onwards. A block you can imagine as a delegate method working in same functional block. As for any delegate method it takes time to invoke, depending upon the condition, same way block executes the code inside it, when it completes its work of geocoding. You can read more about Block in apples documentation or read http://www.raywenderlich.com/9438/how-to-use-blocks-in-ios-5-tutorial-part-2.
You can also have look into my repository on GITHUB https://github.com/Mangesh20/geocoding

Sometimes I receive the wrong GPS location

Sometimes I receive the wrong value for my current location, an error of up to 2 miles. Am I doing everything correctly?
self.myLocation = [[CLLocationManager alloc] init];
myLocation.delegate = self;
myLocation.desiredAccuracy = kCLLocationAccuracyBest;
[myLocation startUpdatingLocation];
What's the most accurate method to receive GPS location?
You get a stream of location updates from the device when you start monitoring location change and so you need to consider both the timestamp of the location update and its horizontal accuracy.
Use the timestamp to reject old values (for example when you first start monitoring, you will be sent an accurate (at the time) but old cached value).
Use the horizontal accuracy to reject values that are outside of your desired range.

How can I disallow use of a application feature based on if the device is a 3G or Non-3G device?

I want to allow only users with a 3G phone to use a particular GPS function. How do I run a check on the device before allowing that feature to be used?
The following code with allow you to determine the exact device that is in use but I would first consider the fact that a 3G device may not actually be able to obtain a GPS lock as the process of doing so is quite slow and requires a more or less clear view of the sky.
For an iPhone 3G the result of this method will be iPhone1,2
- (NSString *)deviceModel
{
NSString *deviceModel = nil;
char buffer[32];
size_t length = sizeof(buffer);
if (sysctlbyname("hw.machine", &buffer, &length, NULL, 0) == 0) {
deviceModel = [[NSString alloc] initWithCString:buffer encoding:NSASCIIStringEncoding];
}
return [deviceModel autorelease];
}
Why would you stop 1g phone users from using location services? If you are near mapped WiFi you can get decent location results even without a GPS on the device.
Instead you should base your choice of what to do around the current location accuracy, if that is a reason why you seek to disable anything.