ExternalAccessory streams delegate not always called in background - objective-c

I am experiencing a bad issue with the EA framework.
Everything is working when the app is in foreground, when the accessory, I open a session, retrieve the streams, set their delegate and schedule the streams on the main run-loop
The accessory is pinging my iPhone every second, and these pings are read with the stream delegate. This ping is a kind of heartbeat : if the iPhone does not received any ping in for seconds, the user is alerted.
This app should work in background, so I have added the corresponding keys in my plist file
When the app run in background, everything work fine for 10-30 minutes, and suddenly, for 7-8 seconds, the stream delegate is not called ( but the ping is sent from the accessory), and then in one second, the delegate is called eight times (for all the pings sent during the last seconds)
It looks like my app is suspended for eight seconds, and then all the events that occured during this interval are queued, and then delivered later. The problem is that, as the application does not received any ping during these 8 seconds, the user is incorrectly alerted
I dont understand this behaviour. Does anybody ecounters the same issue ?
I am considering to poll the stream via a background thread, instead of scheduling them on the main run-loop.
Thanks,

Related

Network activity indicator and asynchronous sockets

I have an app which continuously reads status updates from a server connection.
All is working well with a stream delegate to handle all the reading and writing asynchronously.
There's no part of the app that is "waiting" for a specific response from the server, it is just continuously handling status updates as they sporadically arrive from the socket. There are no requests on the client side that are waiting for responses.
I'm wondering what the best practice would be for the network activity indicator in this case.
I could turn it on in the stream event handler, and off before we leave the handler, but that would be a very short time (just enough for an non-blocking read or write to occur). Trying this, I only see the faintest flicker of the indicator; it needs to be on longer than just during the event handler.
What about turning it on in the stream delegate, and setting a timer to turn it off a short time later? (This would ensure it's on long enough to be seen, rather than the short time spent in the stream delegate.)
Note: I've tried this last idea: turning on the network activity indicator whenever there's stream activity, and note the NSDate; then in a timer (that I have fired every 1 second), if the time passsed is >.5 second, I turn off the indicator. This seems to give a reasonable indication of network activity.
Any better recommendations?
If the network activity is continuous then it sounds like it might be somewhat annoying to the user, especially if it's turning on and off all the time.
Perhaps better would be to test for lack-of-response up to a certain timeout value and then display an alert view to the user if you aren't getting any response from the server. Even that could be optional if you can provide feedback (like "Last update: 5 mins ago") to the user instead.

Desing pattern for background working app

I have created a web-service app and i want to populate my view controllers according to the response i fetch(via GET) in main thread. But i want to create a scheduled timer which will go and control my server, if there becomes any difference(let's say if the count of an array has changed) i will create a local notification. As far as i read from here and some google results, i cant run my app in background more then ten minutes expect from some special situations(Audio, Vo-IP, GPS).. But i need to control the server at least one per minute.. Can anyone offer some idea-or link please?
EDIT
I will not sell the app in store, just for a local area network. Let's say, from the server i will send some text messages to the users and if a new message comes, the count of messages array will increment, in this situation i will create a notification. I need to keep this 'controlling' routing alive forever, whether in foreground or background. Does GCD give such a solution do anyone have any idea?
Just simply play a mute audio file in loop in the background, OR, ping the user's location in the background. Yes, that will drain the battery a bit, but it's a simple hack for in-home applications. Just remember to enable the background types in your Info.plist!
Note: "[...] I fetch (via GET) in main thread." This is not a good approach. You should never fetch any network resources on the main thread. Why? Because your GUI, which is maintained by the main thread, will become unresponsive whenever a fetch isn't instantaneous. Any lag spike on the network results in a less than desirable user experience.
Answer: Aside from the listed special situations, you can't run background apps. The way I see it:
Don't put the app in the background. (crappy solution)
Try putting another "entity" between the app and the "server". I don't know why you "need to control the server at least one per minute" but perhaps you can delegate this "control" to another process outside the device?
.
iOS app -> some form of proxy server -> server which requires
"babysitting" every minute.

Check for data on remote database every five minutes ios

What is the right way to check for data in remote database through http requests in objective c iOS. I am thinking of an nstimer that is called every 5 minutes. The nstimer will trigger a function with a thread in it. Is this the right way? Is this going to work when the app enters the background?
Any help appreciated.
The thread (as like all execution in your program) will pause when entering the background - and if it was waiting on a network response, that response will fail after the app returns to the foreground.
Moreover, you need to explicitly tell iOS when you are beginning a task that you would like to continue in the background (with beginBackgroundTaskWithExpirationHandler: on your UIApplication singleton) and when you have finished that task (with endBackgroundTask:). However, that is only up to a maximum of ten minutes, so I daresay you won't be able to, say, continue your NSTimers in the background. But yes, the method you have described is fine for when the application is in the foreground.

iPhone app sending data while closed

I want to send data to my web server while the app is closed. Is that possible? I've read I can send the position, but I waant to send some id of the phone too.
If it's not possible to have the app running, could I at least communicate with it from my server and then do stuff in the background?
Thanks
When the app goes into the background the applicationDidEnterBackground method on your App Delegate will get called.
In that method you can use the beginBackgroundTaskWithExpirationHandler on UIApplication object to start background processing.
Just realise that you don't get forever to perform tasks in the background. You can find out how long you have left by reading the backgroundTimeRemaining property in UIApplication if you need to know if you're running out of time.
If your processing is short you should be fine, but remember if your processing requires network access then you can't be sure how long that will take.

App stops receiving data from socket when UI scroll

I have an iPad app that receives data using UDP sockets. And it has a UIWebView to browse webpages.
But while doing scroll in the UIWebView, everything freezes and no data is received.
I've been searching and it has something to do with runloops and threads. But if the UIWebView can't run in another thread other than the main one, how can I receive data while doing scroll? It is critical to keep receiving data.
The project uses the AsyncUdpSocket class from Cocoa AsyncSocket that works quite well. And also the singleton class from Matt Gallagher. Everything is running in the main thread, UDP reception and UI.
Thanks in advance!
When you do a scroll, the runloop enters a different mode (UITrackingRunLoopMode) and stops responding to network activity on the main thread. This is done for performance reasons.
You should be able to schedule those updates on the proper runloop mode (UITrackingRunLoopMode I believe). Though, I wouldn't recommend this.
Instead, try setting up your UDP networking code on another thread (or queue, yay GCD!) and schedule callbacks on the main thread to update the UI. This will guarantee the networking thread has the proper runloop mode when getting data back on the socket.