iOS: Notify a WebService of location change (using Significant-Change Location Service) - ios

I'm developing an app that allows me to track the device's location, the idea is that the app notifies every few hours our servers of the current location so I can send relevant push notifications to the user.
This should work even if the app is not running (the app should be awakened by the OS).
I was reading the Location Awareness Programming Guide (http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html) and I think the Significant-Change Location Service would help me accomplish this, however the guide mentions this:
it should do minimal work and avoid any tasks (such as querying the
network) that might prevent it from returning before the allocated
time expires.
If this is the case, I don't think I will be able to notify our servers of the location change.
I'm assuming this is possible because there are apps like "Find My Phone" that have to get the updated location of the devices every once in a while.
If this is not the right approach I would appreciate any pointers to info on what should I do to get this working.
Thanks

Related

React Native iOS app restart on reboot

I want to create an iOS app using React Native. One of the primary features of the app is that it runs constantly in the background. It also requires using GPS btw (in case that is important).
I have had a number of devs tell me its not possible to do this for iOS, however I have read that it is do-able.
Is this possible to do in the iOS environment? Mainly, if the app is running when the phone is powered off, can you make it open when the device is restarted without the user opening it?
I should say that I am a RN novice and any help is much appreciated.
If your app gets permission to get location while it's not in the foreground, then you will get periodic updates and some time to process it.
For example, if you are giving driving directions.
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html#//apple_ref/doc/uid/TP40009497-CH2-SW10
If there is no good user benefit for you to get the location in the background constantly, you might be rejected. Apple suggests region monitoring instead
iOS supports the delivery of location events to apps that are suspended or no longer running. The delivery of location events in the background supports apps whose functionality would be impaired without them, so configure your app to receive background events only when doing so provides a tangible benefit to the user. For example, a turn-by-turn navigation app needs to track the user’s position at all times and notify the user when it’s time to make the next turn. If your app can make do with alternate means, such as region monitoring, it should do so.
I have no idea how RN wraps this behavior, but no matter what it does (or what a plugin might do), the core iOS behavior is how it is described in that URL.
I verified yesterday (at least on iOS 11.2 simulator) that automatically restarting the app (and the location tracking) after phone reboot works.
The key point is that startMonitoringSignificantLocationChanges needs to be on to wake up the app after reboot. For me the difficult part was figuring out when to turn it on, because I couldn't find a reliable way to detect when the phone is being rebooted or run any code at that point. However, based on initial testing it looks like startMonitoringSignificantLocationChanges is independent and doesn't negatively impact the usual location updates, so now I just leave it on all the time and toggle startUpdatingLocation / stopUpdatingLocation on top of it based on Core Motion-detected activity.
Otherwise requirements are the same as for any location tracking on the background, i.e. handle permissions and don't process too much. Apple documentation explains how to detect that the app was relaunched by a location event.
Here's a react native module which basically helps you achieve what you're describing: https://github.com/transistorsoft/react-native-background-geolocation

Getting continous user location and based on that sending information to server

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.

Core Location, iBeacon & Region Monitoring

I am looking to make an App similar to that of the iOS reminders app. Where a user can essentially set reminders to go off when a user has entered or left a certain area.
I am new to iOS app development and have been doing some research into what might be needed but I am getting a bit confused and was wondering if someone could clarify a few things for me.
From my understanding:
Core Location is used to get your current location details
iBeacon is used to set your device as a Beacon for others to discover
Region Monitoring is used to monitor for when you enter a specific region
Am I correct in my assumptions? If not could someone please correct me. Also am I looking at the right kits that will help me achieve this?
What I would like to do is have a table of saved records that are triggered individually when they enter or leave there specified locations. (Do I use Region Monitoring for this)
Also how would I make this app still run in the background, once it is closed, and still trigger events (like the iOS Reminders App).
I have found a few basic tutorials that help me get my current location with CoreLocation but does anyone know of any other tutorials that might help me out? Or know themselves how I can go about accomplishing this.
Would really appreciate some help. Thanks!
I think that the best choice for your app is using Region Monitoring:
You could register up to 20 regions;
iOS will launch your app automatically if iPhone enters the observed region.
From Apple docs:
If a region crossing occurs while your iOS app is not running, the
system automatically wakes it up (or relaunches it) in the background
so that it can process the event. When relaunched, all of the regions
you configured previously are made available in the monitoredRegions
property of any location manager objects you create.
An app can register up to 20 regions at a time. In order to report
region changes in a timely manner, the region monitoring service
requires network connectivity.

Processing network calls from background. Is it allowed by Apple?

We are working in a groupon-like app where alerts are displayed to the user when he/she enters in the range of an offer.
The client insists on having alerts even when the app is in the background.
Due to the architecture of the system, the app gets the location of the client at intervals and checks with the server if there is any new alert. If so, the app does some processing in the local database and displays a notification.
APN cannot be used since changes in the server are out of reach for this project.
My question is whether Apple would accept it in AppleStore as I have read different opinions about it and Apple discourages its use as in this extract from iOS Developer Library
http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html
At wake-up time, your app is put into the background and given a small amount of time to process the location data. Because your app is in the background, it should do minimal work and avoid any tasks (such as querying the network) that might prevent it from returning before the allocated time expires. If it does not, your app may be terminated
Thanks
How often does your app get location from the user? According to Apple's Background Execution and Multitasking, if you are getting the location updates on a regular schedule (I think it's less than 10 minutes), your app can still process in the background if you add location to UIBackgroundModes in your info.plist. With those CLLocation coordinates, you can then process your web service requests.
I personally have not done something like this, so I can't tell you for sure if Apple will reject your app or not. However, if everything is within the guideline and requirements set by Apple, I don't see why they would reject your app.
EDIT:
From the Apple doc:
An app that provides continuous location updates to the user (even
when in the background) can enable background location services by
including the UIBackgroundModes key (with the location value) in its
Info.plist file. The inclusion of this value in the UIBackgroundModes
key does not preclude the system from suspending the app, but it does
tell the system that it should wake up the app whenever there is new
location data to deliver. Thus, this key effectively lets the app run
in the background to process location updates whenever they occur.
I guess even if the app is suspended, it will wake up whenever there is a new location data to deliver.
I think you should reconsider your approach for this application. It sounds like you have decided to build a set of features which are not necessarily well informed by, or a good fit for, the characteristics of the devices the app will run on.
You write that "the app gets the location every n minutes" but that's not how iOS location services work. Querying location services for the current location occasionally is a good approach when your app is running in the foreground but that's not an option once it is suspended or terminated. Instead you need to subscribe to location events, at some level of accuracy, and your app will be notified when the device's location changes. There are no guarantees about the schedule on which you receive these events and it varies depending on the accuracy you request and the speed at which the device is moving.
Additionally, obtaining a location is an expensive operation and can quickly drain the device's battery. Burning through a user's available battery power in an hour or two is a very good way to get your app uninstalled quickly. Where possible you should be using the significant location change service to get low accuracy location updates with minimal power consumption. If you need more precision then consider using boundary crossing events for a defined region or at least reduce the accuracy your have requested as much as possible.
With all that out of the way you still need to work within the limited time your app has to run once started by a location update. That's probably not long enough to make a round trip to the server. If a network connection is already active and the device happens to have low latency you will probably get a response some of the time but I would expect to see the app terminated by the OS frequently. When that happens I don't know that you will continue to receive location updates which might otherwise re-launch the app.
Instead of downloading a list of alerts and displaying them locally a better solution might be to attempt to send your current location to the server via UDP when you see a significant location change. That way you can fire off a network request without waiting for a response. Only some of those requests will still succeed but at least your app won't be terminated. You can then process the locations you receive on the server and send push notifications when appropriate.
I realize that you don't seem to be able to make server side changes. In that case the best you might be able to do is pre-fetch alerts for the nearby region when the app runs (and if you ever manage to complete a round-trip while in the background). That way you could compare location updates to that list and not need to fire off a network request on every location update. Unfortunately it sounds like you might be backed into a corner here with no reliable solution available under your current constraints.

iOS: Start uploading user location after request from server

I need to achieve this: I have an app, which wants to keep track of location of family members. Since I don't want to keep the GPS running all the time, I was thinking I could just send a request from server, when some family member wants to know my location.
But I ran into some problems:
I can't use PUSH Notifications, because those need to be confirmed (tapped on) and only after that the app knows something happened. (This would not be great, since kids probably wouldn't tap the push notifications)
The other option would be to keep the app running in the background, checking server for any news and if it found some request on server only then start the GPS tracking and upload coordinates to server. This sounds a bit better, but also battery draining.
Did anyone already try this? Is there any better way to this problem?
Thanks for any reactions! :)
Yes, I think the only option for you left is run Location Services in background.
For this in Plist set for Required background modes to App registers for location updates. This will enable you to send location updates as you want.
But note that this will only work when application is running or in background, and it will not run when you application is closed. If user closes your application, then you can fire push notification if you done get any updates from device.
Also, note that you need to mention in description of your application, that Application uses location services which will drain your battery, otherwise your application will not be approved.
Hope this info helps you..
We had similar problem in our application. We followed the approach that keep listening to push notification port, whenever we receive any notification, then check if it's for our application and then react accordingly.
We can have listening to port on long time to save battery draining.
Sorry cannot share any of the code with you, but I hope this might be some help.

Resources