Most people will remember the old Nokia phones, which showed your current district (cell tower) you are connected to.
Is this information available on iOS? if so, how to fetch this info?
SO I mean when in New York it would for example return "fulton" as the district...
You don't get access to the cell tower information as you described on iOS, however you can always use the CoreLocation framework (MapKit if you also want backward compatibility with iOS 5.0 for some reason) to do a reverse geocode and get as much detail as available.
For iOS 7.0, you use the CLGeocoder object.
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
// Iterate through available placemarks
}];
The location parameter is a CLLocation object you would have received or created for the user's location.
For reverse geocode requests the array in the completion handler will only contain a single placemark. The various properties and their corresponding real-world relations for a placemark object can be found here
The only thing that we can get from the cell tower is from core telephone framework
Obtaining Information About the Cellular Service Provider
allowsVOIP property
carrierName property
isoCountryCode property
mobileCountryCode property
mobileNetworkCode property
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Reference/CoreTelephonyFrameworkReference/_index.html
Apple currently does not provide any public API that reveals cell tower meta data. From the looks of how they approach telephony API design, I don't see this becoming a feature in the future, either.
Check out: Getting cell tower information in an iOS application?
Related
So, I've got a navigation app. It uses the onboard GPS (and magnetic compass and accelerometer) to construct a 3D Augmented Reality viewport similar to how Google Sky works. We're not using ARKit for a variety of reasons including that this device will be used in a moving vehicle and we're concerned that ARKit would get distracted by the apparently non-moving vehicle interior instead of paying attention to the invisibly-moving exterior reference frame outside the vehicle, which is the reference frame we want our AR navigation display to be aligned to.
The AR orientation part is not my main problem (though I am finding that the magcompass plus accelerometers really are fairly prone to error). My vexing issue is that no matter how hard I try, some iOS devices (mostly iPads) don't seem to be using the actual GPS hardware to determine the Core Location data. It seems to be using Wifi trilateration and therefore providing inferior position data (lacking Altitude) and therefore inferior velocity data calculated from the position data.
Here's some facts.
I initialize the Location services like this:
_locationManager = [[CLLocationManager alloc]init];
[_locationManager requestAlwaysAuthorization];
_locationManager.delegate = self;
_locationManager.distanceFilter = kCLDistanceFilterNone;
_locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
[_locationManager startUpdatingLocation];
On some devices, we definitely get a full 3D GPS location, including altitude.
However, certain test devices ("APPLE MPMF2LL/A iPad Pro with Wi-Fi + Cellular 512GB, 10.5", Silver", "Apple iPad Air 2 MH2V2LL/A (16GB, Wi-Fi + Cellular, Silver) 2014 Model", both with cellular capability and OS 11.2.6), we get Location data that reports a <0 value for Vertical Accuracy, meaning it's not valid, and the Lat/Lon Location value behaves like it's a Wifi trilateration position not a real GPS.
We've tried airplane mode on and off, made sure location services is enabled and permission granted to our app. We tried setting the Location permission to "Always". We tried factory resetting and restoring.
Simple compass apps from other app developers seem to work fine and show a correct altitude and Vertical Accuracy on these devices. Our app seems to work fine on other devices (iPhones of various flavors, full-size 5th gen iPad) and get full GPS Locations. So, it doesn't seem to be a hardware failure of the test devices, yet nor does it seem to be a complete failure of our code.
Is there some magic we aren't requesting or performing properly to ensure we're getting full GPS-sourced location data?
There is already a fallback in the code for devices or circumstances where we can't get GPS Altitude. But if the device HAS the capability, we want to make sure we're using it to the best ability. We also are working on the ability to use external GPSes, but it seems we ought to be able to use what the iOS devices definitely has if we ask for it.
Grateful for any insight. Doesn't seem like it should be this hard.
So, after much pain and suffering, we identified the culprit, but there's still an unknown that is unsolved.
I'll start with the diff of the fix, because reference code trumps all, and then I'll explain what we believe was going wrong.
- CLGeocoder *geocoder = [[CLGeocoder alloc] init] ;
- [geocoder reverseGeocodeLocation:_currentLocation completionHandler:^(NSArray *placemarks, NSError *error)
+ if(_udpSocket == nil || timesincelastnetwork > _waitSecondsWithNoNetwork)
{
- if (!(error))
- {
- CLPlacemark *placemark = [placemarks objectAtIndex:0];
- // NSLog(#"\nCurrent Location Detected\n");
- //NSLog(#"placemark %#",placemark);
- NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
- NSString *Address = [[NSString alloc]initWithString:locatedAt];
- NSString *Area = [[NSString alloc]initWithString:placemark.locality];
- NSString *Country = [[NSString alloc]initWithString:placemark.country];
- NSString *CountryArea = [NSString stringWithFormat:#"%#, %#", Area,Country];
- //NSLog(#"%#",CountryArea);
-
-
- CLLocation* l = placemark.location;
- CLLocationCoordinate2D coords = l.coordinate;
+ _currentLocation = [locations objectAtIndex:0];
+ //[_locationManager stopUpdatingLocation];
-
- float lati = coords.latitude; //39.8560963f; //
- float longi = coords.longitude; //-104.67373759999998f; //
-
- float alti = l.altitude;
So, what appears to have happened is that during the geocoding process, on SOME devices, the altitude was being lost but on some devices it was being preserved. Since we didn't really need the geocoding (we had left it in from the example code in case it would be useful), we just took it out and use the lat/lon/alt directly from the location service and it works properly on all devices now.
I'd consider it a bug or at least an undocumented condition that the geocoder is wiping out the altitude value in some unclear circumstances but not others, but fortunately, it's a bug we are able to work around.
I have used CLLocationManager to get the current GPS coordinates of a user.
I need to get the current state where it is.
With internet:
CLGeocoder *gc = [[CLGeocoder alloc] init];
[gc reverseGeocodeLocation:location completionHandler:^(NSArray *placemark, NSError *error)
{
if(!placemark){
/* handle error */
}else{
CLPlacemark *pm = placemark[0];
NSLog(#"%#", pm.administrativeArea);
}
}];
Is there any way I could find out what the state where the user is without internet?
Your question is not very clear, I'll try an answer though.
Generally if you're asking if you can use the (reverse) geocoding API of CLGeocoder when the device is offline, the answer is no, as stated here in the docs:
The computer or device must have access to the network in order for
the geocoder object to return detailed placemark information.
Although, the geocoder stores enough information locally to report the
localized country name and ISO country code for many locations. If
country information is not available for a specific location, the
geocoder may still report an error to your completion block.
If with state, you mean a country or a nation, you at least have the option to hardcode a list of all the world's countries' coordinates in your app (or maybe you can find one online...) and use the location data to calculate the state... sounds like a lot of effort, but would solve your problem...
I am trying to make a simple app which allows the user to get the longitude and latitude corresponding to a specific address. I want to provide the user with a search box similar to the one in google maps. Specifically I would like some sort of autocompletion to ensure the user enters a valid address. Is it possible to create an instance of google maps search box?
SPGooglePlacesAutocomplete is a simple objective-c wrapper around the Google Places Autocomplete API.
Look at this API from github which might be helpful- https://github.com/spoletto/SPGooglePlacesAutocomplete
Usage shown as per link. Adding the .h file you can have access to the functions which implement the Google places API from within the function. You can set parameters like partial address string, radius, language your app uses, your location (lat,long)
#import "SPGooglePlacesAutocompleteQuery.h"
...
SPGooglePlacesAutocompleteQuery *query = [SPGooglePlacesAutocompleteQuery query];
query.input = #"185 berry str";
query.radius = 100.0;
query.language = #"en";
query.types = SPPlaceTypeGeocode; // Only return geocoding (address) results.
query.location = CLLocationCoordinate2DMake(37.76999, -122.44696)
Then, call -fetchPlaces to ping Google's API and fetch results. The resulting array will return objects of the SPGooglePlacesAutocompletePlace class.
[query fetchPlaces:^(NSArray *places, NSError *error) {
NSLog(#"Places returned %#", places);
}];
It also has a example project which can be used.
I'm working on an application that needs to detect the user's location.
I need to extract the user's country and city codes.
I was able to get the country code using a placemark in locationManager: didUpdateToLocation: fromLocation: as follows:
CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
MKPlacemark * mark = [[MKPlacemark alloc] initWithPlacemark:[placemarks objectAtIndex:0]];
NSString * code = mark.countryCode;
NSLog(#"country code: %#", code);
}];
So, is there any solution that helps me find an IATA 3-Letter Code for the user's city ?
I suggest you use the database available at OpenFlights: http://openflights.org/data.html (which #Ben-G linked indirectly).
There is a somewhat 'web service' as a form: http://openflights.org/html/apsearch but I think that given the size of the database (about 9200 entries) it is actually better to import it in the app and query it directly, specially if you are going to query a lot (more queries... more traffic if using a web service, and so more delay and decreased user experience, etc).
Though I wonder why you wouldn't calculate a circle given the user's position and then query the database for any airport within some specific radius. That will give you all airports in the whereabouts and obviously the cities and the country. Getting the airport code(s) given the user's city might give you nothing if the city mainly served by an airport doesn't correspond to the city of the user's location.
I'm using the iOS 6.0 SDK and I would like to route between two different addresses (not latitude and longitude) with Apple's new iOS 6.0 maps. I would like to show the indications too.
How can I do this?
I looked into do doing this last week and did not figure out a way to do it. It appears that you can give a destination, and you can sort of give it more than just coordinates, but it always assumes your starting position is the current location. That is limiting when you may be planning a trip while you are not currently at the starting location. (But perhaps I am just not seeing how it is done and I hope someone can correct me if that is true.)
A while back I looked into routing options for iOS 6 and gathered the results here...
How would you providing routing for directions between points on a map? What are the missing pieces?
You still may not be able to open up Apple Maps with the exact routing that you want, but perhaps you can draw the route with overlays and annotations on your own instance MKMapView. That may be the best you can do for now.
Below is the code that I used to route to a location and provide at least a label for the destination instead of leaving it to only coordinates. I found that simply giving the destination a label with the full address details would not work, so I just provide that one value.
if (flag != DirectionsFlag_PublicTransit && itemClass && [itemClass respondsToSelector:#selector(openMapsWithItems:launchOptions:)]) {
NSDictionary *address = #{ (NSString *)kABPersonAddressStreetKey : location.title };
MKPlacemark *destinationPlacemark = [[MKPlacemark alloc] initWithCoordinate:location.coordinate addressDictionary:address];
MKMapItem *destinationMapItem = [[MKMapItem alloc] initWithPlacemark:destinationPlacemark];
if (flag == DirectionsFlag_Driving) {
[destinationMapItem openInMapsWithLaunchOptions:#{MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving}];
}
else if (flag == DirectionsFlag_Walking) {
[destinationMapItem openInMapsWithLaunchOptions:#{MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeWalking}];
}
}
This code specifically does not handle Public Transit directions since Apple Maps does not do that. I instead have it open up Google Maps with the URL that I was using previously which now opens up Safari for those directions. The flag is an enum value of Driving, Walking or Public Transit. The location is a model which contains various details including title and coordinates.