-2

This question is an update to some outdated questions like:


I'm currently developing an simple mobile application for iOS by using Swift 4.

It's a messenger app like e.g. WhatsApp and because new messages must be delivered instantly the application must be able to check for new messages for the Users via Json request every minute.

var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid

func registerBackgroundTask() {
    backgroundTask = UIApplication.shared.beginBackgroundTask { endBackgroundTask() }
    assert(backgroundTask != UIBackgroundTaskInvalid)
}

func endBackgroundTask() {
    print("Background task ended.")
    UIApplication.shared.endBackgroundTask(backgroundTask)
    backgroundTask = UIBackgroundTaskInvalid
}


Till now - when the app is in background-mode after about 2 minutes the app is terminating, the getnewmessages-timer interval is stopping and it prints out "Background task ended".

How to use Swift to register an infinite-running timer (background-fetching) that calls the update messages function?

iOS background fetch for: An app that downloads and process new content regularly --> My messenger app

picciano
  • 22,341
  • 9
  • 69
  • 82
Jonas0000
  • 1,085
  • 1
  • 12
  • 36
  • Possible duplicate of [how to call function after every 1 hour?(Swift). Background fetch work when app is terminated?](https://stackoverflow.com/questions/37319143/how-to-call-function-after-every-1-hourswift-background-fetch-work-when-app) – Giuseppe Lanza Jan 25 '18 at 17:20
  • Its an Update to this question like I‘ve mentioned above. @GiuseppeLanza . Also this question was not answered with example code - just with an wrong explanation to the topic! – Jonas0000 Jan 25 '18 at 17:21
  • 1
    While you say that this is an update to the questions yourself posted on top of this one, nothing has changed either in the question or in the apple world. The answers you already have are still valid. You can't. While your app is terminated, there is nothing you can do. All you can do is to make your app compatible with the "Background fetch mode". Despite the name, you **do not** control how often the app is awaken by the system to fetch data. Short story: you can't every minute. – Giuseppe Lanza Jan 25 '18 at 17:23
  • Because they do something completely different than what you want to achieve here. To update your app every minute is impossible as it would be extremely expensive in terms of battery consumption. Apple simply does not allow that. Whatsapp adopts a different communication protocol: https://en.wikipedia.org/wiki/XMPP – Giuseppe Lanza Jan 25 '18 at 17:26
  • 3
    A messaging app wouldn't be polling the server for new messages, it would use sockets and push notifications. – dan Jan 25 '18 at 17:27
  • The point is that the answer didn't change. This question is a duplicate. If you want to know how whatsapp manages that you should be opening a different question. – Giuseppe Lanza Jan 25 '18 at 17:29

2 Answers2

2

You said:

the application must be able to check for new messages for the Users via Json request every minute

That is not advisable. You're going to kill the battery of the device and chew up the user's data plan if you do that. And Apple will simply not let you keep your app running beyond the 30 seconds that they allow apps to finish finite-length background tasks.

In Configuring background execution modes, Apple enumerates the specific sorts of tasks are allowed to keep the app actively running in the background (e.g. VOIP, music, navigation, etc.). Chat is not one of those tasks. And the App Store Review Guidelines are clear that background operation modes can only be used for their respective, designated purposes.

So, this begs the right question as to what is the right way for an app to tell the user as soon as there is data available on some server when the app is not active. The answer is push notifications. Yes, it involves a more complicated server architecture than you were likely contemplating, but it is the only way to achieve your desired UX of notifying the user of some incoming chat message in a timely manner. (Background fetch is the other approach, but it won’t be called anywhere close to the frequency that users would expect from a chat app.)

By the way, this technique of repeatedly polling a some web service should be discouraged while the app is active, too. One would generally use sockets, instead, so rather than your app repeatedly asking whether there is data available, the server will tell your app when there is data available for that open socket. It's far more efficient and will offer a much more responsive UX, too. Why wait for the periodic polling (even if a few seconds) when the socket can tell you immediately?

Rob
  • 415,655
  • 72
  • 787
  • 1,044
0

Instead of background app refreshes. What you should do is use post notifications.

1. A user X sends a message to Server to send to Y (Payload)

2. The server has a unique reference to the phone that user Y has 
and sends a notification to him, that he has received a new message from X.

3. If user opens the app, he will then download the new message.

It would be rational to think that this is how whatsapp works, as running background refresh every minute is draining on the battery.

This way the user is not polling for messages every minute, he will receive a new notification when a new message arrives.

This can be achieved with amazon's SNS service, the documentation is quite clear.

WeCanBeFriends
  • 641
  • 1
  • 10
  • 23