Sync application data between several devices - ios

I've got 3 devices and 1 application.
I make some changes on 1 device (collect milk from my cows). What is the best way server to tell other applications, that I've made this changes to reload data?

You can use the integrated iCloud feature allowing synchronization for CoreData managed objects. There are also some libraries using third party Cloud services like https://github.com/nothirst/TICoreDataSync

Push notifications could be an option. Once your server receives some changes it will issue the sync notification to all other devices which will initiate the sync.
Another option is where every device will periodically check, let’s say every 5 minutes, if any server changes available, and if so, then initiate the sync.

Related

Periodic background synchronization

Im quite new to iOS programming and now want to implement a periodic background synchronization to synchronize my server data with client data. What I want to achieve is comparable with Androids SyncAdapter where you can define a time interval (for example each 30 minutes) and the system will trigger the defined task automatically in the background.
Until now I could not find such mechanism for Swift 3.0 so I need to ask if somone has experience or some hints for me how I can achieve this.
What I want to do sounds quite simple:
When the app starts for the first time the app should setup a sync manager which automatically triggers a background task every 30 minutes. The background task is responsible to synchronize server and client data (using Alamofire).
How can I do that?
There is an iOS feature called BackgroundFetch, which you can set up for
regularly downloads and processes small amounts of content from the network
You can setup a minimumBackgroundFetchInterval.
In contrast to the mentioned Android feature, this interval is not guaranteed though.
The OS does some heuristic in a blackbox. It rewards you for using a "reasonable" (to the OS) CPU time/ power consumption and also for being used often by the user. On the other hand you get punished for draining the battery or (even worse) never being used/opened by the user.
See: Apple Sample and Apple Docs
Update: Since iOS13, BackgroundFetchis deprecated.
There is a similar, new API named BGTask, BGAppRefreshTask is the equivalent to deprecated BackgroundFetch.
See Apple Docs
Alternatively, depending on your needs, you can post a Silent (push) Notification whenever the users data changes on server side. A silent push wakes up your app without notifying the user, so you can fetch data and maybe inform the user by scheduling a local notification.
See: Apple Documentation
You can't. Apple doesn't allow 3rd party apps to have regular background time like that. You'll need to come up with another approach like implementing a silent push notification from your server when new content is available.
As #ekscrypto points out in their comment, you can use Background fetch to load small amounts of data when the system decides to fetch it. However, you don't have any control over when that fetching takes place. Search on "Fetching Small Amounts of Content Opportunistically" in the Xcode help system for more information.

Daily background task in iOS

I'm building an app that fetches data from a third party server and syncs some of that data to my own server. The data for all users will be aggregated on my server and the results will be displayed in the app. The whole data sync (3rd party server -> App -> My server) should be done at least once a day. The app is only for a limited group of users and will be distributed with an enterprise account.
I'd prefer it to sync the data in the background, so the results on my server are always up to date and do not depend on the single users to open the app. I figured I'd use setMinimumBackgroundFetchInterval with UIApplicationBackgroundFetchIntervalMinimum so the sync would be handled in performFetchWithCompletionHandler in my AppDelegate. Unfortunately it doesn't seem to be possible to set a fixed interval for the background fetch. So I can't control when the sync is done, since it partly depends on the way the app is used when and how often the background fetch is executed.
Is there a way to modify the background fetch so I could guarantee the daily sync?
Or is there any other way to execute a background task on a daily basis with which I could accomplish the above?
The only solution I could come up with is a usability nightmare with daily local notifications to remind the users to open up the app, so that the background fetch can "learn" when to execute. I know this sounds bad, but I do have to present a solution to our customer :/

Keeping iOS app in sync with server

We are designing a system that based on particular events on the server creates geofences for particular device. It is expected that the client (device) will be in sync with the server data, question is how?
Initial (most optimal) idea was to send a silent push to the device to notify it about new data, and trigger data pull. Knowing that this solution will work for Android OS devices, we though the problem can be solved in similar fashion on iOS. Unfortunately, my iOS dev told me that silent push are not reliable on iOS, and presented following discussion: Silent push notifications only delivered if device is charging and/or app is foreground.
Therefore, my question is how to keep the (geofence) data on the iOS devices in sync with server side?
We can pull, say every say 5 minutes, this solution is extremely inefficient, for most of the devices new geofences are changed rarely if at all, but our ‘power users’ need to have geofences updated very often.
We could push with some kind of silent push mechanism, but it has to be reliable.
Maybe some kind of persistent connection (tcp or better udp) but that seems like battery draining solution. Besides not reliable, the server would have to keep track of changing IPs which is not even possible on many cellular networks.
WebSocket. Also battery draining solution, that is not intended for background sync. Overkill for devices that really have the data updated rarely (like once a month).
Some commercial solution (PubNub or Pusher), but we would definitely prefer in house solution.
Are there any other solutions that are used in such cases? Maybe our approach with silent push is not right, but there is other build in Apple solution for such use case?
There's a fantastic service called Simperium with an iOS SDK that can help keep your info in Sync. I heard about them because I started using SimpleNote, a free note-taking tool that uses the sync service. They were acquired by Automattic, which runs Wordpress so the whole deal should be decently stable.
Hope this helps!
You can run your syncing operations in the applicationDidEnterBackground: method within AppDelegate. That's the solution I've always used as long as the syncing operation doesn't take too long.
Here you can also query your database for data changes instead of pushing a trigger to the device, which could get hairy with push notifications and aren't really their intended use. If changes in the data are found (or some boolean flag is checked) then initiate a data pull.
I'm not sure how much data you are working with but having a REST query every 5 mins is the way I'd go. Perhaps you can even switch it to a query each time you start up the app would be good enough?
We have an app where the user data needs to be sync'd with the back end server - each time we start the app it queries the backend server to see if there are any updates. We md5hash the data from the server and then we can just check our hash against the latest data - if it doesn't "match" then we pull the new data set.
In general, iOS doesn't really allow you to do multi-tasking the way you can do on android. Now, if you aren't releasing to the app store - and only using this as an in-house app you can get a little funky with things and run in a background mode.

How to poll an API safely and efficiently?

I'm developing an enterprise iOS app in Swift that needs to pull a list of items from our API and display them in a table view.
The list may change a few times a day but our system won't notify us when the data changes.
Instead, the app will need to poll regularly, say every two hours, to get the latest data and refresh the list. I have implemented the API call using NSURLSession directly.
My question is, what is a safe and efficient way to set up a polling mechanism? What if there are additional API services that must be polled, perhaps on different intervals?
Since you are developing an enterprise app and don't need app store approval you can 'misuse' one of the existing background modes, such as VoIP to periodically poll your data.
My suggestion, however, is to implement some code on another server that can poll the API and send a push notification to the devices when there is new data. This will be simpler to implement in the iOS app and more efficient in terms of battery life and data traffic. It also won't require the user to restart your app after device resets.
You can also easily use the same server to check additional data sources in the future.
An efficient polling mechanism can be implemented via NSTimer(s).
You can have multiple NSTimers fetching data from different locations and working on different dispatch queues.
Then, when you fetch new data, you can broadcast a local notification with the new objects (which is similar to Core Data model).
Your app would be able to access the retrieved data from anywhere.
If you only need to use the data in one location, you could use a delegate or a block-ish callback model.

Receive update from web server to iOS App and synchronize data

i'm writing an app that manage a sqlite database, and i have write a web server, i want the user register in my web server with username and password, i already know how make a request from ios app to server and receive the response, but i want enable also the synchronization of the sqlite database to other device, i now that with core data i can use iCloud synchronization, but for now i prefer use sqlite, and find a way to synchronize it, for example i want create this:
make a change in the sqlite in the iPhone app;
the app send this change to the server for that user;
then the server have to send this update to other device connected at that user;
and now i can't go over, how the server can send this change to the other device? the device has to be always listen to the server? or there is a way to send this update directly to some device and handle it? like an apple push notification?
EDIT: if it's possible use an apple push notification to do this, i doesn't want alert with text sound and badge the user, but send a "silent notification" it's possible?
As a high-level there are a few different ways to approach this, all of which have pros and cons. Two name two examples you can do a polling method, active push or a hybrid approach.
Polling: at some pre-determined interval the app tries to "phone home" and send the delta db changes up to the server. Here you know that your server will be expecting X number of responses in any given interval so you can appropriately gauge your load.
Active Push: The user decides when they want those changes to be transmitted to the server by hitting a "Sync" button. This allows the user to only push data back up to the server when they know there's a change but an over zealous user may make a change, upload, make a change, upload, etc instead of queueing up a bunch of changes and sending them all at once. This may create frequently unneeded server calls.
Hybrid: You setup a polling schedule within the app AND give the user the ability to Sync at-will in the event there is a critical change that needs to be made ASAP.
Regarding the listener side of the equation you face a similar challenge conceptually. If the original user makes 20 changes and presses Sync 20 times do you bombard the second user's device 20 times as well or do you queue those changes up and send them down every 5 minutes (as an example)? Unless you have both devices paired to each other or are connected to the same network AND visible to each other via your app you're going to need to leverage that back-end server. Push notifications can be very useful in this manner but there is extra development and setup overhead to take into account to properly implement them.
To boil this all down I would recommend laying out what YOU want your syncing model to look like before you start marching down a path.

Resources