CloudKit: Incoming CKNotification's pushed repeatedly - ios

I have my CloudKit setup working pretty well using a private DB with a custom zone. Whenever I fetch I send the latest token I have cached previously, and I trigger a fetch every time I get a CKNotification.
However in one occasion while debugging my app I saw it getting CKNotifications repeatedly, and I could verify that indeed I'd get new tokens and I'd send the latest one on each fetch. As for the data changes themselves, it was always the same record. This particular record needed to be discarded on the receiving device, and so it was, but I don't see that as an issue, I'm saving the change token every time and I acknowledge the notification to be processed with .newData. I'd expect that change to never be notified again!
I tried to recreate the scenario with another record that also needs to be discarded but so far everything seems to work as expected. My concern is that any of my users will ever get to that repeating notifications scenario I once saw going on.
Any ideas of what may have caused it?

Related

CloudKit: Using notifications to keep changes in sync across multiple devices

I am writing an app and using CloudKit. The app stores its data in the public database. I’ve created a local cache so that my app can function even if the network isn’t available. I’m using CKSubscriptions and the resulting push notifications to keep changes from the cloud in sync. All of this is working well.
Now, if a user has multiple devices and is running my app on all those devices, then I can no longer mark notifications as “read” (using CKMarkNotificationsReadOperation) since I won’t know when all the devices have processed them. This is particularly true if one of the devices is offline when a change happens. If I do mark them as read, then when the other devices check for new notifications (using CKFetchNotificationChangesOperation) they will not see them and their local cache will be out of date.
My current solution is to just leave all notifications in an “unread” state and rely on the CKServerChangeToken in CKFetchNotificationChangesOperation so that each device only grabs the notifications that have occurred since that device last checked. This works well.
But, it seems to me that since I’m not marking any notifications as “read” they will simply continue to pile up on the server. Maybe this isn’t a big deal, but they will take up space and I have no good way to get rid of them. Over time, this seems as if it could be a problem.
Has anyone used subscriptions/notifications in a similar way and come up with a different approach? Also, any feedback on my approach would be welcomed.
The server will delete the old notifications, regardless of the read status.

Healthkit HKObserverQuery Updates with ONLY HKDeletedObject

I have HealthKit background delivery working with a HKObserverQuery and HKAnchoredObjectQuery set up in my AppDelegate as advised in the documentation. While I get callbacks for new data points quickly, I have noticed in my testing that if I make a modification to the Healthkit data that is JUST a deletion (no new HKSample points added), I do not get a callback until the next new point is added. At that point, I will get a callback for the new data point, plus the previous deletes. But I can never get a callback that contains just deletes.
The thing that has me worried is that Apple says that these HKDeletedObjects disappear and won't show up in any queries after some undetermined period of time.
https://developer.apple.com/library/prerelease/ios/documentation/HealthKit/Reference/HKDeletedObject_ClassReference/index.html
So if my app is synchronizing data from HealthKit using this method, what happens in the case where the user deletes some data and then, for a long period of time, doesn't add any new points or launch my app to the foreground? I think that I would just miss the delete entirely in that case.
TLDR: Does the callback for an HKAnchoredObjectQuery ONLY get called in the case where there is at least one new HKSample (even if there are deletes available)? If so, how are we supposed to handle long periods of inactivity after a delete?
To the first part of your question: As I read the documentation of HKStore.enableBackgroundDeliveryForType()... "HealthKit wakes your app whenever new samples of the specified type are saved to the store" - only new samples will trigger the query and this is consistent with my experience.
To the second part, setting HKAnchoredObjectQuery.updateHandler, is causing the anchored query to trigger upon deletes and adds. In my experience though, it is not consistent (see my related question).

NSSystemClockDidChangeNotification acts weird when app wakes up

In my app I'm registering a NSSystemClockDidChangeNotification notification in AppDelegate method application:application didFinishLaunchingWithOptions:options.
Posted whenever the system clock is changed. This can be initiated by
a call to settimeofday() or the user changing values in the Date and
Time Preference panel. The notification object is null. This
notification does not contain a userInfo dictionary.
Month ago it was working fine, but these days every time I suspend my app, lock my iPhone and leave it 2 minutes to pass, when opening the app, the selector method is called, which is weird to me. I didn't change the system or time, I just let the device idle.
Can anyone help me understand this? I just want to execute some code when the user manually change the system time, just in that case (tried with UIApplicationSignificantTimeChangeNotification but that doesn't help).
Like that: Getting iOS system uptime, that doesn't pause when asleep
But remember, this solution will fail sometimes because of out-of-sync when system tries to update time from NTP server when the Internet connection is not reachable.
This answer is a bit late but this is what the apple support team replied when I ask a similar question:
Part of the question I asked:
Could it be possible for the OS posted [this notification] if the
time/timezone has not changed in the device?
The answer I got from them:
Absolutely [1]. It's common for a notification like this to be posted
redundantly. In some cases it's triggered by a state change you can't
see. For example — and I haven't tested this theory, so it's just an
example of how this sort of thing can come about — this notification
might be posted if the system's giant list of time zone info has
changed. So, the time zone state has changed, but it's not something
that affects your app.
But in other cases, a notification might be truly redundant (-: iOS
is a complex system and in some cases this complex machinery generates
redundant notifications, and there's no need to filter them out
because…
Your app should respond to such notifications be refetching the info
it cares about and updating its state based on that. If this update
is expensive, keep your own copy of the previous state, compare the
current system state to that, and only do the update if the stuff you
care about has actually changed.

Manage iPhone app both offline and online

I am stuck to a point, I am managing my app offline also.. first time i get all data (images) from a webservices and store its path into sqlite, now I take an int value 0 or 1 and store its state into NSUserDefaults now I am facing problem in updating those images, like if images are changed how should I notify into my app, I searched it on Google and only solution is to send push notification to app when record is updated. What if user do not allow push notification?
Is there any other solution to manage app offline and update only when record is changed from online database?
You can sync your Data with server Periodically , like call a webservice which check if images have been changed then fetch the new images and if images are not changed then continue with old data.You can add a Boolean Value on server end which can tell you if data on server is updated or not or you can check this with Time stamp like when data is updated last time then compare your local time with Server time at which data has been updated . Good Luck !!
There are ways to handle such kind of situation:
Use push notifications which is the best solution for such situation.
Query the server periodically by giving the ability to the user to set the time interval from app settings.
Query the server whenever the app came from background to foreground.
An idea is to use BackgroundFetch to update the app content while it is not running. I am using similar fetch for one of my apps where I update the content before the user opens the app. I am fetching a small list of items that is indicating which one is up to date and which is not. Then, at runtime I present an option to the user to manually update these items, but of course you can also download all that while in backgroundfetch. My app is without network reach most of the time, and backgroundFetch will update the items list first thing when there is some internet connection.
There are two important methods here that you need to register, setMinimumBackgroundFetchInterval: and application:performFetchWithCompletionHandler: . You can read more about them in Apples guides for background modes.
You can also check out this good tutorial about this fetching capability: http://www.appcoda.com/ios7-background-fetch-programming/
There is way which has being most popular as most of peoples are preferring
At server side build mechanism, which can send lists of images updated after particular date/time.
To keep track of last sync date/time at locally.
Pinged on server with last date/time in case of first time pass any past date and check for update, if there is then download updated images, Otherwise.
Now you have to decide this process when would be query to server
1) At every first time application will be load. (At didFinishLaunchingWithOptions).
2) Query the server periodically by giving the ability to the user to set the time interval from app settings or else where would be preferable.
3) Query the server whenever the app came from background to foreground.

Update ios app every time more data is available on server

I have an app that needs to update every time a java web application creates more data. Simple enough, right?
But I found out that my app can`t run in background to ask for more data periodically, and I think I need to use the push notification system. That seems to be overly complicated for a really small thing.
And then, reading about it, I found out that the push notification can never arrive! For example, if the app is offline when the push notification is sent but is online a few moments later.
So, in that case, how can I update the data? I only bring data from the server when the user logs in. I didn't want to do that every time the application became active...
I guess there is a simple solution but this is my first app, any help would be appreciated.
You see why you should read your question before posting it?
And then, reading about it, I found out that the push notification can
never arrive! For example, if the app is offline.
So, in that case, how can I update the data?
Guess what, if you are offline, there is not much you can do... Moving on to serious things:
iOS7 allows you to do periodic background fetchs (check the Multitasking Enhancements). Have this tutorial.

Resources