iOS swift send message after idle for more than 30 seconds

Hi There,

I'm fixing chat application bug right now. The problem here is when i send message at offline mode and go to background mode. I can only resend the message automatically under 30 seconds after go to background mode.

If i don't go online after 30 seconds. I cannot send the message automatically from background.

I'm using this function
Code Block language
func beginBackgroundTask(expirationHandler handler: (() -> Void)? = nil) -> UIBackgroundTaskIdentifier


I have also tried to changed the duration in AppDelegate with this function from
Code Block language
application.setMinimumBackgroundFetchInterval(UIApplication.backgroundFetchIntervalMinimum)


to

Code Block language
application.setMinimumBackgroundFetchInterval(UIApplication.backgroundFetchIntervalNever)

or
Code Block language
application.setMinimumBackgroundFetchInterval(3600)

but still, it doesn't working. It only give us 30 seconds for the maximum time.

Is there any solutions to resend message at the background mode automatically after 30 seconds ?

(WhatsApp can do this, so it should be possible)


iOS will only provide your app with a limited amount of background task time. IIRC that limit is currently 30 seconds, so what’s happening here is that your app is being suspended 30 seconds after being moved to the background at which point it won’t be able to do any networking.

Is your chat protocol HTTP[S] based? If so, one good option here is to retry your send using an NSURLSession background session. This passes the request to a system daemon which will send it when conditions improve.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
is NSURLSession supposed to be used for download/uploading data file?

As i using websocket also for sending / receiving chat messages

is NSURLSession supposed to be used for download/uploading data
file?

NSURLSession is a general-purpose HTTP[S] API. The NSURLSession background session feature is optimised for large transfers but there’s nothing stopping you using it for small transfers. I wouldn’t do this in general, but it can be helpful in a situation like this, where you have a small transfer but have run out of background time.

As i using websocket also for sending / receiving chat messages

OK. In that case this suggestion won’t work because your can’t run WebSocket requests in a background session.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
ok, so if i'm using websocket, sending messages in background mode is not possible at all?

I also tested it on several apps such as Line, Skype chat, Slack, Telegram, FB Messenger, Siilo. They have the same issue, can't sending messages in background mode after 30 seconds going offline.

But, the only application which i have tested and do well for this background messaging is Whatsapp.
They must be using other method than Web Socket then?
Hi @eskimoo, What if we are sending JSON data to server via POST request. Is there a possibility way it could sent from background ?

if i'm using websocket, sending messages in background mode is not
possible at all?

Correct (assuming you substitute “while suspended” for “in background mode”).

Note It’s important to distinguish between:
  • In the background

  • While suspended

The fact that you’re in the background doesn’t mean that you’re suspended. If you’re running in the background, it’s just like being in the foreground as far as the networking stack is concerned.

They must be using other method than Web Socket then?

I don’t know, and I’m not in a position to reverse engineer other developer’s apps on your behalf.

What if we are sending JSON data to server via POST request. Is there
a possibility way it could sent from background ?

Yes. This an HTTP[S] request and you can issue those via an NSURLSession background session as I mentioned earlier.

However, it’s important to realise that NSURLSession background sessions were designed to support large background transfers, not small requests with tight latency requirements. There’s no guarantee that the system will run your request as soon as it comes back on to the network. In many cases the background session will delay the request until the environment is appropriate for a large transfers.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
ok, i'm trying NSUrlSession now, is it this you mentioned about? https://developer.apple.com/documentation/foundation/url_loading_system/uploading_data_to_a_website
Hi, i am trying this code, but it looks like it didnt work, is it the wrong usage?

Code Block
func postAction(_ sender: Any) {
let Url = String(format: "your url")
guard let serviceUrl = URL(string: Url) else { return }
let parameterDictionary = ["username" : "Test", "password" : "123456"]
var request = URLRequest(url: serviceUrl)
request.httpMethod = "POST"
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameterDictionary, options: []) else {
return
}
request.httpBody = httpBody
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
}


iOS swift send message after idle for more than 30 seconds
 
 
Q