i am implementing web service that sends data to my iphone. my iphone should ask web service for new data every 100 second. where is the best method to call the web service every 100 second ?
can you advice me for this issue ?
use 'NSTimer'
NSTimer* myTimer = [NSTimer scheduledTimerWithTimeInterval:100.0 target: self
selector: #selector(callAfterHundredSecond:) userInfo: nil repeats: YES];
After each 100.0 second , iOS will call the below function
-(void)callAfterHundredSecond:(NSTimer*) t
{
NSLog(#"webServiceCalledAfter100sec");
}
You can run your webservice and receive its data in background thread along with Timer which should run in foreground thread. Then you can sync between those methods with flag or whatever you wish. In this way your web service send response according to timer you set.
I had a kinda same scenario but for me availability of web service during the web service call was kinda critical so what I came up with was to use push notification for IOS/Android to keep pushing notification every 5 minutes, on notification received I was doing my calls and stuff this way I know that web service is up and running, my user is a in a range of 3G/WIFI. Since I was doing this for two way synchronization without user interaction and the users are mostly in remote area where there is no much internet available. At the mean time I use notification for some other stuff too, so thought I can use it here too. dont know it is a good idea but it really work well on over 100 devices.
Related
I've been trying to get an answer to my issue for weeks now without any luck.
I have an app in swift that displays a few labels on the screen. I want the label text to change everyday at midnight, and I want to be able to decide what the label should say from my machine.
I've been told to use either active listeners or cloud functions.
The video below shows a dev using firebase cloud functions to alter text in real time on an app.
https://www.youtube.com/watch?v=Z87OZtIYC_0
How is this any different from active listeners which also do the same?
Objectively speaking, what suits my use case more?
To execute a function at midnight to make a UI change first requires that the app is open. If the app isn't even open then there isn't a UI to update. Therefore, there is no sense in tasking the server with this function because the app may not even be open. And the task of updating the UI should be the responsibility of the client, anyway.
Therefore, create a timer on the client (in your app) that makes a call every midnight to get data from the server that populates the labels. What you need is to create a Timer object that fires in n seconds to midnight that has an interval of 1 day that repeats infinitely. It may look something like this:
var midnightTimer: Timer?
midnightTimer = Timer(fire: Date().addingTimeInterval(secondsToMidnight), interval: oneDayInSeconds, repeats: true) { (timer) in
self.updateLabels()
}
RunLoop.main.add(midnightTimer!, forMode: .common)
I just got asked to reduce the traffic made by my GWT app. There is one method that checks for status.
This method is an asynchronous call wrapped in a Timer. I know web apps are stateless and all that, but I do wonder if there is some other way to do this, or if everyone has a Timer wrapped around a call when they need this kind of behaviour.
You can check out gwteventservice. It claims to have a way to push server events and notify the client.
I have a feeling they might be implemented as long running (hanging) client to server RPC calls which time out after an interval (say 20sec), and then are re-made. The server returns the callback if an event happens in the meanwhile.
I haven't used it personally but know of people using it to push events to the client. Have a look at the docs . If my assumption is correct, the idea is to send an RPC call to the server which does not return (hangs). If an event happens on the server, the server responds and that RPC call returns with the event. If there is no event, the call will time out in 20 seconds. Then a new call is made to the server which hangs in the same way until there is an event.
What this achieves is that it reduces the number of calls to the server to either one for each event (if there is one), or a call once every 20 seconds (if there isn't one). It looks like the 20 sec interval can be configured.
I imagine that if there is no event the amount of data sent back will be minimal - it might be possible to cancel the callback entirely, or have it fail without data transfer, but I don't really know.
Here is another resource on ServerPush - which is likely what's implemented by gwteventservice.
Running on Google app engine you could use they Channel technology
http://code.google.com/intl/en-US/appengine/docs/java/channel/overview.html
If you need the client to get the status from the server, then you pretty much have to make a call to the server to get it's status.
You could look at reducing the size of some of your messages
You could wind back the timer so the status call goes out less often
You could "optimise" so that the timer gets reset when some other client/server IO happens (i.e. if the server replies you know it is ok, so you don't need to send the next status request).
My app is able to consume a wcf using ASIHTTPRequest. But the thing is that i need to check the server hour every one minute. So i need a request to the server every one minute. What is more, sometime i will need to refresh the clock every one second.
the app is a items auction so i need to get the hour no matter what.
so my question is, is this going to kill the iphone?
ASIHTTPRequest have a method to achieve this? making calls every XX time?
some good way to do it?
Thx in advance!
Assuming the data you are getting back isn't larger than the memory threshold, and you are properly managing memory on your end, AND you are performing an asynchronous request (or a request on a background thread), this shouldn't kill the app memory-wise or cause it to hang.
I do something similar, where every 2 minutes I ping my server for updates. I achieve this using an NSURLConnection and NSURLRequest, though I imagine ASIHTTPRequest is not much different. I typically use a recurring timer that, when invoked, calls a method which, using Grand Central Dispatch, sets up my request/connection and fires.
I have an iPad app that works both on and offline but when I am offline there are web service calls that will need to be made once online availability is an option again.
Example:
A new client is added to the app, this needs to be sent to the web service but since we are offline we dont want to slow the user down so we let them add locally and keep going but we need to remember that that call needs to be made to the web service when we can. Same thing for placing orders and such.
Is there some sort of queue that can be setup that will fire once we have connectivity?
I don't think the overhead of a heavyweight tool like MSMQ is needed for a simple action. You can use Core Data, persist managed objects with the data needed to call the web service, and only delete each managed object after a successful post. There might or might not be a way to capture an event when connectivity starts, but you can certainly create a repeating NSTimer when the first message is queued and stop it when there are no messages in the queue.
This library handles offline persistent message queueing for situations like you describe. It says alpha from a year ago, but I have confirmed it is used in production apps:
https://github.com/gcamp/IPOfflineQueue
My iPhone application supports a proprietary network protocol using the CocoaAsyncSocket library. I need to be able to send a network message out when my iPhone application is closed. The code that sends the message is getting called from the app delegate, but the application shuts down before the message actually goes out. Is there a way to keep the application alive long enough for the message to go out?
Bruce
The docs from Apple don't specifically state this, but the sense I get from looking around the Web and from personal experience is that you have about 4 to 5 seconds after the user hits the Home button to shut your app before your application actually terminates. The iPhone OS is controlling this so you can't block the termination to allow your program to finish first. Basically when your time is up, your program is killed.
There may be another solution, though. First I'd confirm that your code is really taking more than 5 seconds to run. Perhaps you can have it run in response to a button tap, and time how long it runs. If it is more than 5 seconds, you probably are running into this time out issue.
You might then find a way to trigger a message to be sent from a server that is always running. You should have enough time to trigger a remote action, which in turn could then take as long as it needs to run.
Or perhaps you could save the vital information to the iPhone file system on exit, and send that message the next time someone starts the application, which should theoretically give you enough time.
Hope this helps!
I assume you're already calling it from your AppDelegate's:
- (void)applicationWillTerminate:(UIApplication *)application
But as you've discovered there's no guarantee it'll be called or will be allowed to finish. There are a few options that may or may not work depending on what you're trying to do:
If you need the server to perform some sort of cleaning operation triggered by when the client app is gone then you could try watching for TCP socket closure on the server and treating that as the triggering event. But if you explicitly need to send data back with the closure this may not work.
If the data you're sending back is not time-sensitive then you can do like most of the analytics libraries do and cache the data (along with a uuid) on the client then try to send it on app closure. If it goes through, you can clear the cache (or do it the next time the app is run). If it doesn't, it's saved and you can send out when the app is run next. On the server, you would use the uuid to avoid duplicate requests.
If the material is time-sensitive then your best bet is to implement heartbeat and send periodic updated values to the server. Then when the client app dies the server times out the heartbeat and can use the last received value as the final closing point of data.
In either case, if an explicit closure event is required by your custom protocol then you may want to reconsider using it in a real-life mobile environment where things have to be much more fluid and tolerant of failure.
As others have noted, there's no way to be absolutely certain that you'll be able to send this, but there are approaches to help.
As Ken notes, you do in practice get a few seconds between "willTerminate" and forced termination, so there generally is time to do what you need.
A problem you're almost certainly running into is with CocoaAsyncSocket. When you get the "willTerminate" message, you're on the last run loop of the main thread. So if you block the main thread, and CocoaAsyncSocket is running on the main thread, it'll never get processed. As I recall, CocoaAsyncSocket won't actually send all the data until the next event loop.
One approach, therefore, is to keep pumping the event loop yourself:
- (void)applicationWillTerminate:(UIApplication *)application
{
// ...Send your message with CocoaAsyncSocket...
while (! ...test to see if it sent...)
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
}
I've also looked at putting this work onto a background thread and letting the main thread terminate, in theory letting us go back to Springboard while continuing to run for a few seconds. It's not immediately clear to me whether this will work properly using NSThread (which are detached). Using POSIX threads (which are joinable by default) may work, but probably circumvents any advantages of the background thread. Anyway, it's something to look at if useful. In my apps, we've used the "post next time we launch" approach, since that always works (even if you crash).