I am working on Location Tracking Application. This application continuously send location even in background. I am using SLC property.
I am also using silent push trick for location tracking. Logic of Silent push:
Check AppIconbadge number and perform the action according to AppIconbadge number. I have a timer which check AppIconbadge at every 10 seconds.
Now this is the case:
Device is on SLC and put the app in background and turn off the device. While you switch back to On this device it is still reporting on SLC while Ping (Silent Push) is not working.
I have started the timer when app get SLC trigger. But its not working.
Can you help?
You can't do it.
The way iOS achieves great battery life and reduces RAM usage makes this kind of thing impossible.
Your only real possibility is to have your server send occasional push notifications to the device, and have your app on the device respond with its location. This is how Find My Phone and Find My Friends both work. The idea is to improve battery life by doing as much as possible on a server, which has mains power and virtually unlimited RAM, instead of on the phone which only has a battery and might need all it's RAM to play a 3D game
Basically the CPU is not running at all most of the time, so it can't schedule stuff to run periodically, and you can't rely on there being enough RAM available to run your app so it also can't be running all the time even if the CPU is powered on.
According to the WWDC 2013 keynote, push notifications are much more powerful on iOS 7, so you should look that up (I haven't looked into it myself, just saw the keynote.
Related
I need to make an app that records heart rate data in near real time and send this data to a server as soon as possible.
First I took this approach: Watch os 2.0 beta: access heart beat rate
In fact it is working fine. There is new heart rate data in the HealthKit every five seconds. But now I have the problem that I can't sync that with a server.
My first approach was the Watch app. The watch was sending data to a server. That doesn't work because as soon as the screen turns black on the watch, it stops sending.
My next approach was to query the HealthKit on the iPhone every five seconds for new data. This works, as long as the app is in foreground.
Then I saw that there's some kind of background functionality that watches the HealthKit itself and revokes the app from background and you can do something.(enableBackgroundDeliveryForType) This doesn't seem to work for heart rate (the Apple Documentation says for things like steps this doesn't work, I guess heart rate is one of those).
I'm stuck now. Do you know how to it? I would need some background task that is executed every 5-10 seconds on the iPhone. That seems to be impossible
UPDATE
As noticed by #BootMaker, Apple made background mode available for HKWorkout apps in WatchOS 3, so it's working now. You have to run a HKWorkoutSession and this will keep your heartrate delivery in real time even when the app is in the background (dark screen on watch)
The closest you are going to be is while the watch app is open.
Why I'm stating this?
There are two HealthKit's Database (one at the iPhone and another at the Apple Watch). When they sync is arbitrary and decided only by the O.S.
The closest you are going to be to real time is when you don't have any password locking your screen in iPhone or Apple Watch.
Either way, there's no guarantee that the sync will happen every time a new measure is added to Apple Watch's HealthKit
The only way to force the Heart rate sensor into working in real time is via workouts or observer while your Apple Watch app is in FOREGROUND.
Background delivery is NOT available for Apple Watch apps.
Watch OS 2 request the sensor to measure automatically (in background) every 10 minutes minimum.
There's no other workaround, if you need real time for longer periods, or while the user is not using your app, you will need to use an specialized wearable.
If anyone still need to get heart rate or other data in real time. Use this solution:
Develop an apple watch app/extention
In watch app, using HKHealthStore, HKWorkoutConfiguration, HKWorkoutSession, HKLiveWorkoutBuilder to create an Workout. After create workout, your watch app will get heart rate in real time.
Using watch kit connection with WCSession to send data to iPhone app.
Enable background mode both in apple watch and iPhone.
I tested, even app terminated, we can still get heart rate (I used Local notification for posting heart rate data for debugging)
I have a location based application that needs to run in the background. I have several iPhones that I am testing on including a older 3G. I register my app to need background location based services and everything works as advertised accept with the older 3G phone. When you press the lock button, it does an applicationWillResignActive: as expected, unfortunately the phone immediately goes into low power mode and that is that. When you have the phone tethered with the USB cable, and then press the lock button, the 3G phone stays alive and correctly reports location changes. When it is disconnected, it goes immediately into low power mode.
The strange thing is that I am pretty sure that it used to work. I want to see if anyone out there has an app running on an older iphone (3G) which registers for location services and is not immediately put into lower power mode when the lock button is pressed. If so, what am I doing wrong.
I followed all the directions, have locations in my Info.plist.
Thanks for your help!
Cheers,
Bryan
I think you are seeing expected behavior.
I noticed on a recent trip with my old 3g the Location Manager appeared to remain active only when the usb supplied power. On usb, unlocking the phone would bring the app up (google maps in this case) immediately with Location Manager active. Without usb, I had to relaunch Location Manager each time I unlocked the phone.
I strongly suspect this is safety/power-saving feature. The Location Manager sucks battery life at a startling rate, especially on older devices. By running the Location Manager continuously while on battery, you could easily flatline a user's phone without their knowledge.
I would be very leery of any design that requires the Location Manager to run continuously in the background. Test it throughly.
You don't want the economic consequences of users deciding that "when I use Bryan's app, my battery mysteriously dies" or the moral consequences of leaving someone in an emergency without a working phone.
I am developing a voice recording application that communicates with the server real-time, therefore requiring persistent Internet connectivity. I have included UIRequiresPersistentWiFi in my info.plist and have also disabled device going to sleep when the app is active. However, this understandably has a serious effect on the battery life of the device. Users end up having to leave this continuously plugged in. For an app that is touted as meant to replace handheld recorders, this is a serious shortcoming. My app also has many xml threads sent from iPhone to server, so wireless connectivity is of paramount importance.
My questions are:
1. Is it possible to somehow switch on UIRequiresPersistentWifi status only when required during a session. For example, can this be switched on only during transfers or xml updates to server and be switched off at other times?
2. Likewise, can IdleTimer be enabled and disabled programmatically at will during a session. For example, enabling idletimer only when no foreground or background tasks are running on the device.
Any other suggestion to ensure normal battery life? All my users will be on iTouch 4 or iPhone 4.
Any help/suggestions would be greatly appreciated.
Answer to part 2: Yes, you can enable and disable the idle timer depending on what the user or app is doing, and how long it's been. I know of a couple apps that disable the idle timer, but then re-enable it if the user doesn't touch any UI elements for 10 minutes, but then re-disables it if the user starts some long operation again. etc.
Partial answer to part 1: Using the radios (sending wifi data) takes power. A good way to save power is to not send data for as long as possible. Maybe buffer large amounts of data on the device, and try to burst upload it later.
My suggestion would be to not communicate with the server continuously, sorry :(
Is it possible to cache chunks of data into a file on the phone and transmit the chunks to the server periodically in one big burst? Same for the XML. Or does your app really really require it to be broadcast real-time?
And as far as I know, if you have specified UIRequiresPersistentWifi, you're stuck with it :(
Sorry, probably not the answer you want!
I'm currently testing the latest iOS4 Feature to put my location aware app in the background. Well, it does work! But on the other hand it's quite hart to handle the immense power usage.
The app consumed about 50% battery power in the last four hours. It read the entire official documentation by Apple on this topic but I'm still not sure which parts of my application are still running and which functionality is suspended (beside the UI Drawing, which should be clear).
I don't use any real boilerplate code but extended libraries like ASIHTTPRequest to talk to my webservice. Tests with a friends car did you show that the Network Connectivity and and the Location Services is still running when I'm using i.e.
[locationManager startMonitoringSignificantLocationChanges];
Apples Documentation on the different application states
Background: The application is in the background and executing code
[...]
Should I write a "bare metal" functions to receive and send this location data? Should I remove all other objects for the time the application resides in the background to reduce the memory footprint? It seems there isn't any best practice yet.
Any ideas? Maybe you guys can provide me with some of your insights. Thanks.
Edit:
There's a new Instruments tool called Energy Diagnostics Instruments to record any power usage (for iPhone 3GS and later) with an attached device. Also there's another service on the device in the Settings App -> Developer -> Power Usage. It's great to test your power usage in field. The created logs can be pulled later in instruments.
Reference: WWDC 2010 Session 309 - Advanced Performance Analysis with Instruments
Sounds like your app is transmitting location data over the cellular network. Turning on the cellular radio is one of the most rapid causes of power drain, especially if the user has a weak signal connection to the cell tower.
You might want to save and package up a bunch of location data, and send the data in a quick burst as seldom as possible (twice per day, when the user stops moving for 30 minutes, only after the user gets to one of their favorite restaurants, etc.) Turning on the radio less than half as often could get you close to doubling the battery life (unless the user is doing something else with the device as well).
Ever since the first beta came out I’ve been trying to find out if “real” multitasking is possible — i.e. can you put a program in the background and have it hang on to a network connection indefinitely?
I’m thinking about IM or IRC apps, for example. I’ve compiled an app myself on iOS 4, and without changing a thing it appeared to stay running in the background, but for all I know it was just suspended to memory.
The docs say the best you can do is request up to 10 minutes, but in the developer presentation they showed off Skype sitting in the background and then notifying the user that a call was coming in. Does anyone know for sure how this all works?
It appears the answer is no. The API for Skype is a very special case, called the "voip" mode, and requires special behavior, such as marking the socket in use for VoIP.
You can receive alarm notifications in the background (such as time passed). The amount of time you are in the background running state is severely limited by the OS.
Android's background model is complete and in many ways much nicer.
Apple has a guide named "Supporting Multitasking In Your Applications" which you should be able to locate.
Apple's iOS 4 developer docs outline this all very clearly.
When your app is closed or switched away from, it is almost immediately "suspended", meaning the OS freezes the app's state. When the user switches back to your app, your code keeps running just where it kept off. You don't need to add any code to your app to do this, just compile it against OS 4.
The above is true in most cases. There are two reasons the "suspended" model may not apply:
1) If the device starts to run low on memory, the OS will start terminating suspended apps that haven't been switched to in a while, without warning. This is why it's in your best interest for your app to remember it's state as well, so if your app is terminated, then re-opened, the user doesn't really notice because it still returns to right where they left off.
2) Your app uses one of the "background" APIs. These are for audio playback, VoIP services, or location services. In this case, your app is allowed to continue running in the background but only has access to those APIs. Additionally, your app can designate certain long-running tasks as "background tasks" that need to be completed before the app is suspended or terminated, like uploading pictures to Flickr or rendering a video, etc.
The "background task" method doesn't cover pinging servers indefinitely, as there is a time limit for the task, after which it will be forcibly halted. Apps that need that sort of functionality are expected to implement push notifications, just as before.
That should clear this up. All in all I think it's a pretty elegant solution to multitasking on a mobile device.
iOS 4 applications can either be running or suspended. The operating system will try to keep as many requested applications as possible in memory, while all other applications are suspended.
Applications that run in the background can access features such as navigation, audio, and VOIP (but NOT instant messaging). So it looks like you might be out of luck.
-- PC World Multitasking on Apples iPhone 4
It is possible for apps to request background time. Read the docs. I would say it iOS is "controlled multitasking".
You can create a long running background task, I believe these can include networking features. Just have to set the background task flag on the work block.
https://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
the OS can limit exactly how much time you get though... it will tell you when your time is up giving you a chance to cleanup nicely.
iOS 4 has "real" multitasking to some extend. There are two things to consider:
The UI event loop is single tasking. So only the front app executes on the UI event loop. Not a big deal: detach your main code form the UI event loop (maybe you need to redesign your app).
The OS "may" terminate your app if some criteria are met (e.g. low memory).
Currently one of these criteria is that execution time is limited to 10 minutes (real time not cpu time). However I expect this to change and see better criteria for background app termination (I hope to).
Apart from this you can have timers (event loops) in background.
There is no real multitasking in iOS 4.2 even. because apps will only be allowed to finish the task related to states..for small interval of time and then it will be in suspended state.. If you will set background task for long interval of time then... it will behave unexpectedly like no method will be called when you will try to run the app from anywhere..
You may be interested in this blog post that outlines how "multitasking" works in systems such as iPhone OS 4 and Android.
in fact u can do this, although it's not allowed by Apple. u gotta set up a toolchain in ur mac and use some unofficial SDK...
check http://code.google.com/p/iphone-backgrounder/ for more information
You should use the Push Notifications framework for the feature set you are creating!