iPhone Location Services is turned off, but the application can still get the location? - iphone

I turned off the Location Services on my iPhone, because I don't want the app to determine my location. But, when I run the app it somehow gets my location! Any ideas?

As the docs suggests here
Locations
An array of CLLocation objects containing the location data. This array always contains at least one object representing the current location. If update events were deferred or if multiple events arrived before they could be delivered, the array may contain additional entries. The objects in the array are organized in the order in which they occurred. Therefore, the most recent location update is at the end of the array.
So the location manager always shows some value.

Related

Merge NSManagedObject with equal properties, but different IDs, synced with iCloud results in duplicates (Core Data, Swift 1.2)

I have a Swift 1.2 app that uses Core Data with iCloud sync.
In the first screen, the user can insert some data to create custom MyNSManagedObjects.
Every MyNSManagedObject must have a specific "group" to which it belongs. This "category" is represented in my data model by another custom NSManagedObject, let's call it MyManagedObjectsCategory.
User can create many MyManagedObjectsCategory objects, but the app also needs a DEFAULT object of type MyManagedObjectsCategory, in case the user doesn't create any different MyManagedObjectsCategory.
Every MyNSManagedObjects can have only 1 MyManagedObjectsCategory, but a MyManagedObjectsCategory can have many MyNSManagedObjects.
When user launches the app, I immediately check if the DEFAULT MyManagedObjectsCategory already exists and if it doesn't I create a DEFAULT MyManagedObjectsCategory object and save it to persistent store. Of course, only the first time the app launches I need to create this object, later I always fetch the object I created on the first launch of the app and use that.
My issue started when I enabled iCloud sync; now, on the first launch of the app, this happens:
The app on launch uses STORAGE 1 (local) as expected and, not finding the DEFAULT object of type MyManagedObjectsCategory, it creates a new one.
If there's network coverage, a few seconds later the app switches to STORAGE 0 (cloud) and saves the DEFAULT MyManagedObjectsCategory object that has just been created; if the device is offline, this doesn't happen immediately, but of course it will occur when network connection becomes available later.
When I launch the app for the first time on a different device, the point 1 and 2 above happen again: since the app starts with storage 1, it doesn't fetch the DEFAULT MyManagedObjectsCategory object and it creates and saves a new one that, a few seconds later or when network is available, is synced to storage 0 as the app switches storage.
As you can imagine, when different devices sync I find myself with multiple DEFAULT objects and, since I'm new to Core Data, I have no idea how to manage this issue.
On one hand, I need the DEFAULT object immediately available when the app launches, so I can't wait the switch to storage 0 (also, because I don't know if the user has network connection, so the storage switch might happen much later); on the other hand, the purpose of the DEFAULT object is to be one, and always the same, on every device.
I understand that, even if every DEFAULT object has matching properties (the object has a name and a myID String property) being created in the exact same way, Core Data creates a unique ID for every managed object and, since the ID doesn't match between the DEFAULT objects created on different devices in different moments, it doesn't merge them in a single DEFAULT object.
So, my questions:
Is there a way to force this merge of the DEFAULT objects into a single one, if certain properties are exactly the same? Is so, how? I suppose I could do it when the app launches, since the duplication of the DEFAULT object would only happen when a new device is added to iCloud.
Is there a completely different way to handle this issue that I'm missing?
I've spent the last 2 months working on this app, but I can't ship something that duplicates objects when syncing, and I have no idea how to fix it, so any help would really, really be appreciated.
Thanks,
#cdf1982
This is fundamental to using iCloud, or really any sync mechanism. If your app creates the same instance on multiple devices, and can't sit around waiting to see if it already exists from a different device, then you'll get duplicates.
The only way to handle this is to let the duplicates happen and then clean them up. With iCloud, you do the cleanup when you receive NSPersistentStoreDidImportUbiquitousContentChangesNotification, indicating that new incoming data is available. The basic scheme is to do a fetch that finds all duplicates and then handles them according to your app's needs (merging/deleting/whatever). I described this in a previous answer and in some detail in a blog post.
You'll make this much, much easier on yourself if your category entity has an attribute that stores a unique ID, and you ensure that you always use the same unique ID value for your default category instance. Then you can simplify the de-duplication by fetching only objects that match the known unique ID value.

Changing a UITableViewController dynamically via location

I am in the process of building an app, for the record I am using the code from the ECSlidingView controller. I would like for my app to use the GPS to pull data from my web interface letting the user know that they can do certain things at a given location. So for example, I have a user go to a store and lets say I want them to make a payment at that location, it will given them that option. Or if the store doesn't offer payment through the app, I disable that. What would be a good way to go about this?
You could try using CoreLocation but you might have trouble getting accurate location inside (it will most probably use wifi or cellular info so the accuracy might not be what you expect). Then, when you get the location, issue a request to your service passing latitude and longiude you receive from CoreLocation. There, you should search by location to retrieve possible matches - consider returning muliple store infos for nearby stores due to the accuracy issues.

iOS - truly persistent data?

I'm exploring a business model that specifies how many times a (costly) function may be invoked per user in an application.
Right now whatever I save, e.g. user defaults, gets deleted when the app is deleted. When the app is reinstalled, the counter is back to zero.
What I need is a way to save information such that deleting the app still leaves the information intact.
I've seen examples that mimic the deprecated unique identifier, but that's per device, which is not what I'm looking for.
KeyChains appear to be the right way to go. I can store a unique ID there specific to the user as well as in the user defaults and that way can track also if the app was reinstalled.

Core Location - fallback, location caching and alternatives

I have a few questions about Core Location.
1) Should the user refuse permission for my app to use core location, or core location is unavailable for some reason, is there a fallback? (Device Locale, for example?)
2)Can I cache a device's location for next time? Does Core Location do this itself?
3)I really need the sunset time in the user's area during the mid-spring season and I have a function to do that, once I have the Latitude and Longitude of the device. Perhaps I can just make an assumption about the time based on Locale? (Example: In the US, assume approximately 7:00pm.)
EDIT:
I really am trying to calculate sunset in the users area for an app. Nothing to do with the map. I am considering the following sequence of events:
Check for Core Location availability. If yes, use it and store it in NSUserPreferences. If Core Location is unavailable, go on to the fallbacks.
Check for a stored Location. If it's stored, use it. If not, go on...
Check for the user's chosen time.
1) Strictly speaking, if the user does not allow using CoreLocation or, if permission were given but CoreLocation is not available, there is no other fallback to get the user's location as a latitude, longitude pair. Using the locale may not work in all of the cases. First, it will just give you an approximation which may be way too far from reality. However, it's up to you to judge whether this approximation is ok for your app. Moreover, there are some users using a locale different from the one related to their country. And, you have no guarantee that people travelling abroad will adjust the date/time every time.
2) Core Location caches by default the last location retrieved from the GPS unit. However, for people travelling abroad this cached location will be certainly wrong (even for people travelling just a few miles away), and in general, you should discard the cached value and localize again the user each time. I understand that for people travelling within their country this will not (usually) create huge problems. But it just depends on the country: travelling within Italy will not change the time, but travelling across the US may change the time up to 3 hours.
3) I would suggest to try using Core Location and, in case of problems, simply ask the user to input his/her local time or location (the city should be enough for your purpose). If you choose to ask for the user's location, then you can get the corresponding latitude/longitude pair but this will require a working network connection.
2) From the online docs for CLLocationManager:
The location service returns an initial location as quickly as possible, returning cached information when available.
You can check the CLLocation timestamp to see if it is a cached value or not.
3) If you do decide to use locale for an initial TZ approximation, remember that users travel, and may not reset their locale promptly. You can get the current TZ object with:
[NSTimeZone localTimeZone]

iPhone Development: CoreLocation and MapKit

How bad is it to use Location Manager to retrieve the location information when MapView.showUserLocation is also TRUE?
I have a situation where i want to show the blue dot to indicate the user's current location, and i want to record the user's current location after some time interval. Having said that, there may be situations where the user's current location is now being shown, but i still want to get the user's current location.
I think i'll have to use the Location Manager in my controller class, but setting showUserLocation = YES would mean that i'll be draining more battery since two Location Managers are working at the same time? Is this assumption correct?
As discussed on other communities, you can have mapView.showUserLocation = YES and still use CLLocationManager to retrieve the most current location information.
In general there's no conflict involved with having multiple CLLocationManager instances running at the same time.
Just save the coordinates in an array and draw mapannotations for past recorded locations. You dont need to run multiple location managers.