I am a little bit confused about this question.
Somewhere I read, it is not allowed by Apple to make network requests, when an app not in the foreground. Is also the case, when app is woken up by locationManager events?
What I'd like to: define a Beacon region, handle locationManager:didEnterRegion: and locationManager:didExitRegion: to call my simple web service methods. It should be done even if the app is not active and woken up by location manager.
Technically it is easy to implement - basically, I have already made it - but I don't know if it is allowed by Apple, and would take app review successfully.
Thanks!
Yes, it is allowed. It is a common technique, and I have several apps in the AppStore that do this. The Beacon Scavenger Hunt, for example, sends stats back to our server when participants use the iOS app to find beacon targets in the hunt.
When you detect a beacon in the background, however, you only have about 5 seconds of running time from iOS. Take care that your server responds quickly enough. This small time window is the way Apple enforces that people don't abuse this.
Related
i want to wake up my app after app terminated using background modes...
i know using location update and push notifications we can do.but i don't to use those. apart from those is their any way to wakeup my app.
actually i need to connect my app with websocket even app was terminated.
is their any way to wakeup app using core motions. or using microphone(i mean if app catches any data of voice(sound))..
can any one explain app life cycle (when it will wakeup and when it will sleep)
thanks u
Even if there is a way (actually there are some tricks with beacons but user would have to be in the range of beacon specified by you) it shouldn't be used like so.
If your app is kind of weather service or newsfeed, iOS device will be woken up at intervals specified by you (not less than 1h) to check for necessary data.
Using microphone or core motion to wake up your app probably won't pass apple review.
To fully answer your question I would have to know reason for background mode.
According to your requirement "i need to track device motion activity", you could use the queryActivityStarting() provided by apple API's.
This gathers and returns historical motion data for the specified time period:
let activityManager = CMMotionActivityManager()
activityManager.queryActivityStarting(from: lastTimeAppCollectedData, to: now, to: queue) { (activities, error) in}
This returns you an array of activities/error that happened in the given period
It still wont wake your app up, but will allow you to query the events after they happened.
You can use CLRegion for geofencing as soon as user exit the region boundary, your app will get open with didExit delegate of CLRegion and after that you can use startActivityUpdates of CMMotionActivityManager to keep your app open till you want.
Resources:
Region Monitoring
No once app is terminated you don't have any access to app until app is opened by user. Even location update and push notifications only work in background.
My iOS app (which targets iOS 8.1+) use location services to determine if a user has entered a particular region during an event. Ideally I would like to enable the geofencing a little before the event and turn it off a little after the event completes. The problem is there is no guarantee the app is running an hour before the event so I turn on geofencing at the point the user registers for the event. This is not the best approach as it means the geofencing is on for much longer than it needs to be.
As far as I can tell, there is no way to "wake up" the app in the background at a scheduled time in iOS. I could use the push notification meant for updating content, but It's not clear to me if Apple would reject such a misuse of that notification.
Any suggestions?
I've been looking into this myself.
If you can arrange a push notification from your backend ("Silent push notification", aka "content-available"), it seems to be a good option. In real-world situations, this seems to give you the best control over the timing. Unfortunately, it won't work if the person doesn't have connectivity. Also, unfortunately, you need a backend that can queue events at a time (not just in response to an input.) If you have such a backend already, and your app is only useful to the user when they have network coverage anyway, this is probably the best option. It seems this an appropriate use of the technology, so Apple should approve.
Another option I'm trying is to use background fetch. You specify a "minimum interval" to avoid too much fetching. Try 50% of the remaining time-to-event as a minimum. Every time the app wakes up (whether in the foreground because the user opened it, or in the background because background-fetch opens it) you can calculate the time-to-next-event, update the fetch interval, or start the region monitoring. You are supposed to use "background fetch" to fetch information from a server, but there doesn't seem to be any requirement to poll a server, you could poll your internal data instead. I haven't fully tested this yet but it seems promising.
You can use significant location change monitoring, which I've read will wake up your app briefly every 15 minutes or less, and you can use the time/location information to decide whether to turn on the geofence. I think this would work well in combination with the above "background fetch": Many hours or days before the event you rely on background fetch, which you then use to turn on significant location change monitoring a few hours before the event. (There's speculation that geofencing is actually more battery efficient than significant change monitoring, but you could choose to assume that other apps on the user's device will already by watching for significant changes, in which case the marginal cost of your app adding itself to the list should be minimal.)
Putting them all together, you could create a sequence of
background fetch -> significant location monitoring -> geofencing
as the time gets closer.
There is also the CLVisit monitoring functionality, it's not understood very well, but supposedly uses less power and is called less frequently than significant location change monitoring. If the background fetch or silent remote notifications aren't working to wake up your app, give this a try, and please report back!
You can't (yet) do a silent content-available local notification (AFAICT). However, perhaps you can schedule up a local notification "Your event starts tomorrow" or something that convinces the user to click the option that starts the geofence. Here's a tutorial on it http://www.appcoda.com/local-notifications-ios8/, the response of action can be UIUserNotificationActivationMode.Background so your geofence can come on (if the user responds to the notification) without bringing the app to the foreground.
It's been 5 to 6 weeks since you asked, do you have your own answer already? Please let me know.
I am developing a client/server app for a client where the clients are iOS devices.
One client module is for traveling salespeople.
My client wants the salesperson's app to automatically download it's local database when the salesperson leaves the office, and when the salesperson returns to the office.
I am setting up a geofence using the location manager's startMonitoringForRegion method, and will look for the UIApplicationLaunchOptionsLocationKey on launch, as well as looking for calls to the location manager locationManager:didEnterRegion/locationManager:didExitRegion methods from the background.
My question is, how do I ask the system to allow me time to make a network connection and download new data in response to either an app launch with a UIApplicationLaunchOptionsLocationKey, or background calls to locationManager:didEnterRegion/locationManager:didExitRegion?
None of the background mode keys (UIBackgroundModes) look like the right fit.
I don't need the location key, since I don't need live location information, just geofence enter/exit messages. The fetch key isn't what I need either, since that causes the system to wake my app up in the background at times it chooses.
Do I have to have one of the background mode keys set in order to make a beginBackgroundTaskWithExpirationHandler call?
I guess what I should do is submit my network request in my beginBackgroundTaskWithExpirationHandler in my locationManager:didEnterRegion/locationManager:didExitRegion methods. Will the system allow me to do that without having a UIBackgroundModes key set?
And can I make a call to beginBackgroundTaskWithExpirationHandler if I'm already running from the background? (In the case where the app is running but not frontmost and a locationManager:didEnterRegion or locationManager:didExitRegion call comes in.) My goal is to ask for enough background time to process my network download and save the data to my local database.
Any guidance from somebody who's done something like this would be a big help. The docs are pretty vague, and figuring out how to use the background APIs by trial and error is likely to be pretty time-consuming.
P.S. I'm developing this app in Swift, although I'm a longtime Objective-C developer. I'm comfortable translating Objective-C to Swift or mixing Objective-C and Swift as needed, so examples in either language would be useful.
It is OK to call beginBackgroundTaskWithExpirationHandler from background. As of iOS8 this call will extend your run time to 180 seconds from 10s.
Keep in mind that you need to request Always authorization for location services, that's what is required to run region monitoring.
I suggest you do use the background location key. I forgot to set it in one of my apps, and it still was receiving the region enter/exit events. However,
-- the behavior might change with minor iOS upgrade, and also
-- the app might be rejected 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.
I have a requirement to develop an app that is capable of receiving pushed information from a server - which as its not possible to intercept SMSs or apple push notifications would probably have to be implemented as a poll and see what's there or similar type of thing.
However of course such a thing isn't possible if the app isn't executing in the background.
The app couldn't be considered to be musical or voip related, however its possible that it could be considered to be gps related as the pushed information would be displayed to the user based on certain triggers, and one of those triggers could be location.
Would this app with a UIBackgroundMode of gps submitted to the app store stand a good chance of being accepted?
i have been trying to do the same thing and here is what i found
iPhone - Backgrounding to poll for events
(top answer: update 2)
shows a method that should be ok, meaning your app wont be rejected for using it. the guy who posted it said it should be ok and i have asked other members who said the same (i have not verified this myself).
here is my implementation of that post
local notifications?
You don't have to use a hack for your requirements.
iOS provides a facility whereas your application is suspended but your socket is still monitored. If there's any incoming traffic on the socket, the app is woken up and handed back the control of the socket.
Advanced App Tricks
Look under the heading, "Tips for Developing a VoIP App"