I am building an iOS app that uses the phone's GPS EXIF data from both camera and image library.
My problem is that I while I am able to get GPS data from images in the phone's library, I have not been able to get any GPS data when using the camera within my app.
I first built this app about a year ago and at that time I was able to get GPS data from both the library AND the camera from within the app. I believe that at that point I was still building for iOS 12.. I believe that the new security features that came with iOS 13 or 14 now dissalow my app's access to the GPS data when using the camera.
This issue is new as of iOS 13 or 14. The code I had was working fine with earlier versions of iOS
I am having no issues with getting GPS from the EXIF on the device library images.
Images taken with the NATIVE IOS CAMERA APP are saved to the library with full GPS data.
- However I am not able to get GPS data directly from camera image EXIF when using the camera from within my app.
When saving an image taking by the camera from within my app the image is saved to the library with NO GPS data.
I am able, at any time, to ask the device for current GPS coordinates.
As far as I can tell, device settings are all correct. Location services are available at all times.
My feeling is that iOS is stripping the GPS data from the EXIF image before handing the image data to my app.
I have searched Apple developer forums, Apple documention, Stack Exchange, on and on for over several weeks now and I seem no closer to knowing if the camera API even returns this data or not and if it will be necessary for me to talk to the location services and add the GPS data myself (which is what I am working on now as I have about given up on getting it from the camera).
Info.plist keys I am currently setting:
LSRequiresIPhoneOS
NSCameraUsageDescription
NSLocationAlwaysUsageDescription
NSLocationWhenInUseUsageDescription
NSMicrophoneUsageDescription
NSPhotoLibraryUsageDescription
NSPhotoLibraryAddUsageDescription
Am I missing some required plist key? I have been searching and searching for the name of a key that I might be missing but have found absolutely nothing other than people trying to hack some post-camera device location merging.
This has been very frustrating..
Any insite is appreciated
Is it currently possible to get GPS data directly from the camera's EXIF output any more?
Do I need to ask the device for the current GPS values and insert the GPS data into the image EXIF on my own?
Is there any example code of getting GPS data from the camera?
Is there any example code of inserting GPS data into the Exif before saving the file to the device?
Sample swift code which processes the camera image.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
// let pickedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage
// using editedImage vs originalImage has no effect on the availabilty of the GPS data
userImage.image = pickedImage
picker.dismiss(animated: true, completion: nil)
}
Maps & Location
RSS for tagLearn how to integrate MapKit and Core Location to unlock the power of location-based features in your app.
Post
Replies
Boosts
Views
Activity
What is the minimum horizontal accuracy value that we can expect in a location callback? Because I want to know if it is possible to get a horizontal accuracy <= 5
I'm working on an iOS iBeacon app that uses CoreLocation APIs for both ranging and monitoring regions for beacons. I've noticed that if I turn on audio streaming by pairing my phone to my car and making a phone call that's broadcast over the car speakers or running an audio streaming app like Pandora through the car speakers then ranging stops and I receive didExitRegion callbacks.
This is with the beacon and the phone within a couple feet of each other and not moving. It happens both with the app in the foreground and background.
I guess there's some kind of priority issue going on with the phone's broadcast of audio over BT taking priority of its listening for iBeacons but it seems extreme.
My beacons are custom with a broadcast interval of 2 secs and power of 4dB.
I'm on the latest iOS 17.x on a recent iPhone and other users have reported the same issue.
Is this a well-known issue?
Is there some way to mitigate this?
I'am developing an iOS widget for my weather app, where the user can set the widget to "My location". This means the widget needs to be refreshed on location changes. Since a widget can't run a location manager in the background, apple tech support wrote that you have to setup a location manager in the main app and share the updated location data over App groups to the widget. This part works fine. I also managed to setup a location manager running in the background, but it uses too much battery and shows always the location indicator on top (blue bar) if the app is running, but I don't need this since its not a navigation app or something similar. How to configure a lightweight location manager running in the background?
class WidgetLocationManager: NSObject, CLLocationManagerDelegate {
static let shared: WidgetLocationManager = WidgetLocationManager()
let manager = CLLocationManager()
override init() {
super.init()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyKilometer
manager.distanceFilter = 1000
manager.allowsBackgroundLocationUpdates = true
manager.pausesLocationUpdatesAutomatically = false
manager.activityType = .other
manager.showsBackgroundLocationIndicator = false
}
func setupWidgetLocationManager() {
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
manager.startMonitoringSignificantLocationChanges()
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
if manager.authorizationStatus == .notDetermined || manager.authorizationStatus == .denied || manager.authorizationStatus == .restricted {
manager.stopUpdatingLocation()
manager.stopMonitoringSignificantLocationChanges()
}
if manager.authorizationStatus == .authorizedAlways || manager.authorizationStatus == .authorizedWhenInUse {
manager.startUpdatingLocation()
manager.startMonitoringSignificantLocationChanges()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let newestLocation = locations.last {
UserDefaults(suiteName: "group.com.***")?.set(Double(newestLocation.coordinate.latitude), forKey: "newest_location_latitude")
UserDefaults(suiteName: "group.com.***")?.set(Double(newestLocation.coordinate.longitude), forKey: "newest_location_longitude")
UserDefaults(suiteName: "group.com.***")?.set(Double(newestLocation.altitude), forKey: "newest_location_altitude")
WidgetCenter.shared.reloadAllTimelines()
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
}
}
Capability for background modes location is set, also mandatory strings in info.plist for location privacy info.
Can Mapkit show me details about bus stops, train stations, underground and overground stops, or other public transportation locations based on a specific latitude and longitude?
If you check the Google Maps picture I shared, I marked all the public transportation spots near Elephant & Castle in London. This includes bus stops, the Elephant & Castle Underground station, and the Elephant & Castle Rail station. Additionally, tapping on these spots brings up an alert with more info, like which buses are coming or details about train lines.
In the initial Xcode 15/iOS 17 Beta selecting a Marker would give a visible indication that the marker was selected without setting the selection. This is the code I used.
struct ContentView: View {
let location = CLLocationCoordinate2D(latitude: 37.0,
longitude: -122.0)
@State private var position: MapCameraPosition = .automatic
@State private var selectedItem: MKMapItem?
var body: some View {
VStack {
Text(selectedItem == nil ? "Nothing Selected" :
selectedItem?.name == nil ? "No name" :
selectedItem!.name!)
.bold()
.padding()
Map(position: $position, selection: $selectedItem) {
Marker("Marker", coordinate: location)
.tag(1)
.tint(.red)
}
}
.padding()
}
}
I submitted feedback and things changed in Beta 3. Now I can not select the Marker. That's not the direction I'd hoped to see. Am I doing something wrong or is there no way to select a Marker placed on a map?
I am currently facing a critical issue with the Google Maps integration in my iOS app. The application functions flawlessly on my personal device during development; however, when I upload it to the Apple Store, users on their iPhones experience frequent crashes.
The problem seems to be specifically tied to the Google Maps functionality within the app.
Despite thorough testing on my end, the discrepancy between the local environment and the App Store release persists. I am seeking assistance from fellow developers to help me identify and rectify the root cause of this problem.
Any insights, suggestions, or debugging tips would be greatly appreciated to ensure a smooth and reliable user experience for all. Thank you in advance for your expertise and support in resolving this issue.
Hello,
I am facing an issue with mapkit JS map when it is accessed from China. From other regions maps render and display fine, but when user from China tries it, it throws 401. Signed JWT token is shared for all regions (without origin field) and is still valid and verified on JWT.io (and it works on other regions so it should not be the problem). Does mapkit js work for China users as it is stated that it does?
Thanks in advance,
Marko
Right now my map is littered with road annotations (interstate and highway markers) that are quite distracting and not at all relevant to my application. Is there a way to turn them off?
I already tried mapkit.pointOfInterestFilter but the categories do not include the road annotations. I can't find anything else. Does anyone know?
I am creating an app that runs on Mac using objective-c.
Since location information permission is required, I implemented the following.
// AppDelegate.m
#import <CoreLocation/CoreLocation.h>
- (void)getLocation {
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager requestWhenInUseAuthorization];
}
- (IBAction)buttonClicked:(id)sender{
[self getLocation];
}
Info.plist
<key>NSLocationUsageDescription</key>
<string>This app requires location information.</string>
What I'm hoping for is that when I run this app and press the button, I'd like to see an OS alert asking for permission to use location information, saying "***" would like to use your current location.
However, when I try it, no alert is displayed.
However, the app name has been added to the "Location Services" item in "Security & Privacy" in System Preferences.
How can I display alerts?
When I run an app that uses location services on the Xcode 13.1 simulator for iOS 15 the location privacy settings are missing. If you go to the settings on the simulator under privacy the section for location services is missing. The exact same thing on a physical iPhone running iOS 15.0 does show the location settings under privacy in the settings app. Where did the settings for location privacy go? In order to test using the simulator a developer needs to be able to turn those settings on and off, like turning off precise location to see how an app responds.
I am adding Apple Maps using the API to my Apple IOS to show address to be visited. another feature we require is to have the addresses showing in the best order to be able to visit each one in the fastest time.
I am wondering if apple allow to upload multiple addresses via a API and the addresses will be optimised and returned back to my app in the fastest order
Is there a SDK that will allow this function?
Hello.
I've submitted a small update for my app and i
received an email that said: "The “” value for the
NSLocationWhenInUseUsageDescription key isn’t allowed
"
I have values for the above key in English and Greek in
InfoPlist files and they are appearing correctly when the
app is asking for location permissions. It has been like this
for years and i didn't change anything related to
this function.
Can someone please explain to me why i received this email
although i've set everything correctly?
As an iOS native MapKit engineer, the MkAnnotationView constructor "initWithAnnotation:reuseIdentifier:" seems to take more time in iOS 17.
Just use the code snippet below to measure the time, it constructs 50,000 MKAnnotationView objects.
long st = [[NSDate date] timeIntervalSince1970] * 1000;
NSLog(@"create annotation view start time = %ld", st);
MKAnnotationView *myAV = nil;
MKPointAnnotation *anno = [[MKPointAnnotation alloc] init];
anno.coordinate = CLLocationCoordinate2DMake(64, 121);
for (int i = 0; i < 50000; ++i) {
myAV = [[MKAnnotationView alloc] initWithAnnotation:anno reuseIdentifier:[@"hehe" stringByAppendingString:[NSString stringWithFormat:@"%d", i]]];
}
long ed = [[NSDate date] timeIntervalSince1970] * 1000;
NSLog(@"create annotation view end time = %ld, interval = %ld", ed, ed - st);`
In iOS17, it takes around 2.6s.
In iOS16, it takes around 0.9s.
This performance degradation between different iOS version(iOS SDK 16 vs. iOS SDK 17) affects our app which uses the native MKMapView.
Could someone take a look at this issue or offer any workaround?
Hi,
We have Bluetooth Hardware and we want to connect to that bluetooth device to open lock in the background when user shakes his phone.Is it possible to do that?
I came accross such apps in the store, but i do not know how to do it.
Regards.
Hi, I'm using MKMapSnapshotter in my app to make a snapshot of routes and I'm using MKMarkerAnnotationView for markers with specific images. This all used to work just fine until iOS 17 arrived. Since then every map that is rendered places a back square around my markers. I have tried everything, searched the whole Internet and there is no way I can solve this...
Anyone ran into this and have a way to fix this or is is just a bug we have to live with for now?
Thanks in advance!
https://maps-api.apple.com/v1/directions
After installing 17.1 on test devices, I am seeing a lengthy difference in requesting a user location. Takes about 4-5 seconds. This issue doesn't occur on 16 or 17.0. Anyone else seeing this problem?
If you refresh the page after initially granting location permissions, you will be prompted for location permissions again and will need to grant permission again. Currently this only occurs on iOS. Is there a way?
The tested iOS versions are 16.2 and 17.
This is the code implemented when retrieving location information.
<script>
var options = {
timeout: 15000,
enableHighAccuracy: true,
maximumAge: 86400000,
};
function success(pos) {
var crd = pos.coords;
alert('Your current position is:');
alert(`Latitude : `+crd.latitude);
alert(`Longitude: `+crd.longitude);
};
function error(err) {
alert(`ERROR(): `+err.message);
};
navigator.geolocation.getCurrentPosition(success, error, options);
</script>
If you refresh the page after initially granting location permissions, you will be prompted for location permissions again and will need to grant permission again. Currently this only occurs on iOS. Is there a way?
I launched that web from app and the Safari settings didn't fix the issue. What should I do about this problem?
The tested iOS versions are 16.2 and 17.
This is the code implemented when retrieving location information.
<script>
var options = {
timeout: 15000,
enableHighAccuracy: true,
maximumAge: 86400000,
};
function success(pos) {
var crd = pos.coords;
alert('Your current position is:');
alert(`Latitude : `+crd.latitude);
alert(`Longitude: `+crd.longitude);
};
function error(err) {
alert(`ERROR(): `+err.message);
};
navigator.geolocation.getCurrentPosition(success, error, options);
</script>