In my app for iPad, I have a requirement that I have to post some data almost after each 30 sec. So for that I'm creating a new http request every time and adding the request to a queue.
Is there any other efficient way to do so?
Related
I have an app that is firing a lot of initial Alamofire GET Requests to an API to eventually collect the data. However there are buttons on the app screen which also fire off POST requests to save etc. Though when i tap on the buttons, the alamofire requests take a long time to fire off due to the fact all the other GET Requests are still running.
Is it possible to make it so I can push the POST request ahead of the queue?
There is no way to do this using Alamofire or the underlying URLSession APIs. What you'd want to do is build your own request queue that lets you keep perhaps half a dozen requests in flight at any time. You would enqueue all of your GETs and then push your POSTs to the front of the line when needed.
I want to make my app more responsive when there are problems with getting data from server.
Right now I am using Reachability library to check access to Internet but i think that it is not enough. Sometimes server can handle request for long time or even be down and not responding.
In cases when network requests take too much time I want to notify user that something went wrong, not showing endless activity indicators.
Where to start from? What are the best practices?
Set a custom timeout interval for the URLRequest. It should be ideally
depending on the amount of data you expect the server to send and the
internal queries the server does to fetch the data and finally dump
the same to the API you are using.
Try using postman to get an idea of server response time and the data you received. Based on that estimate a justified timeout interval for your request.
let request = NSMutableURLRequest()
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.timeoutInterval = 20 // this is what you need to set.
You can then provide message or response to the user through some message. As far as connectivity is concerned, you could look at the YouTube app, try putting device on flight mode and you'll see the strip which shows connectivity status without intruding the user experience.
First i would suggest add a loading before checking internet, and dismiss the loading when you received anythings from the URLRequest.
Second, you can set your custom timeout interval for URLSessionConfiguration, so that it wont hang in there
fyi: https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1408259-timeoutintervalforrequest
I'm experiencing slow response times for my first http POST request to my server.
This happens both in Android and iOS networking libraries. (Volley on Android, and Alamofire in iOS).
First response is roughly 0.7s-0.9s, whereas subsequent requests are 0.2s.
I'm guessing this is due to the session being kept-alive by the server, therefore eliminating the need for establishing a new session on each request.
I figure I can make a dummy request when the app starts to start the session, but it doesn't seem very elegant.
I also control the server side (Node.js) so if any configuration needs to be done there I can also try it.
Investigating a little further, I tried sending an https CONNECT request before issuing the first "real" POST request, and the behavior replicates.
After 30 seconds or so, the connection is dropped (probably at the iOS URLSession level, the load balancer is configured to keep connections as 60 seconds).
In theory this makes sense because setting up an https connection takes up several (12 total) packets and I'm on an inter continental connection.
So my solution is to send a CONNECT request when I expect the user to send a regular request.
I have an app that lets the user send messages with images. A user might hit send, then immediately close their phone or switch to another app.
We were running into an issue that if there's temporarily a bad network connection the message would fail to send. We switched to using NSURLSession backgroundConfigurationWithIdentifier so that backgrounding the app doesn't immediately time out the running request. We switched to using this for all our api requests, thinking that it wouldn't hurt for every request to able to continue in the background if the app were closed at the wrong time.
Fast forward a couple weeks we're noticing all requests seem slow. Using wireshark I just discovered that this background session seems to use a new http connection per request, meaning it requires setting up a TCP connection and new TLS handshake for every request, which was adding a ~500ms latency on every request in our app. This is a pretty big deal but I can't find this behavior documented anywhere, including the link above or Apple's background transfer considerations.
So my question is, is this behavior expected, or am I doing something wrong somewhere? Is there an easy way with NSURLSession to make an HTTP request that will use an existing keep-alive connection if there is one, but can fall back to the backgroundConfiguration if the app gets moved to the background?
NSURLSession is the recommended way to fulfill your use case. Have you tried setting backgroundSessionConfig.discretionary = true
iOS Reference
A Boolean value that determines whether background tasks can be
scheduled at the discretion of the system for optimal performance.
If that doesn't help, I recommend filing a bug with iOS.
I have an iOS application where I POST transactions to an API each time a transaction is completed. Once I get a 200 response code from the server I update an attribute on the transaction:
newTransaction.Synced = true
Incase the network connection ever drops I also POST every transaction where Synced = false when Reachability detects a network connection.
In perfect network conditions this works wells. However when I enable the Network Link Conditioner on my iPad and set packet loss to say 40% I start to see duplicated transactions on my server. What I assumed was happening is that it was taking longer than 30 seconds (the client side timeout on the request) to send my request and get the response from the server due to the high packet loss.
To confirm this, I made my API Sleep for 40 seconds for each web request and disabled Network Link Conditioner. As expected, the iOS app never set the Synced attribute to true as it was timing out before it got the response. However the server still created the entity for each POST request that was generated each time the iOS app launched or got network connectivity.
What's the best way to handle this situation so that duplicates never occur? I did think of adding a GUID to the transaction and then coding the API not to re-add the transaction if the GUID already exists. However the flip side is the iOS app would still never know the transaction has successfully synced. Is there a better way to handle this? Perhaps a timeout on the request which the server also adheres to?
Your Idea of assigning the GUID to transaction is good, but you might need to maintain a table on client side (browser memory) which will hold a record of all the calls you made to server and never heard back.