Best way to notify iOS app on server database updates - ios

I am quite new into programming and I cant find efficient solution for my problem. Could someone point me in the right direction please?
I have an app which is heavily relying on server data. Data on server is unique for each user and may change every minute as well as only every few hours. Currently I am updating local data when app becomes active but I also need a way of notifying app to trigger updates when app stays in active state and data has changed on server. I thought about few solutions:
1) NSTimer set to one minute and triggering url request to check if there is new data on server. Server after comparing lastModified value would return new data if available.
I don't really like that solution as I don't want to overload my server with number of requests, especially that data in the database may change only every few hours or even longer.
2) APNS - sending notifications from server every time data will change and than update local data with server database when notification received.
It seems like a good solution but only if it would be possible to restrict remote notifications to be received when app is in active state. As far I know it is not possible and as I mentioned before data may change even every minute so I don't want to spam users with number of notifications when app is not running.
3) TCP Sockets using NSStream/CFStream?
This is something I never did before, so I am not even sure if I am going in the right direction researching about this one.

This is a hard topic in general, but more technologies are coming out to help with it. Couple thoughts on each of your solutions:
The NSTimer solution is effectively polling, which is the worst option I feel. You'd be hitting your server pretty hard for each user.
This would be a better solution. APNS now supports silent notifications, so you can send push notifications to a user without worrying about notifying them. You can send a silent notification by including the content-available key in the payload and not including the alert key. More info here: http://hayageek.com/ios-silent-push-notifications/. It is rate limited, though. You may go minutes to hours without getting a delivery, so if that's important you'd be best to go to option 3.
This is your best solution. It would require a persistent connection with your server. AFNetworking 2.0 supports this kind of connection based on Rocket. Here's Rocket's documentation: http://rocket.github.io. Take a look at server-sent events.
Hope that helps!

Related

APNS quiet hours

I'm trying to decide which way to implement a "quiet hours" feature in my app to allow users to specify times in which push notifications should be silent. I see two options:
1) Server-side. Their settings are sent to the server which sends notifications with different properties (or perhaps not at all) during quiet hours.
2) Client-side. The app receives all notifications via silent push, the app then processes each notification and only notifies the user as appropriate.
I see problems / limitations with each method.
For #1, the implementation becomes more complex (especially if I want to add additional notification filters based on alert type, etc), and the issue of which timezone the client is in would be very hard to resolve (especially as the client moves from one timezone to another). I certainly don't want to be tracking their position and updating their current timezone on the server.
For #2 I have read a number of comments in various places that the silent push that goes only to the app is not as reliable as normal push notifications that directly notify the user and are not processed through the app. I would prefer to implement quiet hours in this way, but I am very concerned about a reduction in the reliability of the notifications coming through. I have also read that the app will NOT be started in the background if the user has force-quit it. Is that still the case?
I have two questions. First, how have others handled this concept of quiet hours? Second, is the silent push as unreliable as I have heard in the real-world, or has this gotten better (or worse) with the latest versions of iOS? I know there are factors, such as how much power the app consumes while processing these notifications. On average my app would only receive a few silent notifications a day, and processing would be very fast.
Not sure this is really an answer, but too much for a comment!
Is your app likely to be used in different time zones?
Or are your users all based in one country?
This could mean handling client side is going to be a lot simpler.
Also remember that there is no guaranteed delivery time of a push, its normally pretty instant, but not always, so although you might of sent it with 5 minutes to spare before a quiet hour, it might arrive after the quiet hour has actually started.

Auto Refresh JSON

So my app extracts JSON from a server that i don't control, and parses that JSON to populate a UITableView.
I want to update my UITableView to reflect the latest information available on the server in real time. So Whenever something changes on the server my UITableView also gets updated.
Now one solution that comes to mind is to Continuously send GET Requests lets say after one minute, parse the JSON and reload data on the table.
However there must be some other solution for this problem. I have tried searching but thus far no success.
Now i understand this questions is somewhat subjective by stackoverflow's standards but really i need help regarding this matter and i haven't got the slightest clue on where to start. So any help would be greatly appreciated.
Repeated GETs are generally frowned upon, because it demands client and server resources when nothing is happening, which can be most of the time.
Since you don't control the server, I'd recommend building a server that you do control that can perform the polling, and then send the push upon detecting a change. This has a couple advantages over polling from the client: It scales better since only one source of polling will exist in the world, and it conserves client energy as well as the pure push approach does.
Apple provides a push system (APNS) wherein your server sends a message to your iOS device (via Apple). The device will launch your app in the background and invoke:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo;
on your app delegate.
As the above answer states, its better to use APNS.
if however, you truly do not control the server, then as you describe theres nothing you can do except poll. Since you're writing for iOS, you're well advised to consider a few things:
Wifi constraints: Are you fetching a tiny payload such that it doesn't matter whether you are on wifi? otherwise you ought to configure reachability to not be a drag on the users cellular service.
Backgrounding Sessions & background Execution: Consider using an NSBackgroundUrlSession to request this data. Backgrounding sessions are a bit more efficient to the OS in that they allow the OS to perform the request opportunistically. Consider The Background Execution entitlement if You need to customize the NSURLSessionTasks for the background session.
Scalability: can your backend handle continuous requests from your volume of users?
better solutions might utilize APNS, or Socket / WebSockets / Socket.io / firebase / etc.
Normal Silent Notification is best solution for this
When you adding any new item on server that time you can send push notification (Silent push notification) to devices to notify status that you added something on server side.
When device receives such push notifications then you have to call API and reload your table view. So you don't have to reload tableview every 10 sec.
It "will not show notification alert in notification bar, but it will only notify your app that there is some new data available, when you want to push new content.
Displayed in Notification center : No
Awake app to perform background task : Yes
just add below paylod from server side in push notification
{
"content-available" : 1
}
{
"content-available" : 1
}

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 do bring my App "up to date" - background fetch?

I am looking for a good way how to make my app "upToDate". These are my requirements:
I have an RESTful Webservice, with tasks for different users. Every user has an iOS App, which should get automatically updated when the Server/Service assigned a task to that User.
So first ill created a manuall "Sync" Button, which checks for new Tasks. Fetches the data with Alamofire, and updated the UI.
But, my goal is automatically sync if there are new tasks.
So, ill guess there are 2 different ways to solve that:
1. Make a Background Fetch (with a NStimer?) every xx Minutes and check if there are new tasks.
After checking that tutorial here:
http://www.raywenderlich.com/92428/background-modes-ios-swift-tutorial i am not sure if a background fetch is a good way to solve that. In that case the App uses an scheduler, to check once for new updates, and not every xx minutes.
So in my case i would create an NStimer in the AppDelegate (maybe in applicationDidEnterBackground) and check every xx minutes for new data (but when there are 3 days not any new task, that would be unnecessary battery consumption, or?)
2. Using Push Notifications.
My other idea is to use Push Notifications, so when there is a new task, ill send a Push Notification an manually start the sync. In my opinion that would use less battery, because he will only start the sync when there is a new task available.
Generaly Questions about using Background Services
So ok, if the user finished the task, some data should be automatically uploaded to the server. Normally not a problem, with the manual sync ill check if there is something to upload. But, what if, when there is no internet connection (ill check if before uploading) - and the user do not press on "manual sync".
So i would prefer to check in my "Background Service" if ill got an Internet connection, and if yes - start uploading some data.
Ill know this is not a specific question, but ill think there are lots of users who have the same requirements and it would be great if someone can help me out whats the best way to solve that in the best and practical way.
Thanks in advance!
Background updates sound wonderful until you realise that Apple throttles them heavily: you can ask to be updated as frequently as possible, but iOS decides what that value actually means based on how often users open your app and when they do so. Apple considers background updates the kind of thing that should happen just before a user opens your app so the latest content is right there, rather than something that runs proactively in the background.
Your push notification solution is a better one, particularly if you use CloudKit to subscribe to record change events using CKSubscription and CKNotificationInfo. If you do this you'll automatically get push messages in your app, so you can get what you want with very little work. You can read my tutorial for more information on subscribing to CloudKit to get push messages.

iOS - Push notifications and background threading

I have a service that allows user to enter the type of events they like, and whenever a new event that fits those criteria is available in my database, I want them to get a notification.
I have been looking around at the best way to handle it and I have found two possible solutions, but I'm not very clear with which one I should use and how.
First, a solution that looked great was the didReceiveRemoteNotification method and the usage of remote silent notifications to tell the app that new content was available. But my questions remains: how can I send this remote notification to the user if I don't know which criteria he has. I mean, how can I send this notification using PHP? I'm a bit lost here.
So I found another possible solution that does look a lot like a hack (iPhone - Backgrounding to poll for events), to be able to make your app execute a method every XX minutes while it is in background. This would be way more battery consuming and I'm not even sure it would be accepted by Apple, but at least it is clear as to how it works: the app downloads data from a link with the parameters that fit the special criteria, and if there is new data, it sends a notification.
How could I combine both these methods?
EDIT
I think the main issue on my side is that I don't understand how I could check a certain PHP file whenever new data is added into mysql and make sure that it fits the criteria of the user and then send the notification. That is the part that I don't understand in the backend PHP usage.
Your flow should be like this -
Mobile -> BackendServer(PHP) -> APNS server -> Notifications->Back on device.
User will submit her/his criteria to server then server will process on that and send request to APNS server.
The APNS server will send remote notification on her/his device based on criteria requested.

Resources