I am creating an app that uses a lot of gps location. If a user's phone settings allows for GPS, is it ever possible if their initial location is "
None"?
The reason I ask this is because when I simulate the app on the simulator, the default setting for location is "None" (Which causes some bugs). I want to know if these "None" locations only affect simulators or if they should be accounted for.
Yes.
You have to handle this case.
A user can have an issue with his device GPS or not allow access to it or GPS takes time on load to get the first location for some reason.
You can't expect any perfect scenario, deal with None.
I want to know if these "None" locations only affect simulators or if they should be accounted for.
You should design your app to be able to tolerate not getting a location even if you're sure the device has the necessary hardware and the user permits the app to get location data. There will be times when the device simply can't get a location fix, or when the hardware fails, or the battery is so low that the system chooses not to turn on the radio, or whatever. You can't ensure that all the things that could go wrong won't, so make sure your app is prepared to handle problems.
this "None" location would need to be handled in multiple places -- I don't want to add unncessary code
That sounds like a different problem. If you have more than one part of your app getting location data... why? Make location processing part of your app's data model. That way you're only receiving the location in one place, and you can handle problems in one place, and any other part of the app that needs the location data can get it without having to reimplement all that stuff.
Related
For context I work on an app that requires authorizedAlways permission. Since the release of iOS 13 we have noticed that ~3-4% of our users are receiving location updates (from didUpdateLocations) that have a coordinate of 0,0 and a horizontalAccuracy of 2500. This seems to only be happening while the app is in a background state.
This is all very confusing given that the app logs all changes to authorization status (using didChangeAuthorization) and at no point do I see any change to a value other than authorizedAlways. That said, based on manual testing I've done it does seem that the app will be notified of a change to authorizedAlways status after a user hits the initial requestAlwaysAuthorization prompt with Allow While Using App. Then when the user backgrounds the app for a little while they are reprompted with two options, Keep Only While Using or Change to Always Allow. The app seems to only get notified of an authorization status change if the user proceeds with Keep Only While Using selection (and the app is notified of a change to authorizedWhenInUse.)
I had a hypothesis that there might be some weird state between the user being prompted for the background use (or the OS determining a prompt is required) and the user actually responding to the prompt, but my testing has pretty consistently shown that in that state the app is simply not receiving any location updates.
I've hit a wall on troubleshooting this and am hoping its just an iOS 13 bug but I've yet to hear of any other apps experiencing this issue. Would greatly appreciate any suggestions on further troubleshooting ideas or simply that your app has experienced this issue as well so I can stop banging my head on it!
This sounds like a bug. If the location is invalid it should have a negative value for horizontalAccuracy but this is definitely an invalid location. Run the CLLocationCoordinate2D through CLLocationCoordinate2DIsValid() or compare it to kCLLocationCoordinate2DInvalid but since you have a positive horizontal accuracy it will probably tell you (incorrectly) that it's valid.
My guess is the same as yours, that the app has been told it has "Always" permission before the user has actually granted Always from the second prompt and it's somehow receiving bad locations when in the background.
There's no notification because your app is never supposed to know when it actually has Always permission (presumably to prevent it from waiting until it has Always to start abusing background location).
Either file a bug with Apple or use a DTS incident. If it's a framework bug you should be re-credited your DTS and get faster support at the same time.
In the meantime, add extra checks for invalid locations that include the coordinate being 0,0.
I've got a concept of adding feature to my app which will register user location in interval of few seconds. Then sending this coordinates through cellular or Wi-Fi all when staying active in background. I need to send this in almost real time, so the app can't be killed in backgorund.
I know this concept is very power consuming but it is only a conception.
The conception of getting constant location in backgorund is in this theard https://forums.developer.apple.com/thread/69152
so I think it is possible.
But refreshing only the process in my app of sending coordinates to server it's a little bit difficult. I could not get straight answer that it is possible to set the time interval in which the app will refresh in backgrund.
Is there a method for telling the app how often it should refresh in background?
Apple won't let your app idea onto the app store. They're quite strict about which types of apps are allowed to run in the background, and are allowed to use continuous GPS. (Both of those things really drain the user's battery.) Sending a continuous stream of location updates to a server will also keep the cellular/WiFi transmitter powered up, making things even worse.
For your own experimentation, though, you can probably set up your app to be a navigation app. Those are allowed to keep the GPS "lit" constantly and to run in the background. You could then set up the location manager with the highest accuracy setting and start updating your location.
I don't think you have the ability to control how often you get location updates though. You could create a timer that fires on a regular interval and fetches the current location from the location manager. However I don't think there's much value in that, since you WILL get called when the user's location changes, and fetching the current location more often will just give you the same answers repeatedly.
I have to build an app that will have the following features :-
A way to add users and their data in a database. (which will be parse)
The app will access the location updates of the user (say after every 10 minutes or when the user has moved a significant distance). This will be done even when the app is in background. These locations will then be updated to the parse database as and when the new locations are received.
I am a beginner, so any suggestion to how i should approach this will be appreciated. Most importantly, i have the following problems :-
The app will also run in the background and will regularly use GPS. This will drain a lot of battery. How can i avoid this? (The precision of the locations are important)
The app will regularly update these locations to the parse database and will have to make regular API requests which will add to the cost. How can i minimise this?
From your description what you want is "significant location change" monitoring, which is built in to CLLocationManager. Instead of running continuous location updates, you tell the location manager to send you "significant" changes in location, i.e. when the user has moved some undocumented "significant" amount. It's specifically designed to minimize battery drain, so you don't need to bother disabling and reenabling it. Instead iOS makes sure you're using as little battery as possible to get the updates.
The CLLocationManager discuss the approach in some detail, but the basics are:
Once you've created your location manager, tell it to start significant location updates:
locationManager.startMonitoringSignificantLocationChanges()
Location changes are provided to the delegate via the same locationManager(manager:didUpdateLocations:) method used for continuous location updates.
iOS will wake your app up to let it process location updates.
You'll want to periodically update your location rather than leave GPS on continuously. Here's a tutorial covering CLLocationManager you may find helpful.
Without specific code, I can't give you a specific answer, but generally speaking you'll want to periodically turn on CLLocationManager, get your location, and turn it off again until the next update. You can also configure the accuracy of CLLocationManager--the more specific your location, the more battery power is required.
Here's another tutorial on CLLocationManager to take a peek at, too.
As far as I have searched, iOS devices without internet (WiFi) are struggling to acquire current location when GPS is the only option.
Is it possible to get current location in that situation, I mean using only GPS?
Sure it does automatically, if no WiFi is enabled it should automatically trigger the GPS, it takes a long time because if no location data is cached it starts to search for satellites.
If you want to display and error message, you can use a timer, if after X seconds no location is obtained just stop updates and show an alert to the user.
A great difference in time is made by the desiredAccuracy, if you set a lower accuracy even if when the GPS is on it will require less to get your position.
what do you mean by struggle?
Is it possible to get current location in that situation, I mean using
only GPS?
yes, perfectly
I'm creating an app that allows the user to navigate with a map when offline (no internet connection or wifi available), and I want to let the user know if the gps location not being updated. I know I can get the last updated location timestamp and the accuracy, but is it possible to know if the gps has no reception?
No, there's no public interface for finding out about the state of specific location hardware such as the GPS receiver.
The Location Manager abstracts all that away, so that developers can get location and accuracy information without worrying about whether the device used GPS, Wifi, iBeacons, cell tower locations, Loran-C, celestial navigation, etc. to determine the location. This is generally a very good thing because it means that your apps work on all devices regardless of whether they have GPS, and will continue to work (and maybe even work better) on new devices that might use other technology. But it also means that you don't get to ask the question "is the device receiving a GPS signal right now?"
Is it possible to know if the GPS location is not being updated?
No. It doesn't seem possible given the available API.
There are a few things about GPS to consider, if you haven't already. It is technically possible to receive a location update from CLLocationManager when you're "offline" but it will depend on several things:
If your device actually has GPS hardware. Some don't.
If you have line of sight to GPS satellites. There's a difference between GPS and A-GPS
Those true GPS updates will come much less frequently because of the way GPS works, but it should work.
... but is it possible to know if the gps has no reception
Based on the way GPS works (as best I understand it) you either turn the radio on/off (-startUpdatingLocation/-stopUpdatingLocation) with the Location Services API and you either get locations more frequently with A-GPS or infrequently with pure GPS when you don't have a network signal. I don't think the Location Services API has a way of telling you "I don't have a GPS signal at all."